【问题标题】:Choosing between FileReader and InputStreamReader在 FileReader 和 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 没有任何贡献:没有它,代码也可以正常工作。

标签: java java-io


【解决方案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 数据
    猜你喜欢
    • 2011-12-20
    • 2011-01-29
    • 2010-12-06
    • 2013-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-12
    相关资源
    最近更新 更多