【问题标题】:Writing to a file from a void method从 void 方法写入文件
【发布时间】:2016-07-16 10:41:29
【问题描述】:

我正在开发一个使用 Dijkstra 算法并将结果记录到文本文件的程序。我写入文件的代码如下所示:

try (PrintWriter pr = new PrintWriter(filename + "Out.txt")) {
                pr.println("Adjacency Matrix: " + (endTime - startTime) + " ms ");
                pr.println("Min-Heap: ");
                pr.println("Fibonnaci Heap:");
                pr.println("Dijkstra Adjacency Matrix");
                pr.println(g.printPath(END));
    }
        } catch (Exception e) {

        }

我对这段代码没有任何问题,除了 g.printPath(END) 行。我收到的错误是“此处不允许使用 void 类型”。我完全理解这意味着什么。这是因为 printPath 方法无效。它看起来像这样:

public void printPath(String end) {
    if (!graph.containsKey(end)) {
        System.err.printf("End vertex is not contained within graph \"%s\"\n", end);
        return;
    }

    graph.get(end).printPath();
    System.out.println();

}

由于我需要访问将要打印的变量,因此我尝试将其修改为具有可以写入文本文件的返回类型。我想出的是这样的:

public String printPath(String end) {
    if (!graph.containsKey(end)) {
        System.err.printf("End vertex is not contained within graph \"%s\"\n", end);
        return null;
    }

    graph.get(end).printPath();
    System.out.println();
    return graph.get(end).printPath();

}

这同样有错误,因为方法是字符串类型但 graph.get(end).printPath() 是无效的(get 方法也是无效的)。我尝试返回其他变量,例如 graph 和 graph.get(end) 但它们不返回图中的实际变量。我知道 graph.get(end).printPath() 打印出我想要的正确值。我只是在努力寻找一种方法来存储它们。有没有一种简单的方法可以将它写入我忽略的文本文件,而无需返回并编辑我的所有方法以使它们不失效?谢谢!

【问题讨论】:

  • graph.get(end) 的返回实例是什么?
  • get() 是 Map.java 中的一个方法,而 graph.get(end) 不打印任何值,我相信该方法只是从头到尾获取路径中的值节点。

标签: java return void printwriter


【解决方案1】:

有一种方法可以通过redirectSystem.out.print

public String printPath(Graph graph, String end) {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    PrintStream printStream = new PrintStream(bos);
    //set output stream to bos to capture output
    System.setOut(printStream);

    graph.get(end).printPath(); //your output
    System.out.println();

    //reset output stream to file descriptor
    System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out)));
    return bos.toString();
}
  1. System.out重定向到ByteArrayOutputStream
  2. 开始打印
  3. System.out 重置为FileDescriptor

最后,真的不建议这样做,这是肮脏的代码,重要的是它不是线程安全的,而且很混乱。有一个关于如何处理的建议:

  • 创建一个方法来格式化graph.get(end)并返回正确的String类型路径

【讨论】:

    【解决方案2】:

    根据您当前的使用情况,printPath 不应该打印任何内容:也许您甚至可以将其重命名为 getPath。你需要用正确的值构建一个字符串并返回,这样返回的值就可以传递给println

    public String printPath(String end) {
        if (!graph.containsKey(end)) {
            return "End vertex is not contained within graph \"%s\"\n", end);
        }
    
        // Also rework this to return a string instead of printlning stuff.    
        return graph.get(end).printPath();
    }
    

    或者,不要将值传递给println,直接调用g.printPath(END);

    try (PrintWriter pr = new PrintWriter(filename + "Out.txt")) {
         pr.println("Adjacency Matrix: " + (endTime - startTime) + " ms ");
         pr.println("Min-Heap: ");
         pr.println("Fibonnaci Heap:");
         pr.println("Dijkstra Adjacency Matrix");
         g.printPath(END);
    } catch (Exception e) {
    }
    

    【讨论】:

    • 也许我误解了你,但是在第一种情况下,如果方法被保留为 void,那么它会产生错误,因为第二个返回值是意外的。如果你把它变成一个类型,比如 String,它也会产生一个错误,因为 return 语句仍然是 void 类型。在另一种情况下,g.printPath(END) 不写入文件,它只是将其输出到系统。
    • 抱歉,我错过了将返回类型更改为字符串,现在已修复。正如我的 sn-p 中的评论所说,您还需要更改 printPath 以返回一个字符串,而不是直接输出到 PrintStream (System.out)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-08
    • 2013-01-02
    • 1970-01-01
    • 1970-01-01
    • 2023-02-10
    相关资源
    最近更新 更多