Java 中的 PrintWriter 和 FileOutputStream

PrintWriter and FileOutputStream in Java

PrintWriter 用于将数据作为文本写入文件,而 FileOutputStream 用于以二进制形式写入。

考虑

import java.io.*;

public class Main {
    public static void main(String[] args) throws Exception {
        PrintWriter pw = new PrintWriter(new File("data"));
        for(int i=1;i<=10;++i)
            pw.print(i);
        pw.close();
    }
}

输出:

12345678910

但是,如果我使用 FileOutputStream,我会得到文本不可读的二进制数据。

import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        FileOutputStream fos = new FileOutputStream(new File("data")) ; 
        for(int i= 1; i<=10; ++i)
            fos.write(i);
        fos.close();
    }
}

给出输出:

现在,如果我将 PrintWriterFileOutputStream 一起使用,那么我仍然会得到如下所示的文本数据。为什么?它是如何变成文本的,为什么?

import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        PrintWriter pw = new PrintWriter( new FileOutputStream(new File("data")));
        for(int i=1 ;i<=10;++i)
            pw.print(i);

        pw.close();
    }
}

输出:

12345678910

****** 编辑:***

现在考虑,案例

import java.io.*;
import java.util.*;

public class Main
{

    public static void main(String[] args) throws Exception
    {
        PrintWriter pw = new PrintWriter( new DataOutputStream(new FileOutputStream(new File("data"))));
        for(int i=1 ;i<=10;++i)
            pw.print(i);

        pw.close();


    }


}

输出仍然是: 12345678910

根据 JavaDocs:

A data output stream lets an application write primitive Java data types to an output stream in a portable way. An application can then use a data input stream to read the data back in.

那么,现在如果 PrintWriter 正在向 DataOutputStream 发送字节,整个过程是如何工作的?

查看文档。

来自FileOutputStream.html#write(int)

Writes the specified byte to this file output stream.

来自PrintWriter.html#print(int)

Prints an integer. The string produced by String.valueOf(int) is translated into bytes according to the platform's default character encoding, and these bytes are written in exactly the manner of the write(int) method.

也就是说,这个方法会写出你看到的数字。 另一个写入字节。 字节值9不是数字9,而是一个不可读的字符。

文件包含字节。总是。

通过使用编码将字符转换为字节,将字符写入文件。存在许多这样的编码。例如,ASCII 允许将 128 个不同的字符转换为字节。 UTF-8 允许将任何 Unicode 字符编码为字节。例如,这两种编码将字符“1”转换为字节 49。“2”将转换为字节 50。

当使用带有文件名作为参数的 PrintWriter 时,PrintWriter 实际上会打开一个 FileOuptutStream 以将字节写入文件。当您将字符写入 PrintWriter 时,PrintWriter 使用编码将字符转换为字节,然后将这些字节写入 FileOutputStream,FileOutputStream 将字节写入文件。

因此,例如,如果您使用以下程序:

public class Main {
    public static void main(String[] args) throws Exception {
        FileOutputStream fos = new FileOutputStream(new File("data")) ; 
        for(int i = 49; i <= 58; ++i)
            fos.write(i);
        fos.close();
    }
}

然后用文本编辑器打开文件,你应该在文件中看到123456789,因为代码直接写入了这些字符的字节表示(ASCII 或UTF8)。