似乎有很多,很多方法的Java(阅读文本文件BufferedReader,DataInputStream等等),我个人最喜欢的是Scanner用File在构造函数(它只是简单地使用mathy数据处理工作得更好,并具有熟悉的语法).
鲍里斯蜘蛛也提到了Channel和RandomAccessFile.
有人可以解释这些方法的优点和缺点吗?具体来说,我什么时候想要使用?
(编辑)我想我应该是具体的,并补充说我对该Scanner方法有强烈的偏好.所以真正的问题是,当不会想使用它?
Bor*_*der 14
让我们从头开始.问题是你想做什么?
了解文件的实际内容非常重要.文件是光盘上的字节集合,这些字节是您的数据.Java提供了各种级别的抽象:
File(Input|Output)Stream- 将这些字节作为流读取byte.File(Reader|Writer)- 从字节流中读取数据流char.Scanner- 从流中读取char并标记它.RandomAccessFile- 将这些字节读取为可搜索的byte[].FileChannel - 以安全的多线程方式读取这些字节.除了每个都有装饰器,例如你可以添加缓冲BufferedXXX.您可以为FileWriterwith 添加换行符感知功能PrintWriter.你可以把一个InputStream成Reader与InputStreamReader(可以指定一个字符编码目前唯一的方式Reader).
所以 - 什么时候不想用它[a Scanner]?.
Scanner如果你愿意,你不会使用a (这些是一些例子):
bytesbytes从一个文件复制到另一个文件,可能会进行一些过滤.Scanner(File file)构造函数采用File并FileInputStream使用平台默认编码打开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)