老铁们,大家好,相信还有很多朋友对于深入解析Java NIO:学习笔记第五篇和的相关问题不太懂,没关系,今天就由我来为大家分享分享深入解析Java NIO:学习笔记第五篇以及的问题,文章篇幅可能偏长,希望可以帮助到大家,下面一起来看看吧!
路径实例表示文件系统中的路径。路径可以指向文件或目录,路径可以是绝对路径或相对路径。在某些操作系统中,请勿将文件系统路径与环境变量中的路径混淆。 java.nio.file.Path接口与path环境路径变量无关。
在许多方面,java.nio.file.Path 接口与java.io.File 类相似,但存在一些细微的差异。但在很多情况下,可以使用Path 接口来代替File 类的使用。
创建 Path 对象
您可以使用Paths 类(java.nio.file.Paths) 中名为Paths.get() 的静态方法创建Path 实例。 get() 方法是Path 实例的工厂方法。示例如下:
公共类路径示例{
公共静态无效主(字符串[] args){
//使用绝对路径创建
路径absolutePath=Paths.get("D:\test\1.txt");
//使用相对路径创建
路径relativePath=Paths.get("D:\test", "1.txt");
System.out.println(absolutePath.equals(relativePath)); //真的
}
}请注意,路径分隔符在Windows 上为“”,在Linux 上为“/”。
Paths 类只有2 个方法:
方法说明static Path get(String first, String. more) 转换路径字符串或连接成路径时形成路径字符串的字符串序列。 static Path (URI uri) 将给定的URI 转换为路径对象。 Path接口的一些方法:
方法说明booleanendsWith(Path other) 测试此路径是否以给定路径结束。 boolean equals(Object other) 取决于文件系统实现。通常不区分大小写,但有时也区分大小写。不访问文件系统。 Path Normalize() 返回一个消除了多余名称元素的路径,例如“.”、“.” Path toAbsolutePath() 返回一个表示该路径的绝对路径的路径对象。 File toFile() 返回表示此路径的File 对象。 String toString() 返回的路径字符串使用默认的名称分隔符来分隔路径中的名称。
Files
NIO 文件类(java.nio.file.Files) 提供了几种操作文件系统中的文件的方法。 File 类与java.nio.file.Path 类一起工作。您需要先了解Path 类,然后才能使用它。文件类。
判断文件是否存在
static boolean isn"t(Path path, LinkOption. options) options 参数用于指示当文件是符号链接时如何处理符号链接。默认是处理符号链接。 LinkOption 对象是一个枚举类,它定义如何处理符号链接的选项。整个类只有一个NOFOLLOW_LINKS;它始终处于打开状态,表示不遵循符号链接。
createDirectory(Path path) 创建目录
路径输出=Paths.get("D:\test\output");
路径newDir=Files.createDirectory(output);
//文件.createDirectories(输出); //该方法也可以创建不存在的父目录。
System.out.println(输出==newDir); //真的
System.out.println(Files.exists(输出)); //true 如果目录创建成功,则返回一个指向新创建路径的Path实例。该实例和参数是同一个实例。
如果目录已经存在,则抛出FileAlreadyExistsException。如果出现其他问题,例如,如果所需的新目录的父目录不存在,则可能会抛出IOException。
复制文件
共有3种复制方式:
静态长复制(路径源,OutputStream 输出);
静态路径复制(路径源、路径目标、CopyOption.选项);
static long copy(InputStream in, Path target, CopyOption. options) 其中,CopyOption选项可以选择指定复制模式。一般来说,它的子枚举类StandardCopyOption提供了选项。有3种模式。第二个参数是可变参数。可以多种组合使用:
ATOMIC_MOVE: 原子复制,不会被线程调度机制打断的操作;一旦开始,就会一直运行到结束; COPY_ATTRIBUTES:同时复制属性,默认不复制属性; REPLACE_EXISTING:重写模式,将覆盖现有的目标文件;示例如下:
路径sourcePath=Paths.get("D:\test\source.txt"); //源文件必须先存在
路径desPath=Paths.get("D:\test\des.txt"); //目标文件不需要存在
Files.copy(sourcePath, desPath); //默认情况下,如果目标文件已经存在则抛出异常
Files.copy(sourcePath, desPath, StandardCopyOption.REPLACE_EXISTING); //覆盖模式注意:复制文件夹时,只能复制空文件夹。如果文件夹不为空,则需要递归复制,否则只能得到一个空文件夹。并且该文件夹中的文件不会被复制。
移动文件/文件夹
移动文件或文件夹只有1 种方法:
静态路径移动(路径源、路径目标、CopyOption.选项);如果文件是符号链接,则移动符号链接本身,而不是符号链接指向的实际文件。
和移动文件一样,还有第三个可选参数CopyOption,参考上面。如果移动文件失败,例如文件已存在于目标路径中并且省略了覆盖选项,或者要移动的源文件不存在等,则可能会抛出IOException。
与复制文件夹不同,如果文件夹中有内容,复制只会复制空文件夹,而移动会将文件夹中的所有内容一起移动。以下是移动文件夹:的示例
//将s目录移动到一个不存在的新目录
路径s=Paths.get("D:\s");
路径d=Paths.get("D:\test\test");
Files.createDirectories(d.getParent());
文件.移动(s,d);与Linux mv 命令一样,重命名文件与移动文件相同。移动文件还可以将文件移动到不同的目录并同时更改其名称。另外,java.io.File类还可以使用其renameTo()方法来移动文件,但现在java.nio.file.Files类也具有文件移动功能。
删除文件/文件夹
static void delete(Path 路径);
静态布尔deleteIfExists(路径路径); //如果通过此方法删除文件,则返回true。如果文件是目录,则该目录必须为空才能删除。
Files.walkFileTree() 静态方法
删除和复制文件夹时,如果文件夹为空,则删除失败或只能复制空文件夹。这时,可以使用walkFileTree() 方法遍历文件树,然后访问FileVisitor 对象的File() 方法来执行删除或复制文件操作。
Files类有2个重载的walkFileTree()方法,如下:
静态路径walkFileTree(路径开始,
文件访问者?超级探路者);
静态路径walkFileTree(路径开始,
设置选项,
int 最大深度,
文件访问者?超级探路者); walkfiletree() 方法以Path 实例和FileVisitor 作为参数,可以递归遍历目录树。 Path实例指向要遍历的目录。 FileVisitor 在遍历过程中被调用。首先介绍FileVisitor接口:
公共接口FileVisitor{
FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs) 抛出IOException;
FileVisitResult VisitFile(T file, BasicFileAttributes attrs) 抛出IOException;
FileVisitResult VisitFileFailed(T file, IOException exc) 抛出IOException;
FileVisitResult postVisitDirectory(T dir, IOException exc) 抛出IOException;
}您必须自己实现FileVisitor 接口并将其实现的实例传递给walkFileTree() 方法。在目录遍历过程中,FileVisitor 实现的四个方法会在不同的时间被调用,分别代表对遍历到的文件或目录进行哪些操作。如果不需要使用所有方法,可以扩展SimpleFileVisitor 类,该类包含FileVisitor 接口中所有方法的默认实现。
Files.walkFileTree(inputPath, new FileVisitor() {
//在访问文件夹之前调用此方法
@覆盖
公共FileVisitResult preVisitDirectory(路径目录,BasicFileAttributes attrs)抛出IOException {
System.out.println("预访问dir:" + dir);
返回FileVisitResult.CONTINUE;
}
//对于每个访问的文件都会调用此方法,仅针对文件,而不是目录。
@覆盖
公共FileVisitResult 访问文件(路径文件,BasicFileAttributes attrs)抛出IOException {
返回FileVisitResult.CONTINUE;
}
//如果访问文件失败,将调用此方法。它只对文件执行,对目录不会执行。
@覆盖
公共FileVisitResult VisitFileFailed(路径文件, IOException exc) 抛出IOException {
返回FileVisitResult.CONTINUE;
}
//访问文件夹后会调用该方法
@覆盖
公共FileVisitResult postVisitDirectory(Path dir, IOException exc) 抛出IOException {
返回FileVisitResult.CONTINUE;
}
});这四个方法都返回一个FileVisitResult枚举实例。 FileVisitResult 枚举包含以下四个选项:
CONTINUE:继续TERMINATE:终止SKIP_SIBLINGS:跳过兄弟节点然后继续SKIP_SUBTREE:跳过子树(不访问该目录的条目)并继续,仅在preVisitDirectory 方法返回时才有意义,否则与CONTINUE 相同。通过返回这些值之一,被调用的方法可以决定文件遍历期间下一步要做什么。
搜索文件
walkFileTree() 方法也可用于搜索文件。以下示例扩展SimpleFileVisitor 以查找名为input.txt 的文件:
路径rootPath=Paths.get("D:\test");
String fileToFind=File.separator + "input.txt";
Files.walkFileTree(rootPath, new SimpleFileVisitor() {
@覆盖
公共FileVisitResult 访问文件(路径文件,BasicFileAttributes attrs)抛出IOException {
String fileString=file.toAbsolutePath().toString();
System.out.println("pathString:" + fileString);
if (fileString.endsWith(fileToFind)) {
System.out.println("在path:找到文件" + fileString);
返回FileVisitResult.TERMINATE;
}
返回FileVisitResult.CONTINUE;
}
同样,删除有内容的目录时,可以重写visitFile()方法并在其内部执行文件删除操作,重写postVisitDirectory()方法并在其内部执行目录删除操作。
Files 类中的其他方法
Files 类包含许多其他有用的函数,例如用于创建符号链接、确定文件大小、设置文件权限等的函数。有关java.nio.file.Files 类的更多信息,请查看JavaDoc
管道 Pipe
管道是两个线程之间的单向数据连接。管道具有源通道和汇通道。当数据写入到宿通道时,可以从源通道读取数据。
下面解释一下管道原理:
image
使用管道进行读取数据
我们先看一个完整的例子:
公共类管道示例{
公共静态无效主(字符串[] args)抛出IOException {
管道管道=Pipe.open();
Pipe.SinkChannel sinkChannel=pipeline.sink(); //接收通道写入数据
字符串数据="某个字符串";
ByteBuffer 缓冲区=ByteBuffer.allocate(32);
缓冲区.clear();
buffer.put(data.getBytes());
缓冲区.flip(); //翻转缓冲区并准备读取
while (buffer.hasRemaining()) {
inkChannel.write(缓冲区); //将Buffer数据写入sink通道
}
Pipe.SourceChannel sourceChannel=pipeline.source(); //源通道读取数据
ByteBuffer readBuffer=ByteBuffer.allocate(32);
int bytesRead=sourceChannel.read(readBuffer); //返回值代表读取了多少数据
System.out.println("Read:" + bytesRead); //读取: 11
System.out.println(new String(readBuffer.array())); //一些字符串
}
}在上面的代码中,您必须首先创建一个管道。打开管道后,使用同一个管道对象来获取对应的sink通道和source通道。这将自动连接两个通道。相比之下,在标准IO管道中,它们是单独创建的。读取管道并写入管道,然后在构造函数中将它们连接起来或使用pipe1.connect(pipe2)方法,如下:
PipedOutputStream 输出=new PipedOutputStream();
PipedInputStream 输入=new PipedInputStream();
输入.连接(输出);
【深入解析Java NIO:学习笔记第五篇】相关文章:
2.米颠拜石
3.王羲之临池学书
8.郑板桥轶事十则
用户评论
终于等到JAVA NIO学习笔记第五篇了!
有20位网友表示赞同!
Java NIO真是太重要了,我还在努力理解它的用法。
有16位网友表示赞同!
这篇文章写得真好,很详细地讲解了NIO的关键概念。
有18位网友表示赞同!
我已经把前面的几篇学习笔记都看过了,感觉这次的重点内容更精彩。
有5位网友表示赞同!
希望能多分享一些实际应用案例,这样更容易理解NIO的使用场景。
有20位网友表示赞同!
我对异步编程一直很感兴趣,希望这篇文章能让我深入了解NIO在异步处理中的优势。
有18位网友表示赞同!
有没有小伙伴和我一样是Java程序员?一起学习NIO吧!
有15位网友表示赞同!
感觉NIO的读写效率比BIO高很多,对高并发场景特别友好啊。
有10位网友表示赞同!
希望可以多探讨一些NIO遇到的问题和解决方法,互相交流经验。
有8位网友表示赞同!
这篇文章让我对NIO有了更深入的理解,我要好好总结一下今天学到的知识点。
有6位网友表示赞同!
学习Java NIO真的需要时间和耐心,不过最终的目标是值得的!
有13位网友表示赞同!
感觉NIO可以用在很多地方,比如服务器开发、大数据处理等等。
有16位网友表示赞同!
我已经开始运用NIO来优化我的代码了,效率确实提高了很多!
有9位网友表示赞同!
对NIO还不算很熟悉,希望通过这篇文章能快速掌握其基本概念和使用方法。
有18位网友表示赞同!
感谢作者的分享,学习笔记非常有价值!
有19位网友表示赞同!
希望能看到更多关于Java NIO的学习资源,帮助我们更好地理解和应用它。
有11位网友表示赞同!
最近在项目中遇到了NIO的使用难题,希望这篇文章能给我一些启发。
有5位网友表示赞同!