在 FileReader 和 InputStreamReader 之间进行选择

Posted

技术标签:

【中文标题】在 FileReader 和 InputStreamReader 之间进行选择【英文标题】:Choosing between FileReader and InputStreamReader 【发布时间】:2012-04-13 21:01:00 【问题描述】:

我有两种方法在 java 中读取文本文件,一种使用 FileReader 和其他文件 InputStream

FileReader fr=new FileReader("C:\\testq\\test.txt");
BufferedReader br=new BufferedReader(fr);
String s;
while((s=br.readLine())!=null)
    System.out.println("value are "+s);

其他是

FileInputStream fstream = new FileInputStream("C:\\testnew\\out.text");
DataInputStream in = new DataInputStream(fstream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
while ((strLine = br.readLine()) != null)
   System.out.println (strLine);

虽然两者都给了我输出...我只是想知道哪种方法最好。

【问题讨论】:

第二个示例中的 DataInputStream 没有任何贡献:没有它,代码也可以正常工作。 【参考方案1】:

我会强烈建议使用InputStreamReader 而不是FileReader,但要明确指定字符编码。这确实是使用InputStreamReader 的最大好处(并且无法为FileReader 指定编码是API 中的一个主要漏洞,IMO)。

我还会使用 DataInputStream 删除“层” - 只需将 FileInputStream 传递给 InputStreamReader 构造函数即可。

Java 8 之前

或者,考虑使用Guava 中的一些方便方法,这可以使这类事情更加简单。例如:

File file = new File("C:\\testnew\\out.text");
List<String> lines = Files.readLines(file, Charsets.UTF_8));

来自 Java 8

Java 8 在 java.nio.files 中引入了一堆新的类和方法,其中许多默认(明智地)使用 UTF-8:

Path path = Paths.get("C:\\testnew\\out.text");
List<String> lines = Files.readAllLines(path);

【讨论】:

谢谢 .. 它有效,但你所说的“明确指定字符编码”到底是什么意思。.. 请详细解释一下 @Sebs_Jedi:你不明白哪一点?目前您正在调用使用 default 字符编码的构造函数,但您可以指定一个(UTF-8、UTF-16 等)。使用默认编码很少是个好主意,尽管显然您需要使用文本文件所使用的任何编码。 甚至 java.nio.file 包也具有与 [Files.readAllLines(...)](docs.oracle.com/javase/7/docs/api/java/nio/file/…, java.nio.charset.Charset)) 相同的功能 @GagandeepBali:在 Java 7 中,是的。如果我们最终在基础库中看到越来越多的 Guava 功能,我会很高兴... @Jon Skeet 你好,哥们,你能不能给 Guava 一些想法。它是什么或任何开始学习的链接?【参考方案2】:

这两种方法都可以,因为您使用了 BufferedReader,与无缓冲方法相比,它极大地提高了性能。在第二种情况下,不需要将 FileInputStream 包装在 DataInputStream 中。最后一种方法,让我们通过 InputStreamReader 指定文件编码,这通常很重要。

【讨论】:

【参考方案3】:

这取决于,如果你想读取一个只包含文本的文件(我的意思是一个文本文件),那么你应该使用第一种情况。

如果你想读取一些代表二进制数据的文件(我的意思是图像文件或视频文件等),你应该使用第二种情况。

【讨论】:

谢谢你的回答,但你能告诉我哪种替代方法 不,帖子中的代码根本没有使用DataInputStream.readLine。它使用BufferedReader.readLine - 请仔细查看。 @Sebs_Jedi 你用对了,你的代码绝对是写的。我之前误解了。对不起。【参考方案4】:

好吧,您最初从 FileInputStream 创建了一个 BufferedReader。你应该这样做:

FileInputStream fstream = new FileInputStream("C:\\testnew\\out.text");
BufferedInputStream bstream = new BufferedInputStream(fstream);

获得正确的流相关方法。

【讨论】:

为什么?他想阅读文本,所以 reader 更合适 - 我怀疑是否值得在 两个 层中显式缓冲。 我并不是说他应该在这种情况下使用这种方法。我的意思是必须以这种方式使用流相关的方法:) @AlexStybaev:所以要解决不同的问题,您会使用不同的代码吗?我认为这是理所当然的……您的回答与 OP 的实际问题有什么关系? @Jon Skeet:他询问了两种方法中的最佳方法,我指出第二种方法实际上并不正确,它是字节读取,而不是文本读取。不是和他的问题有关吗? @AlexStybaev:这与一个糟糕的方法 - 这是一个 的方法。 OP 想要阅读文本 - 因此他想要 Reader,而不是 InputStream。从InputStream 创建Reader正确方法是使用InputStreamReader,就像在帖子中一样。您还没有展示如何从 BufferedInputStream... 读取 text 数据

以上是关于在 FileReader 和 InputStreamReader 之间进行选择的主要内容,如果未能解决你的问题,请参考以下文章

我是不是需要同时关闭() FileReader 和 BufferedReader?

IO流FileReader和FileWriter

FileReader和FileInputStream的区别

使用 FileReader 和 JSZip.js 在浏览器中打开 zip 文件

bufferedreader 和 filereader 的具体区别

FileReader和FileWriter文件复制