Java FileInputStream与FileReader

Java FileInputStream与FileReader,java,io,writer,Java,Io,Writer,当我使用FileReader和FileWriter读写mp4文件时,output.mp4文件不能很好地呈现。但是当我使用FileInputStream和FileOutputStream时,它工作得很好 因此,我可以断定FileReader和FileWriter仅用于阅读和书写文本吗?是的,您的结论是正确的Reader和Writer的子类用于阅读/书写文本内容InputStream/OutputStream用于二进制内容。如果您查看文档: Reader-用于读取字符流的抽象类 InputStrea

当我使用
FileReader
FileWriter
读写mp4文件时,
output.mp4
文件不能很好地呈现。但是当我使用
FileInputStream
FileOutputStream
时,它工作得很好


因此,我可以断定
FileReader
FileWriter
仅用于阅读和书写文本吗?

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

Reader
-用于读取字符流的抽象类

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

FileReader
(以及任何扩展阅读器)实际上都是用于文本的。从:

用于读取字符流的抽象类

(我的重点)看看API,你会发现它完全与文本有关-
char
,而不是
byte

InputStream
OutputStream
用于二进制数据,如mp4文件

就我个人而言,我会完全避免使用
FileReader
,因为它总是使用系统默认的字符编码——至少在Java11之前是这样。相反,在
文件InputStream
周围使用
InputStreamReader
。。。但只有当你想处理文本时。(或者,使用
文件.newbuffereder

另一方面,这是一种从输入复制到输出的非常低效的方法。。。使用
read
write
的重载,它们读入缓冲区或从缓冲区中写入数据-一个
byte[]
或一个
char[]
。否则,您将为文件中的每个字节/字符调用读写

您也应该关闭中的IO流。最后,块,即使在处理它们时抛出异常,它们也被关闭。

“文件写入器是用来编写字符流的。对于原始字节流,请考虑使用文件输出流。”

FileWriter和FileReader是为字符流设计的

致以最良好的祝愿


Furkan

文件输入流
用于读取原始数据字节流,如原始图像<另一方面,code>FileReaders用于读取字符流

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

因此,当您试图读取包含字符
“Č”
的文件时, 在
文件输入流中
将给出结果为
196 140
,因为
ASCII
值为
268


FileReader
中,将给出
268
的结果,这是char
Č
ASCII
FileReader
fileInputStream都可以读取文本文件,但mp3和png只能使用
fileInputStream
读取

  • fileReader
    逐字符读取

  • fileInputStream
    逐字节读取


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

    字节流

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

    字符流

        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); 
        }
    
    字符流将逐个字符读取文件。字符流是比字节流更高级的概念。字符流实际上是用逻辑包装的字节流,该逻辑允许它从特定编码输出字符。这意味着,需要为字符流指定文件的编码才能正常工作。字符流可以支持所有类型的字符集ASCII、Unicode、UTF-8、UTF-16等。所有字符流类都是读写器的后代

    如果您试图读取已写入的
    .txt
    文件 使用默认情况下在java中使用的Uni-8编码,则可以使用Reader和InputStream类读取文件 给出相同的输出。这里每个字节代表一个字符

    我创建了一些方法来帮助您理解 这两个术语之间的区别--
    FileInputStream逐字节读取
    FileReader逐字符读取
    。 请耐心一点,进一步阅读以理解这一点

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

    使用Unicode 16编码将数据写入文件的方法

    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();
    
    output.txt

    
        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");
            }
        }
    
    以下是3种读取文件的方法:首先使用默认方式的FileReader,然后使用FileInputStream,然后使用带有Unicode-16字符集(编码)的InputStreamReader。 方法中的注释是不言自明的,请阅读它们以清楚地了解其工作原理。

    文件阅读器

    Hello World
    
    输出

    
        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");
            }
        }
    
    使用默认cons(默认)输出文件读取器
    
    /*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();
            //  }
    
            }
        }