文件查找
粗糙的方法,在 path
上调用 toString()
,然后使用 string
操作查看结果。
java.nio.file
有更好的解决方案:通过在 FileSystem
对象上调用 getPathMatcher()
获得一个 PathMatcher
,然后传入感兴趣的模式。
模式
模式
glob
glob
比较简单,实际上功能非常强大,因此可以使用 glob
解决许多问题。
在 matcher 中,glob 表达式开头的 **/ 表示“当前目录及所有子目录”,这在当你不仅仅要匹配当前目录下特定结尾的 Path 时非常有用。
单 * 表示“任何东西”,然后是一个点,然后大括号表示一系列的可能性—我们正在寻找以 .tmp 或 .txt 结尾的东西
regex
如果问题更复杂,可以使用 regex
文件读写
如果一个文件很“小”,即“它运行得足够快且占用内存小”,那java.nio.file.Files
类中的实用程序将帮助你轻松读写文本和二进制文件。
Files.readAllLines()
一次读取整个文件(因此,“小”文件很有必要),产生一个List<String>
- 只需将
Path
传递给 readAllLines() readAllLines()
有一个重载版本,包含一个Charset
参数来存储文件的 Unicode 编码Files.write()
被重载以写入byte
数组或任何Iterable
对象(它也有Charset
选项):
ClassReader cr = new ClassReader("com/javaedge/asm/TestAsm"); ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); ClassVisitor cv = new MyClassVisitor(cw); cr.accept(cv, ClassReader.SKIP_DEBUG); byte[] data = cw.toByteArray(); Files.write(Paths.get("src/main/java/com/javaedge/asm/out.class"), data); System.out.println("generate success!");
如果文件大小有问题怎么办? 比如说:
- 文件太大,如果你一次性读完整个文件,你可能会耗尽内存。
- 您只需要在文件的中途工作以获得所需的结果,因此读取整个文件会浪费时间。
Files.lines()
方便地将文件转换为行的 Stream
:
流式处理,跳过 13 行,然后选择下一行并将其打印出来。
Files.lines()
对于把文件处理行的传入流时非常有用,但是如果你想在 Stream
中读取,处理或写入怎么办?这就需要稍微复杂的代码:
因为我们在同一个块中执行所有操作,所以这两个文件都可以在相同的 try-with-resources 语句中打开。
PrintWriter
是一个旧式的 java.io
类,允许你“打印”到一个文件,所以它是这个应用的理想选择
总结
虽然本章对文件和目录操作做了相当全面的介绍,但是仍然有没被介绍的类库中的功能——一定要研究 java.nio.file 的 Javadocs,尤其是 java.nio.file.Files 这个类。
Java 7 和 8 对于处理文件和目录的类库做了大量改进。如果您刚刚开始使用 Java,那么您很幸运。在过去,它令人非常不愉快,Java 设计者以前对于文件操作不够重视才没做简化。对于初学者来说这是一件很棒的事,对于教学者来说也一样。我不明白为什么花了这么长时间来解决这个明显的问题,但不管怎么说它被解决了,我很高兴。使用文件现在很简单,甚至很有趣,这是你以前永远想不到的。