【问题标题】:Why does this Java code not write to file?为什么此 Java 代码不写入文件?
【发布时间】:2020-09-19 16:22:27
【问题描述】:

Java 中有很多输入/输出类。 这真是一团糟。你不知道该使用哪个。 操作系统提供哪些功能?会有一个 我猜是读取文件的一个字节或文件的多个字节。

例如,如果我使用它。

String path = "C:\\Users\\myName\\test.txt";
FileOutputStream fos = new FileOutputStream(path);
fos.write(333);

如果我用文本编辑器打开它,它会显示字母 "G" 。这个我已经不明白了。

而且这段代码没有写任何东西,文件奇怪地是空的。

String path = "C:\\Users\\myName\\test.txt";
FileOutputStream fos = new FileOutputStream(path);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(fos));
out.write("something");

所有这些 I/O 类都让我感到困惑。缓冲是什么意思。它一次读取 1000 个字节。所以 我猜有直接读取1000字节文件的操作功能。

【问题讨论】:

  • 在流上调用flush。 fos.flush()
  • 关闭fosout
  • 这能回答你的问题吗? How do I create a file and write to it in Java?
  • 至于“G”,您写了一个数字并尝试将其读取为 ASCII 字段。
  • @soni Kumari 你必须冲出去。如果您冲洗 fos,它将无法正常工作。 @cliff2310 不,我写的是字节,不是数字

标签: java java-io


【解决方案1】:

您需要在调用out.write("something")后关闭BufferedWriterout和FileOutputStreamfos的实例,然后才能成功创建包含您尝试写入的内容的文件。

     public static void main(String[] args) throws IOException {
         String path = "C:\\Users\\myName\\test.txt";
         FileOutputStream fos = new FileOutputStream(path);
         BufferedWriter out = new BufferedWriter(new OutputStreamWriter(fos));
         out.write("something");
         out.close(); // Closes the stream, flushing it first. 
         fos.close(); // Closes this file output stream and releases any system resources associated with this stream.
        }

【讨论】:

  • 好的,谢谢。关闭两者就足够了。不需要冲洗。但这很奇怪。为什么我必须先关闭,然后才能将文本写入 file 。是不是因为缓冲区未满,然后只有在缓冲区已满时才会自动写入。
  • 您没有刷新流,只有在刷新后文本才写入文件中。 close() 基本上会刷新和关闭流。您可以使用out.flush() 将内容放入文件中。
【解决方案2】:

关闭 BufferedWriter 和 FileOutputStream 的实例将解决问题。 fos.write(333) => 数字已写入文件,当您打开文件时,它会以 ASCII 格式打开。您可以使用以下代码。

    public static void main(String[] args) throws IOException {

        FileWriter fw=new FileWriter("D:\\test.txt");
        fw.write("Hello! This is a sample text");
        System.out.println("Writing successful");
        fw.close();

        /* your code
        String path = "D:\\test1.txt";
        FileOutputStream fos = new FileOutputStream(path);
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(fos));
        out.write("Hello! This is a sample text");
        out.close(); 
        fos.close();
        */
    }

【讨论】:

  • 嗯,好的。谢谢。当我写 65 时,它现在在文件中显示“A”。说得通。但这是一个非常奇怪的结构。 BufferdWriter 需要一个需要 FileOutputStream 的 OutputStreamWriter。好复杂。
  • 是的,我同意,这是一个有点复杂和奇怪的实现。但是当你在java中对文件操作进行更多编程时,你会习惯它。
  • @Alicia22 BufferedWriter 可以写入任何地方,而不仅仅是文件:网络或其他写入器。这就是这些作家背后的想法:你把他们锁起来。您的代码只是写入通用流,并不关心最终是 zip 文件、加密文件、纯文本文件还是加密的压缩网络连接。这称为多态性。
  • 如果抛出异常,您还应该关闭Writer。使用 try-with-resources 语句最容易做到这一点。另外,请注意FileWriter 如果未指定编码,则使用平台默认编码,而不是 UTF-8,这可能会引起可移植性问题。
  • new BufferedWriter(new OutputStreamWriter(fos));在这种情况下使用 BufferedWriter 实际上是没有必要的。只需 OutputStreamWriter 就足够了。
【解决方案3】:

Java 中有很多输入/输出类。这真是一团糟。您不知道该使用哪个。

Files 类是迄今为止最容易使用的。例如,

Files.writeString(Paths.get("test.txt"), "hello world!");

创建一个名为“test.txt”的文本文件,其中包含文本“hello world!”。

仅当您想做一些花哨的事情时才需要其他类(例如,处理太大而无法放入主内存的文件)。例如,假设您想要读取一个巨大的日志文件(数百 GB 长)并且想要将包含特定单词的每一行写入另一个文件。如果你用

打开文件
Files.readAllLines(Paths.get("huge.log"));

您会收到OutOfMemoryError,因为该文件不适合主内存。为了解决这个问题,我们必须逐段读取文件,这就是所有 ReaderWriter 类(或 InputStreamOutputStream,如果您正在处理二进制文件)的好处:

    try (
        var reader = Files.newBufferedReader(Paths.get("huge.log"));
        var writer = Files.newBufferedWriter(Paths.get("interesting.log"));
    ) {
        String line;
        while ((line = reader.readLine()) != null) {
            if (line.contains(searchWord)) {
                writer.write(line);
                writer.write('\n');
            }
        }
    }

如您所见,它们的使用要复杂得多。一方面,我们必须在处理完 ReaderWriter 后关闭它们,这最容易通过上面显示的 try with resources 语句完成。

关闭是必要的,因为大多数操作系统都会限制一次可以打开的文件数量。关闭还使任何Buffered* 类有机会清空其缓冲区,确保将仍在缓冲区中的任何数据传递到文件系统。

如果我们未能关闭,就像您在示例代码中所做的那样,该文件将保持打开状态,直到我们的程序退出,此时缓冲区中的所有数据都将丢失,从而导致您找到的文件不完整。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-12
    • 1970-01-01
    • 1970-01-01
    • 2018-02-26
    • 1970-01-01
    • 2020-10-07
    • 1970-01-01
    • 2022-08-15
    相关资源
    最近更新 更多