Pipe
- 两个线程之间的单向数据连接,从
source通道读取和sink通道写入
//获取通道
Pipe pipe = Pipe.open()
//写入
Pipe.SinkChannel sink = pipe.sink()
ByteBuffer bbSink = ByteBuffer.allocate(1024)
bbSink.put("PipeDemo".getBytes())
bbSink.flip()
sink.write(bbSink)
//读取
Pipe.SourceChannel source = pipe.source()
ByteBuffer bbSource = ByteBuffer.allocate(1024)
int len = source.read(bbSource)
System.out.println(new String(bbSource.array(), 0, len))
source.close()
sink.close()
两个线程的案例
Pipe pipe = Pipe.open();
new Thread(() -> {
Pipe.SourceChannel source = pipe.source();
ByteBuffer bb = ByteBuffer.allocate(1024);
bb.clear();
try {
int len = source.read(bb);
if (len != -1) {
bb.flip();
System.out.println(new String(bb.array(), 0, len));
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " - finished");
},"B").start();
new Thread(() -> {
Pipe.SinkChannel sink = pipe.sink();
ByteBuffer bb = ByteBuffer.allocate(1024);
bb.put(Thread.currentThread().getName().getBytes());
bb.flip();
try {
TimeUnit.SECONDS.sleep(1);
sink.write(bb);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
sink.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " - finished");
}, "A").start();
FileLock
- 文件锁,同一个时间,只能有一个程序修改此文件
- 进程级别,解决多个进程并发访问、修改同一个文件的问题;同一个进程内的多个线程,可以同时访问,修改文件
- 进程对文件不能重复加锁
- 锁释放
- 调用
release()
- 关闭对应的
FileChannel对象
- 当前JVM退出
- 排它锁,独占锁,对文件加锁后,其他进程不能读写此文件,直到该进程释放锁
- 共享锁,其他进程只能读此文件
- lock,阻塞式的,如果未获取到文件锁,会一直阻塞当前线程
- 非阻塞式,尝试获取文件锁,成功返回锁对象,失败返回null
String pathName = "/Users/mzx/Desktop/java/nio/test4.txt"
String input = Thread.currentThread().getName()
Path path = Paths.get(pathName)
ByteBuffer bb = ByteBuffer.allocate(1024)
FileChannel fc = FileChannel.open(path, StandardOpenOption.READ, StandardOpenOption.WRITE)
//加锁,如果是独占锁,其他进程不能获得锁;如果是共享锁,就可以获得
FileLock lock = fc.lock(0, Long.MAX_VALUE, true)
fc.position(fc.size() - 1)
fc.write(ByteBuffer.wrap(input.getBytes()))
//是否是共享锁
System.out.println(lock.isShared())
//读
fc.position(0)
int len = fc.read(bb)
System.out.println(len)
bb.flip()
System.out.println(new String(bb.array(), 0, len))
TimeUnit.SECONDS.sleep(300)
Path
String pathName = "/Users/mzx/Desktop/java/nio/test4.txt"
//创建决定路径
Path path = Paths.get(pathName)
System.out.println(path)
//创建相对路径,路径拼接
Path path1 = Paths.get("/Users/mzx/Desktop/java", "nio/test4.txt")
System.out.println(path1)
//sout
/Users/mzx/Desktop/java/nio/test4.txt
/Users/mzx/Desktop/java/nio/test4.txt
//..代表Desktop的上一层
String pathName1 = "/Users/mzx/Desktop/../java/nio/test4.txt"
Path path2 = Paths.get(pathName1)
System.out.println(path2)
Path path3 = path2.normalize()
System.out.println(path3)
//sout
/Users/mzx/Desktop/../java/nio/test4.txt
/Users/mzx/java/nio/test4.txt
Files
Path path = Paths.get("/Users/mzx/Desktop/java/nio/test");
Files.createDirectory(path);
Files.createDirectories(Paths.get("/Users/mzx/Desktop/java/nio/test1/test"));
Path from = Paths.get("/Users/mzx/Desktop/java/nio/test1.txt")
Path to = Paths.get("/Users/mzx/Desktop/java/nio/test/test10.txt")
Files.copy(from,to)
//覆盖
Files.copy(from,to, StandardCopyOption.REPLACE_EXISTING)
Path from = Paths.get("/Users/mzx/Desktop/java/nio/test/test101.txt")
Path to = Paths.get("/Users/mzx/Desktop/java/nio/test/test10.txt")
//可以进行重命名,文件名与to相同,会异常,可以进行覆盖
Files.move(from, to, StandardCopyOption.REPLACE_EXISTING)
Path path = Paths.get("/Users/mzx/Desktop/java/nio/test/test10.txt")
Files.delete(path)
Files.deleteIfExists(path)
Path root = Paths.get("/Users/mzx/Desktop/java/nio")
//找文件
String fileToFind = File.separator + "test4.txt"
Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
String fileString = file.toAbsolutePath().toString()
if (fileString.endsWith(fileToFind)) {
System.out.println("success - " + file.toAbsolutePath())
return FileVisitResult.TERMINATE
}
System.out.println(file.toAbsolutePath())
return FileVisitResult.CONTINUE
}
})