Java读取文件的方法不同

Sim*_*ang 13 java file-io

似乎有很多,很多方法的Java(阅读文本文件BufferedReader,DataInputStream等等),我个人最喜欢的是ScannerFile在构造函数(它只是简单地使用mathy数据处理工作得更好,并具有熟悉的语法).

鲍里斯蜘蛛也提到了ChannelRandomAccessFile.

有人可以解释这些方法的优点和缺点吗?具体来说,我什么时候想要使用?

(编辑)我想我应该是具体的,并补充说我对该Scanner方法有强烈的偏好.所以真正的问题是,当不会想使用它?

Bor*_*der 14

让我们从头开始.问题是你想做什么?

了解文件的实际内容非常重要.文件是光盘上的字节集合,这些字节是您的数据.Java提供了各种级别的抽象:

  1. File(Input|Output)Stream- 将这些字节作为流读取byte.
  2. File(Reader|Writer)- 从字节流中读取数据流char.
  3. Scanner- 从流中读取char并标记它.
  4. RandomAccessFile- 将这些字节读取为可搜索的byte[].
  5. FileChannel - 以安全的多线程方式读取这些字节.

除了每个都有装饰器,例如你可以添加缓冲BufferedXXX.您可以为FileWriterwith 添加换行符感知功能PrintWriter.你可以把一个InputStreamReaderInputStreamReader(可以指定一个字符编码目前唯一的方式Reader).

所以 - 什么时候不想用它[a Scanner]?.

Scanner如果你愿意,你不会使用a (这些是一些例子):

  1. 读入数据为bytes
  2. 读入序列化的Java对象
  3. bytes从一个文件复制到另一个文件,可能会进行一些过滤.

Scanner(File file)构造函数采用FileFileInputStream使用平台默认编码打开a 也没有任何价值- 这几乎总是一个主意.通常认为您应该明确指定编码以避免令人讨厌的基于编码的错误.此外,流不是缓冲的.

所以你可能会更好

try (final Scanner scanner = new Scanner(new BufferedInputStream(new FileInputStream())), "UTF-8") {
    //do stuff
}
Run Code Online (Sandbox Code Playgroud)

丑陋,我知道.

值得注意的是Java 7提供了进一步的抽象层来消除循环文件的需要 - 这些都在Files类中:

byte[] Files.readAllBytes(Path path)
List<String> Files.readAllLines(Path path, Charset cs)
Run Code Online (Sandbox Code Playgroud)

这两种方法都将整个文件读入内存,这可能不合适.在Java 8中,通过添加对新StreamAPI的支持进一步改进了这一点:

Stream<String> Files.lines(Path path, Charset cs)
Stream<Path> Files.list(Path dir)
Run Code Online (Sandbox Code Playgroud)

例如,要从中获取单词,Path您可以执行以下操作:

    final Stream<String> words = Files.lines(Paths.get("myFile.txt")).
            flatMap((in) -> Arrays.stream(in.split("\\b")));
Run Code Online (Sandbox Code Playgroud)