使用 Files
操作文件
查看
Path path = Paths.get(System.getProperty("user.dir")
+ "/jdk8Test/src/main/resources/file.txt");
// 查看文件大小
Files.size(path);
写入
Path path = Paths.get(System.getProperty("user.dir")
+ "/jdk8Test/src/main/resources/file.txt");
// 写数据
int writeCount = 100;
List<String> info = IntStream.rangeClosed(0, writeCount)
.parallel()
.mapToObj(e -> "content" + e).collect(Collectors.toList());
Files.write(path, info);
查询
int readCount = 20;
// 2.1 读取
List<String> collect = Files.lines(path).limit(readCount).collect(Collectors.toList());
System.out.println(collect);
// 2.2 跳过读取
collect = Files.lines(path).skip(readCount).limit(readCount).collect(Collectors.toList());
System.out.println(collect);
// 3. 记录行数
AtomicLong atomicLong = new AtomicLong(0L);
Files.lines(path).forEach(e -> {
atomicLong.incrementAndGet();
});
System.out.println(atomicLong.get());
使用 Files 类静态方法进行文件操作注意释放文件句柄
// 1 Too many open files
// 并没有复现
LongAdder longAdder = new LongAdder();
LongAdder finalLongAdder = longAdder;
IntStream.rangeClosed(1, 1000).forEach(i -> {
try {
Files.lines(path).forEach(line -> finalLongAdder.increment());
} catch (IOException e) {
e.printStackTrace();
}
});
// 2 用 try with resources 包裹
longAdder = new LongAdder();
LongAdder finalLongAdder1 = longAdder;
IntStream.rangeClosed(1, 1000).forEach(i -> {
// try with resources
try (Stream<String> lines = Files.lines(path)) {
lines.forEach(line -> finalLongAdder1.increment());
} catch (IOException e) {
e.printStackTrace();
}
});
复制
- 使用
BufferedXXX
进行文件复制 - 也可以使用
FileChannel
```java Path path = Paths.get(System.getProperty(“user.dir”)
Path pathTo = Paths.get(System.getProperty(“user.dir”)+ "/jdk8Test/src/main/resources/file.txt");
+ "/jdk8Test/src/main/resources/file2.txt");
// 文件复制 FileChannel in = FileChannel.open(path); FileChannel out = FileChannel.open(pathTo, StandardOpenOption.CREATE, StandardOpenOption.WRITE); in.transferTo(0, in.size(), out); ```
BufferedXXX 的意义
- 内部维护一个 8kb 的缓冲区,应对不一样的场景
- 避免单字节读取的缓慢
- 避免应对未知大小数据时,如何取舍缓冲区的大小(反正就是用了就稳定有缓冲区了)