49
FileReader rd=new FileReader("new.mp4");
FileWriter wr=new FileWriter("output.mp4");
int ch;
while((ch=rd.read())!=-1)
  wr.write(ch);

wr.flush();
wr.close();

当我使用FileReaderandFileWriter读写一个 mp4 文件时,output.mp4无法很好地渲染该文件。但是当我使用FileInputStreamand时,FileOutputStream它运行良好。

那么我可以得出结论FileReader并且FileWriter仅用于阅读和编写文本吗?

4

6 回答 6

58

是的,您的结论是正确的子类,Reader并且Writer用于阅读/编写文本内容。InputStream/OutputStream用于二进制内容。如果您查看文档:

Reader- 读取字符流的抽象类

InputStream- 抽象类是表示字节输入流的所有类的超类。

于 2011-03-01T13:40:17.570 回答
39

FileReader(实际上任何扩展 Reader 的东西)确实适用于text。从以下文档Reader

用于读取字符流的抽象类。

(强调我的。)查看 API,您会发现它与文本有关 -char而不是byte到处都是。

InputStream并且OutputStream用于二进制数据,例如 mp4 文件。

不过,我个人会完全避免FileReader,因为它始终使用系统默认字符编码——至少在 Java 11 之前。相反,使用InputStreamReader...FileInputStream但仅在您想要处理文本时使用。(或者,使用Files.newBufferedReader。)

顺便说一句,这是从输入复制到输出的一种非常低效的方法......使用readwrite从缓冲区读取或写入的重载 - abyte[]或 a char[]。否则,您将为文件中的每个字节/字符调用 read 和 write。

应该在块中关闭 IO 流,finally以便即使在处理它们时抛出异常,它们也会关闭。

于 2011-03-01T13:40:56.413 回答
6

FileInputStream用于读取原始字节数据流,例如原始图像。FileReaders,另一方面,用于读取字符流

FileInputStream和之间的区别FileReader是, FileInputStream逐字节FileReader读取文件和逐字符读取文件。

因此,当您尝试读取包含该字符的文件时"Č", inFileInputStream将给出结果为196 140,因为的ASCII值为.Č268

InFileReader将给出结果,268这是ASCIIchar 的值Č

于 2014-04-29T06:24:13.060 回答
3

要彻底理解这一点,您需要了解什么是字符流和字节流,所以让我们快速看一下——

字节流

字节流逐字节访问文件。Java 程序使用字节流来执行 8 位字节的输入和输出。它适用于任何类型的文件,但不太适合文本文件。例如,如果文件使用 unicode 编码并且一个字符用两个字节表示,则字节流将分别处理这些,您需要自己进行转换。面向字节的流不使用任何编码方案,而面向字符的流使用字符编码方案(UNICODE)。所有字节流类都来自 InputStream 和 OutputStream 。

字符流

字符流将逐个字符地读取文件。Character Stream 是比 Byte Stream 更高层次的概念。字符流实际上是一个字节流,它已被逻辑包装,允许它从特定编码输出字符。这意味着,需要为字符流提供文件的编码才能正常工作。字符流可以支持所有类型的字符集 ASCII、Unicode、UTF-8、UTF-16 等。所有字符流类都是从 Reader 和 Writer 继承而来的。

如果您尝试从.txt使用 Java 默认使用的 Uni-8 编码编写的文件中读取,则使用 Reader 和 InputStream 类读取文件将给出相同的输出。因为这里每个字节代表一个字符。

我创建了一些方法来帮助您理解这两个术语之间的区别 -FileInputStream reads byte by byteFileReader reads char by char. 请耐心等待并进一步阅读以了解这一点。

现在您已经对这两个流有所了解,让我们看一下示例以了解它在内部是如何工作的——

使用 Unicode 16 编码在文件中写入一些数据的方法


    public void unicode16Writer() throws Exception {
        try (OutputStream outputStream = new FileOutputStream("output.txt")) {
            Writer writer = new OutputStreamWriter(outputStream, Charset.forName("UTF-16"));
            writer.write("Hello World");
        }
    }

输出.txt

Hello World

这是从文件中读取的 3 种方式,首先使用 FileReader 默认方式,然后使用 FileInputStream,然后使用带有 Unicode-16 字符集(编码)的 InputStreamReader。 方法中的注释是不言自明的,请阅读它们以清楚地了解它是如何工作的。

文件阅读器

    public void fileReaderUnicode8() throws IOException {
        FileReader fr = new FileReader("output.txt");
        int i;
        int j = fr.read();
        /*
         * here it is not able to convert the 
         * int(a byte/8 bits read from the file) to a
         * char as we had used UTF-16 to encode the file so 16 bits 
         * represented one character, but we can use its super class 
         * InputStreamReader to provide the charset(what we used for encoding)
         * which for our case is UTF-16 , then we can
         * easily convert that into char.
         */
        System.out.println("Output of FileReader using default cons(default charset) : " + (char) j);
//              while ((i=fr.read()) != -1) 
//                System.out.print((char) i); 
    }

输出

Output of FileReader using default cons(default charset) : þ

文件输入流

public void readBytebyByte() throws IOException {
        try (FileInputStream fis = new FileInputStream("output.txt")) {

            int i;
            int j = fis.read();
            /*
             * here it is not able to convert the 
             * int(a byte/8 bits read from the file) to a
             * char as we had used UTF-16 to encode the
             * file so 16 bits represented one
             * character.
             */

            System.out.println("Output of FileInputStream reading byte by byte : " + (char) j);
//              while ((i=fis.read()) != -1) 
//                System.out.print((char) i); 
        }
    }

输出

Output of FileInputStream reading byte by byte : þ

输入流读取器

/*Here we are using the parent class of FileReader so that 
     *we can set the charset(type of encoding)
     *in its constructor.
     */
    public void unicode16Reader() throws IOException {
        try (InputStream inputStream = new FileInputStream("output.txt")) {
            Reader reader = new InputStreamReader(inputStream, Charset.forName("UTF-16"));
            int data = reader.read();
            System.out.println("uni-16 ISR: " + (char) data);
        //  while(data != -1){
        //      char theChar = (char) data;
        //      data = reader.read();
        //  }

        }
    }

输出

uni-16 ISR: H

于 2020-04-19T16:32:11.747 回答
1

“FileWriter 用于写入字符流。对于写入原始字节流,请考虑使用 FileOutputStream。”

http://download.oracle.com/javase/1.4.2/docs/api/java/io/FileWriter.html

FileWriter 和 FileReader 用于字符流...

最好的祝福。

富尔坎

于 2011-03-01T13:43:32.220 回答
0

文本文件可以同时使用fileReaderfileInputStream但 mp3 和 png 只能使用fileInputStream

  1. fileReader逐字符读取

  2. fileInputStream逐字节读取

于 2016-07-10T18:43:56.267 回答