1

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

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 重定向到控制台 - 这可能吗?

4

4 回答 4

5

基本上,您需要创建一个方法,该方法只需要 aOutputStream并将所有详细信息写入它......

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

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);
}

您可能还想查看Java 语言的代码约定...它将使人们更容易阅读和理解您的代码;)

于 2013-05-18T08:25:13.127 回答
2

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

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

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

/**
 * Constructs a new instance that will print to the given OutputStream
 */
PrintFlightSchedule(OutputStream stream);
于 2013-05-18T08:25:57.120 回答
2

不要提供文件名字符串作为参数,而是提供 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));
}

不要忘记在输出后刷新写入器。 如何使用 BufferedWriter 写入标准输出

于 2013-05-18T08:16:53.200 回答
1

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

公共文件输出流(文件描述符 fdObj)

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

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

如果 fdObj 为 null,则抛出 NullPointerException。

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

默认的 FileDescriptors 是:

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);
}
于 2015-11-06T19:32:15.220 回答