为什么这段Java代码没有写入文件?

huangapple go评论79阅读模式
英文:

Why does this Java code not write to file?

问题

在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");

所有这些输入/输出类都让我感到困惑。缓冲是什么意思?它一次性读取 1000 个字节。所以应该有一个操作函数可以直接读取文件的 1000 个字节,我猜的。

英文:

There are so many Input/Output Classes in Java.
It is really a mess. You do not know which to use.
Which functions does operating system offer ? There will be one
to read one byte of a file or many bytes of a file I guess.

So for example if I use this.

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

If I open it with a text editor it shows me letter "G" . Already I do not understand this.

And this code does not write anything, the file is empty weirdly.

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

All these I/O classes just confuse me. What does buffered mean. It reads 1000 Bytes at once. So
there is operating function to straight away read 1000 Bytes of a file I guess.

答案1

得分: 1

> 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语句。

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

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

英文:

> There are so many Input/Output Classes in Java. It is really a mess. You do not know which to use.

The Files class is by far the easiest to use. For instance,

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

creates a text file named "test.txt" containing the text "hello world!".

The other classes are only needed if you want to do something fancy (for instance, deal with files too big to fit in main memory). For instance, suppose you wanted to read a huge log file (hundreds of gigabytes long) and wanted to write each line containing a particular word to another file. If you were to open the file with

Files.readAllLines(Paths.get("huge.log"));

you'd receive an OutOfMemoryError because the file doesn't fit in main memory. To work around that, we must read the file piece-wise, and that is what all those Reader and Writer classes (or InputStream and OutputStream, if you're dealing with binary files) are good for:

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

As you can see, their use is quite a bit more complicated. For one, we must close the Reader and Writer once we are done with them, which is easiest accomplished with the try with resources statement shown above.

Closing is necessary because most operating systems limit the number of files that can be open at once. Closing also gives any Buffered* classes the opportunity to empty their buffers, ensuring that any data still in buffers is passed on to the file system.

If we fail to close, as you did in your example code, the file remains open until our program exits, upon which time any data in the buffers is lost, resulting in the incomplete file you found.

答案2

得分: 0

你需要在调用 out.write("something") 后,关闭 BufferedWriter 的实例 out 和 FileOutputStream 的实例 fos,这样才能成功创建文件,并成功写入你尝试写入的内容。

	 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(); // 关闭流,首先执行刷新操作。
		 fos.close(); // 关闭此文件输出流并释放与该流相关联的任何系统资源。
	    }
英文:

You need to close the instances of BufferedWriter out and FileOutputStream fos, after invoking the out.write("something"), then only the file gets created successfully with the contents you are trying to write.

	 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.
	    }

答案3

得分: 0

Closing the instances of BufferedWriter and FileOutputStream will solve the issue.
fos.write(333) => 该数字已被写入文件,当您打开文件时,它会以ASCII格式打开。您可以使用以下代码。

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

        FileWriter fw = new FileWriter("D:\\test.txt");
        fw.write("Hello!这是示例文本");
        System.out.println("写入成功");
        fw.close();

        /* 您的代码
        String path = "D:\\test1.txt";
        FileOutputStream fos = new FileOutputStream(path);
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(fos));
        out.write("Hello!这是示例文本");
        out.close();
        fos.close();
        */
    }
英文:

Closing the instances of BufferedWriter and FileOutputStream will solve the issue.
fos.write(333) => The number has been written to the file and when you open the file it opens in ASCII format. You can use below code.

    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();
        */
    }

huangapple
  • 本文由 发表于 2020年9月20日 00:22:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/63970941.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定