Java7技术系列:try-with-resource Java7技术系列:int与二进制的转换优化 Java7技术系列:MultiCatchException Java7技术系列:NIO.2异步IO Java7技术系列:DI依赖注入 Java7技术系列:Queue Java7技术系列:Java并发
文章目录
1 NIO.2相关API介绍1.1 NIO.2关键基础类1.2 文件处理的基础类
2 Path2.1 获取Path2.2 从Path中获取信息2.3 去除冗余项2.4 转换Path2.5 java7的Path与java7之前的File之间转换2.6 文件属性
3 文件操作3.1 创建文件3.2 删除文件3.3 复制文件3.4 移动文件
4 文件读写数据4.1 读文件4.2 写文件4.3 读写文件的简化4.4 拥有文件寻址的FileChannel读写文件4.5 文件修改监听通知WatchService
5 处理目录与目录树5.1 目录树查找文件过滤5.2 遍历目录树
6 异步IO7 Socket和Channel整合
1 NIO.2相关API介绍
NIO.2把位置(由Path表示)的概念和物理文件系统的处理(比如复制一个文件)分得很清楚,物理文件系统通常是由Files辅助类实现的【即Path不一定代表真实的文件或目录,你可以随心所欲地操作Path,用Files中的功能来检查文件是否存在,并对它进行处理】
【个人理解:Path是虚拟的,不对实际的文件进行操作处理,只读取Path指定目录或文件的信息; Files是会对实际的文件进行操作处理,比如复制、读写等】
1.1 NIO.2关键基础类
API描述
NIO2Path类中的方法可以用来获取路径信息,访问该路径中的各元素,将路径转换为其他形式,或提取路径中的一部分。有的方法还可以匹配路径字串以及移除路径中的冗余项Paths工具类,提供返回一个路径的辅助方法,比如get(String first, String… more)和get(URI uri)FileSystem与文件系统交互的类,无论是默认的文件系统,还是通过其统一资源标识(URI)获取的可选文件系统FileSystems工具类,提供各种方法,比如其中用于返回默认文件系统的FileSystems.getDefault()
相对路径与绝对路径(以访问 /java7developer/src/main 目录为例):
比如程序在路径 /java7developer/src/test 目录下运行,代码要读取位于/java7developer/src/main目录的文件名。
为了进入 /java7developer/src/main 目录,可以用相对路径 ../main。
如果程序在路径 /java7developer/src/test/java/com/java7developer 运行,用相对路径 ../main 则无法进入目标目录,而是会访问到不存在的目录 /java7developer/src/test/java/com/main,只能用绝对路径 /java7developer/src/main。
【总结:使用相对路径,相当于将当前运行程序的目录回退一个目录,然后再进入对应的目标目录,也就是说,要访问的目录与程序运行目录,它们的上一级目录是相同的,此时才能使用相对路径正确访问】
1.2 文件处理的基础类
API描述
Files实现复制、移动、删除或处理文件的工具类WatchService用来监视文件或目录的核心类,不管它们有没有变化
2 Path
2.1 获取Path
private static void operate1() {
java
.nio
.file
.Path path
= Paths
.get("/usr/bin/zip");
java
.nio
.file
.Path samePath
= FileSystems
.getDefault().getPath("/usr/bin/zip");
java
.nio
.file
.Path absolutePath
= path
.toAbsolutePath();
}
2.2 从Path中获取信息
private static void operate2() {
java
.nio
.file
.Path path
= Paths
.get("/usr/bin/zip");
java
.nio
.file
.Path filename
= path
.getFileName();
int nameCount
= path
.getNameCount();
java
.nio
.file
.Path parent
= path
.getParent();
java
.nio
.file
.Path root
= path
.getRoot();
java
.nio
.file
.Path subpath
= parent
.subpath(0, 2);
}
2.3 去除冗余项
private static void operate3() {
java
.nio
.file
.Path normalizePath
= Paths
.get("./Listing_2_1.java").normalize();
try {
java
.nio
.file
.Path realPath
= Paths
.get("/usr/logs/log1.txt").toRealPath(LinkOption
.NOFOLLOW_LINKS
);
} catch (IOException e
) {
e
.printStackTrace();
}
}
2.4 转换Path
private static void operate4() {
java
.nio
.file
.Path prefix
= Paths
.get("/uat/");
java
.nio
.file
.Path completePath
= prefix
.resolve("conf/application.properties");
String java7developerPath
= "/java7developer/src/test/java/com/java7developer";
String mainPath
= "/java7developer/src/main";
java
.nio
.file
.Path java7developerDir
= Paths
.get(java7developerPath
);
java
.nio
.file
.Path mainDir
= Paths
.get(mainPath
);
java
.nio
.file
.Path java7developerRelativizePath
= java7developerDir
.relativize(mainDir
);
java
.nio
.file
.Path mainRelativizePath
= mainDir
.relativize(java7developerDir
);
System
.out
.println(java7developerRelativizePath
);
System
.out
.println(mainRelativizePath
);
}
2.5 java7的Path与java7之前的File之间转换
private static void operate5() {
File file
= new File("../Listing_2_1.java");
java
.nio
.file
.Path path
= file
.toPath();
path
.toAbsolutePath();
file
= path
.toFile();
}
2.6 文件属性
private static void operate3() {
java
.nio
.file
.Path normalizePath
= Paths
.get("./Listing_2_1.java").normalize();
try {
java
.nio
.file
.Path realPath
= Paths
.get("/usr/logs/log1.txt").toRealPath(LinkOption
.NOFOLLOW_LINKS
);
} catch (IOException e
) {
e
.printStackTrace();
}
}
3 文件操作
3.1 创建文件
java
.nio
.file
.Path path
= Paths
.get("D:\\Backup\\MyStuff.txt");
Set
<PosixFilePermission> perms
= PosixFilePermissions
.fromString("rw-rw-rw-");
FileAttribute
<Set
<PosixFilePermission>> attr
= PosixFilePermissions
.asFileAttribute(perms
);
Files
.createFile(path
, attr
);
3.2 删除文件
java
.nio
.file
.Path target
= Paths
.get("D:\\Backup\\MyStuff.txt");
Files
.delete(target
);
3.3 复制文件
java
.nio
.file
.Path sourcePath
= Paths
.get("C:\\MyDocuments\\Stuff.txt");
java
.nio
.file
.Path targetPath
= Paths
.get("D:\\Backup\\MyStuff.txt");
Files
.copy(sourcePath
, targetPath
, StandardCopyOption
.REPLACE_EXISTING
);
3.4 移动文件
java
.nio
.file
.Path sources
= Paths
.get("C:\\MyDocuments\\Stuff.txt");
java
.nio
.file
.Path targets
= Paths
.get("D:\\Backup\\MyStuff.txt");
Files
.move(sources
, targets
, StandardCopyOption
.REPLACE_EXISTING
, StandardCopyOption
.COPY_ATTRIBUTES
);
4 文件读写数据
4.1 读文件
java
.nio
.file
.Path path
= Paths
.get("/tmp/app.log");
try (BufferedReader reader
= Files
.newBufferedReader(path
, StandardCharsets
.UTF_8
)) {
String line
;
while ((line
= reader
.readLine()) != null
) {
System
.out
.println(line
);
}
} catch (IOException e
) {
e
.printStackTrace();
}
4.2 写文件
java
.nio
.file
.Path logPath
= Paths
.get("/tmp/app.log");
try (BufferedWriter writer
= Files
.newBufferedWriter(logPath
, StandardOpenOption
.WRITE
)) {
writer
.write("Hello World!");
} catch (IOException e
) {
e
.printStackTrace();
}
4.3 读写文件的简化
java
.nio
.file
.Path logFile
= Paths
.get("/tmp/app.log");
try {
List
<String> lines
= Files
.readAllLines(logFile
);
byte[] bytes
= Files
.readAllBytes(path
);
} catch (IOException e
) {
e
.printStackTrace();
}
4.4 拥有文件寻址的FileChannel读写文件
java
.nio
.file
.Path file
= Paths
.get("/temp/app.log");
ByteBuffer buffer
= ByteBuffer
.allocate(1024);
FileChannel channel
;
try {
channel
= FileChannel
.open(file
, StandardOpenOption
.READ
);
channel
.read(buffer
, channel
.size() - 1000);
} catch (IOException e
) {
e
.printStackTrace();
}
4.5 文件修改监听通知WatchService
try {
boolean isShutdown
= false;
WatchService watcher
= FileSystems
.getDefault().newWatchService();
java
.nio
.file
.Path dir
= Paths
.get("/usr/vincent");
WatchKey key
= dir
.register(watcher
, StandardWatchEventKinds
.ENTRY_MODIFY
);
while (!isShutdown
) {
key
= watcher
.take();
for (WatchEvent
<?> event
: key
.pollEvents()) {
if (event
.kind() == StandardWatchEventKinds
.ENTRY_MODIFY
) {
System
.out
.println("dir changed!");
isShutdown
= true;
}
}
key
.reset();
}
} catch (IOException | InterruptedException e
) {
e
.printStackTrace();
}
5 处理目录与目录树
5.1 目录树查找文件过滤
java
.nio
.file
.Path dir
= Paths
.get("C:\\workspace\\java7developer");
try {
DirectoryStream
<java
.nio
.file
.Path
> stream
= Files
.newDirectoryStream(dir
, "*.properties");
for (java
.nio
.file
.Path path
: stream
) {
System
.out
.println(path
.getFileName());
}
} catch (IOException e
) {
e
.printStackTrace();
}
5.2 遍历目录树
java
.nio
.file
.Path startingDir
= Paths
.get("C:\\workspace\\java7developer\\src");
try {
Files
.walkFileTree(startingDir
, new FindJavaVisitor());
} catch (IOException e
) {
e
.printStackTrace();
}
private static final class FindJavaVisitor extends SimpleFileVisitor<java
.nio
.file
.Path
> {
@Override
public FileVisitResult
visitFile(java
.nio
.file
.Path file
, BasicFileAttributes attrs
) throws IOException
{
if (file
.toString().endsWith(".java")) {
System
.out
.println(file
.getFileName());
}
return FileVisitResult
.CONTINUE
;
}
}
6 异步IO
privatestatic
void operate10() {
try {
java
.nio
.file
.Path file
= Paths
.get("/usr/vincent/foobar.txt");
AsynchronousFileChannel channel
= AsynchronousFileChannel
.open(file
);
ByteBuffer byteBuffer
= ByteBuffer
.allocate(100_0000
);
Future
<Integer> result
= channel
.read(byteBuffer
, 0);
while (!result
.isDone()) {
System
.out
.println("do something in main thread");
}
Integer bytesRead
= result
.get();
System
.out
.println("Bytes read[" + bytesRead
+ "]");
} catch (IOException | InterruptedException
| ExecutionException e
) {
e
.printStackTrace();
}
try {
java
.nio
.file
.Path files
= Paths
.get("/usr/vincent/foobar.txt");
AsynchronousFileChannel channel
= AsynchronousFileChannel
.open(files
);
ByteBuffer byteBuffer
= ByteBuffer
.allocate(100_0000
);
channel
.read(byteBuffer
, 0, byteBuffer
, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result
, ByteBuffer attachment
) {
System
.out
.println("Bytes read [" + result
+ "]");
}
@Override
public void failed(Throwable exc
, ByteBuffer attachment
) {
System
.out
.println(exc
.getMessage());
}
});
} catch (IOException e
) {
e
.printStackTrace();
}
}
7 Socket和Channel整合
private static void operate11() {
SelectorProvider provider
= SelectorProvider
.provider();
try {
SocketChannel channel
= provider
.openSocketChannel();
SocketAddress address
= new InetSocketAddress(3080);
channel
= channel
.bind(address
);
Set
<SocketOption
<?>> socketOptions
= channel
.supportedOptions();
System
.out
.println(socketOptions
.toString());
channel
.setOption(StandardSocketOptions
.IP_TOS
, 3);
Boolean keepAlive
= channel
.getOption(StandardSocketOptions
.SO_KEEPALIVE
);
} catch (IOException e
) {
e
.printStackTrace();
}
try {
NetworkInterface networkInterface
= NetworkInterface
.getByName("net1");
DatagramChannel dc
= DatagramChannel
.open(StandardProtocolFamily
.INET
);
dc
.setOption(StandardSocketOptions
.SO_REUSEADDR
, true);
dc
.bind(new InetSocketAddress(8080));
dc
.setOption(StandardSocketOptions
.IP_MULTICAST_IF
, networkInterface
);
InetAddress group
= InetAddress
.getByName("180.90.4.12");
MembershipKey key
= dc
.join(group
, networkInterface
);
} catch (IOException e
) {
e
.printStackTrace();
}
}