【问题标题】:Redirecting FileOutputStream to console - Java将 FileOutputStream 重定向到控制台 - Java
【发布时间】:2013-05-18 08:12:30
【问题描述】:

我想重写并简化我的代码,以减少类中执行完全相同但写入文件或控制台的方法的数量,以便我可以执行以下操作:

PrintFlightSchedule(String aFileName); // prints to a file
PrintFlightSchedule(); // writes to console.

我尝试创建以下测试方法,只是为了演示我想要实现的目标,方法是定义一个抽象的 OutputStream,然后将其实例化为 PrintStream 或控制台(通过 System.out):

public static void testOutputStream(String fileNm, String msg) {
    OutputStream os;
    if (fileNm.equals("") ) { // No file name provided, write to console
        os = System.out;
    }
    // File name provided, write to this file name
    else {
        try {
            os = new FileOutputStream(fileNm);
        }
        catch (FileNotFoundException fe) {
            System.out.println("File not found " + fe.toString());
        }
    }
    // Use the output stream here - ideally println method?
    // os.println or write(6);
}

这无疑是半途而废,但它让您了解我想要实现的目标。

Java 中是否有一种方法可以在运行时定义输出方法(文件或控制台),所以我可以在运行时使用相同的方法来执行任何一种操作?我想一个简单的方法是将 FileOutputStream 重定向到控制台 - 这可能吗?

【问题讨论】:

  • 你不能只使用log4j 或类似的东西而不是自己写吗?
  • 为什么不写一个以 OutputStream 作为主要参数的方法。您可以保留其他两种方法,并简单地将它们通过第三种方法...

标签: java console


【解决方案1】:

基本上,您需要创建一个简单地接受OutputStream 并将所有详细信息写入其中的方法...

然后您创建一些辅助方法,只需使用适当的流调用它...

public void printFlightSchedule(OutputStream os) throws IOException {
    // Write...
}

public void printFlightSchedule(File file) throws IOException {
    FileOutputStream fis = null;
    try {
        fis = new FileOutputStream(file);
        printFlightSchedule(fis);
    } finally {
        try {

        } catch (Exception e) {
        }
    }
}

public void printFlightSchedule() throws IOException {
    printFlightSchedule(System.out);
}

您可能还想看看Code Conventions for the Java Language...它将使人们更容易阅读和理解您的代码;)

【讨论】:

  • 感谢 MadProgrammer flup 和 bowmore:我收到了消息 - 提供我想要用作从设计角度来看合乎逻辑的方法的参数的作者。正如你所看到的,我不是 Java 设计方面的专家,但有趣的是,当你用这些东西回到设计的基础时,你经常会得到答案!
  • 我喜欢你减少代码重复的想法,这是正确的工作思路。为此,从最小公分母 (OutputStream) 开始,然后从那里开始
【解决方案2】:

java.io.OutputStream 已经是“可以写入字节的东西”的抽象。如果您的类与 OutputStream 交互并且您的类的客户端可以选择 OutputStream 实际上是什么(文件、控制台、空设备,...),那么您的类将不需要关心 OutpuStream 的类型是实际需要给定的上下文。

因此,与其让你的类尝试做它需要做的事情为其客户创建 OutputStreams,不如让它专注于其真正的责任并让客户提供他们想要的 OutputStream。

所以只保留一个构造函数:

/**
 * Constructs a new instance that will print to the given OutputStream
 */
PrintFlightSchedule(OutputStream stream);

【讨论】:

  • 谢谢鲍莫尔,关键是回到你说的“专注于其真正的责任”。
  • 是的,只需遵守单一职责原则。
【解决方案3】:

不要提供文件名字符串作为参数,而是提供 Writer。 你方法的签名变成了

void PrintFlightSchedule(Writer writer);

您显示的代码将是根据运行时参数在启动时创建 Writer 的位:

public static Writer createOutputWriter(String fileNm) {
    OutputStream os;
    if (fileNm.equals("") ) { // No file name provided, write to console
        os = System.out;
    }
    // File name provided, write to this file name
    else {
        try {
            os = new FileOutputStream(fileNm);
        }
        catch (FileNotFoundException fe) {
            System.out.println("File not found " + fe.toString());
        }
    }
    return new BufferedWriter(new OutputStreamWriter(os));
}

不要忘记在输出后刷新写入器。 How to write to Standard Output using BufferedWriter

【讨论】:

  • 感谢flup - 与其他人的建议一致:将我想要的作家作为参数传递。所有的答案都很好。
【解决方案4】:

您可以使用 FileDescriptor 而不是字符串来创建 FileOutputStream。

公共 FileOutputStream(FileDescriptor fdObj)

创建一个文件输出流以写入指定的文件描述符,它表示与文件系统中实际文件的现有连接。

首先,如果有一个安全管理器,它的 checkWrite 方法会以文件描述符 fdObj 参数作为它的参数来调用。

如果 fdObj 为 null,则抛出 NullPointerException。

如果 fdObj 无效,此构造函数不会抛出异常。但是,如果在结果流上调用方法以尝试对流进行 I/O,则会引发 IOException。

默认的文件描述符是:

static FileDescriptor   err
A handle to the standard error stream.

static FileDescriptor   in
A handle to the standard input stream.

static FileDescriptor   out
A handle to the standard output stream.

所以等价的应该是:

public static void testOutputStream(String fileNm, String msg) {
    FileOutputStream os;
    if (fileNm.equals("") ) { // No file name provided, write to console
        os = new FileOutputStream(FileDescriptor.out);
    }
    // File name provided, write to this file name
    else {
        try {
            os = new FileOutputStream(fileNm);
        }
        catch (FileNotFoundException fe) {
            System.out.println("File not found " + fe.toString());
        }
    }
    // Use the output stream here - ideally println method?
    // os.println or write(6);
}

【讨论】:

    猜你喜欢
    • 2013-11-14
    • 1970-01-01
    • 2012-02-01
    • 2011-07-03
    • 2016-07-01
    • 2021-12-12
    • 2023-03-20
    相关资源
    最近更新 更多