4.NIO-文件编程
1.3、文件编程
1.3.1、FileChannel
获取
- FileInputStream 只能读
- FileOutStream 只能写
- RandomAccessFile 构造传参决定 rw:读写
读取
从channel读取填充到buffer
channel.read(buffer); 返回读到的字节数,如果-1,读到了末尾
写入
ByteBuffer buffer = ...;
buffer.put(...); // 存入数据
buffer.flip(); // 切换读模式
//因为writer并不能保证一次将buffer内容写入到channel
while(buffer.hasRemaining()) {
channel.write(buffer);
}
关闭
channle.close
位置
//获取当前位置
long pos = channel.position();
//设置位置
long newPos=...
channel.position(newPos);
获取文件大小
size();
强制写入
操作系统不会立即吸入。如果需要,force(true); 马上写入磁盘
1.3.2、Channel互传
public class TestFileChannelTransTo {
//最多只能传2g数据
public static void main(String[] args) {
try {
FileChannel from = new FileInputStream("data.txt").getChannel();
FileChannel to = new FileOutputStream("to.txt").getChannel();
from.transferTo(0, from.size(), to);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//超过2g,改进
public static void trans() {
try {
FileChannel from = new FileInputStream("data.txt").getChannel();
FileChannel to = new FileOutputStream("to.txt").getChannel();
long size = from.size();
for (long left = size; left > 0; ) {
left = left - from.transferTo((size - left), left, to);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
1.3.3、Path
- Path表示文件路径
- Paths工具类,获取Path
Path source = Paths.get("1.txt"); // 相对路径 使用 user.dir 环境变量来定位 1.txt
Path source = Paths.get("d:\\1.txt"); // 绝对路径 代表了 d:\1.txt
Path source = Paths.get("d:/1.txt"); // 绝对路径 同样代表了 d:\1.txt
Path projects = Paths.get("d:\\data", "projects"); // 代表了 d:\data\projects
.
代表了当前路径..
代表了上一级路径
例如目录结构如下
d:
|- data
|- projects
|- a
|- b
代码
Path path = Paths.get("d:\\data\\projects\\a\\..\\b");
System.out.println(path);
System.out.println(path.normalize()); // 正常化路径
会输出
d:\data\projects\a\..\b
d:\data\projects\b
1.3.4、Files
//1.检查文件是否存在
Path path = Paths.get("helloword/data.txt");
System.out.println(Files.exists(path));
//2.创建一级目录,不能创建多级,如若目录存在, FileAlreadyExistsException
Path path = Paths.get("helloword/d1");
Files.createDirectory(path);
//3.创建多级目录
Path path = Paths.get("helloword/d1/d2");
Files.createDirectories(path);
//4.复制文件,如果文件已存在,会抛异常 FileAlreadyExistsException
Path source = Paths.get("helloword/data.txt");
Path target = Paths.get("helloword/target.txt");
Files.copy(source, target);
//5.如果希望用 source 覆盖掉 target,需要用 StandardCopyOption 来控制
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
//6.移动文件,StandardCopyOption.ATOMIC_MOVE保证文件移动的原子性
Path source = Paths.get("helloword/data.txt");
Path target = Paths.get("helloword/data.txt");
Files.move(source, target, StandardCopyOption.ATOMIC_MOVE);
//7.删除文件,不存在抛出NoSuchFileException
Path target = Paths.get("helloword/target.txt");
Files.delete(target);
//8.删除目录,如果目录有内容,异常DirectoryNotEmptyException
Path target = Paths.get("helloword/d1");
Files.delete(target);
//9.遍历目录,底层是访问者模式
public class TestWalkFileTree {
public static void main(String[] args) throws IOException {
final AtomicInteger dirCount = new AtomicInteger();
final AtomicInteger fileCount = new AtomicInteger();
Files.walkFileTree(Paths.get("E:\\myself"), new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
System.out.println("文件夹==>" + dir);
dirCount.getAndIncrement();
return super.preVisitDirectory(dir, attrs);
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
fileCount.getAndIncrement();
return super.visitFile(file, attrs);
}
});
System.out.println("文件夹数==="+dirCount.get());
System.out.println("文件数==="+fileCount.get());
}
}
//7.遍历删除目录
public static void delDir() throws IOException {
Files.walkFileTree(Paths.get("E:\\home"),new SimpleFileVisitor<Path>(){
@Override//访问文件时
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file);
return super.visitFile(file, attrs);
}
@Override//访问文件夹后
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
Files.delete(dir);
return super.postVisitDirectory(dir, exc);
}
});
}
//8.复制文件夹及其下文件
public static void dirCopy() throws IOException {
Path source = Paths.get("E:\\ldhb\\IOT开发文档");
Path target = Paths.get("E:\\ldhb\\copy-test");
Files.walk(source).forEach(o -> {
String targetName = o.toString().replace(source.toString(), target.toString());
try {
if (Files.isDirectory(o)) {
Files.createDirectory(Paths.get(targetName));
} else {
Files.copy(o, Paths.get(targetName));
}
} catch (IOException e) {
throw new RuntimeException(e);
}
});
}
分类:
Netty
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
2021-10-12 阿里云的这群疯子