让我们从头开始。问题是你想做什么?
了解文件实际上是什么很重要。文件是光盘上字节的集合,这些字节是您的数据。Java提供了以上各种级别的抽象:
File(Input|Output)Stream
-将这些字节读取为byte
。File(Reader|Writer)
-从字节流中读取为char
。Scanner
-从的流中读取char
并将其标记化。RandomAccessFile
-将这些字节读取为可搜索的byte[]
。FileChannel
-以安全的多线程方式读取这些字节。
在每个装饰的顶部都有装饰器,例如,您可以使用添加缓冲
BufferedXXX。你可以断行的认识添加到
FileWriter用
PrintWriter。您可以将
InputStream转换为
Reader,然后将转换为
InputStreamReader(目前是指定的字符编码的唯一方法
Reader)。
所以- 我什么时候不想使用它[aScanner
]?。
如果愿意,您不会使用a
Scanner(这些示例):
- 读入数据为
byte
s - 读入序列化的Java对象
- 将
byte
s从一个文件复制到另一个文件,可能需要进行一些过滤。
这也是一文不值的
Scanner(File file)构造函数将
File并打开一个
FileInputStream与 平台默认的编码
-这是几乎总是一个 坏 主意。通常认为,您应该明确指定编码,以避免讨厌的基于编码的错误。此外,流不会被缓冲。
所以你可能会更好
try (final Scanner scanner = new Scanner(new BufferedInputStream(new FileInputStream())), "UTF-8") { //do stuff}丑,我知道。
值得注意的是,Java 7提供了更多的抽象层来消除循环文件的需要-
这些位于Files类中:
byte[] Files.readAllBytes(Path path)List<String> Files.readAllLines(Path path, Charset cs)
这两种方法都将整个文件读入内存,这可能不合适。在Java 8中,通过添加对新
StreamAPI的支持进一步改善了这一点:
Stream<String> Files.lines(Path path, Charset cs)Stream<Path> Files.list(Path dir)
例如,要从中获取单词流,
Path可以执行以下操作:
final Stream<String> words = Files.lines(Paths.get("myFile.txt")). flatMap((in) -> Arrays.stream(in.split("\b")));


