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[]
。否则,您将为文件中的每个字节/字符调用读写
您也应该关闭“文件写入器是用来编写字符流的。对于原始字节流,请考虑使用文件输出流。”
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();
// }
}
}