文件系统文件操作
文件路径拼接
URI, URL
URI:
格式:{scheme}: //{user}@{host}:{port}{path}?{query}#{fragment}
demo:http://yunzhong@yunzhong.com:8080/yunzhong/eat?when=afternoon#meat
输出:
Authority = yunzhong@yunzhong.com:8080
Fragment = meat
Host = yunzhong.com
Path = /yunzhong/eat
Port = 8080
Query = when=afternoon
Scheme = http
Scheme-specific part = //yunzhong@yunzhong.com:8080/yunzhong/eat?when=afternoon
User Info = yunzhong
URI is absolute: true
URI is opaque: false
java demo: URITester.java
URL
是URI的一个子集,一般用于网络上。
java demo:URLTester.java
Path路径拼接
URL转成Path:
Path path = Paths.get(resource.toURI());
URI可以直接作为参数传递给Path。
Path还可以拼接多级路径,不需要用户处理"/",""等问题。
@Test
public void testAppend() {
System.out.println(Paths.get("D:/temp", "hello/world", "files").toString());
System.out.println(Paths.get("D:/temp", "hello\\world", "files").toString());
System.out.println(Paths.get("D:/temp", "hello", "world", "files").toString());
Path path = Paths.get("D:/temp");
Path resolve = path.resolve("hello").resolve("world").resolve("files");
System.out.println(resolve.toString());
}
文件夹操作
FileSystemUtil包含了所有的文件操作demo。
- 文件夹下的遍历操作
一种方式是使用Files.walkFileTree接口。这个接口遍历目录下所有的文件和文件夹。接口的参数需要传入FileVisitor,提供了文件、文件夹的操作接口。
一种方式是使用Files.newDirectoryStream。这个接口只打印第一层的文件和文件夹。另外,因为是打开了一个stream,需要在finally中close stream。比较好的是用户可以自己定义过滤条件,支持“*”等通配符。
最后一种方式,是采用File.listFiles列举所有的第一层文件。 - 创建文件夹操作
文件夹的创建分为两个接口:Files.createDirectory和Files.createDirectories。
Files.createDirectory只能创建一级目录。比如说已经存在了“/home/yunzhong”,可以创建“/home/yunzhong/temp”,但是不可以创建“/home/yunzhong/temp/firstDir”。
Files.createDirectories则是会将路径上不存在的文件夹都创建出来,相当于是Files.createDirectory的更便利的封装。 - 删除文件夹
删除的文件夹,必须没有子文件或者子文件夹,所以不管怎么操作都需要先删除文件夹的内容,再删除文件夹。
可以采用Files.walkFileTree进行删除。也可以通过递归的方式删除文件夹。
代码:
public static void printFileTree(String rootPath) throws IOException {
Path path = Paths.get(rootPath);
if (Files.notExists(path)) {
log.warn("there is no path {}", rootPath);
return;
}
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path path, BasicFileAttributes arg1) throws IOException {
System.out.println(path.toString());
return FileVisitResult.CONTINUE;
}
});
System.out.println("split--------------------------------------");
Files.walkFileTree(path, new FileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path path, BasicFileAttributes arg1) throws IOException {
System.out.println(path.toString());
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path arg0, IOException arg1) throws IOException {
System.out.println("post visit directory:" + arg0.toString());
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult preVisitDirectory(Path arg0, BasicFileAttributes arg1) throws IOException {
System.out.println("pre visit directory:" + arg0.toString());
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path arg0, IOException arg1) throws IOException {
return FileVisitResult.CONTINUE;
}
});
}
/**
* print file in folder
*
* @param rootPath
* @throws IOException
*/
public static void printFileDirectory(String rootPath) throws IOException {
Path path = Paths.get(rootPath);
if (Files.notExists(path)) {
log.warn("there is no path {}", rootPath);
return;
}
File[] listFiles = path.toFile().listFiles();
for (File file : listFiles) {
System.out.println("file :" + file.getAbsolutePath());
}
}
/**
* @param rootPath
* @param glob
* @throws IOException
*/
public static void printDirectory(String rootPath, String glob) throws IOException {
Path path = Paths.get(rootPath);
if (Files.notExists(path)) {
log.warn("there is no path {}", rootPath);
return;
}
DirectoryStream<Path> newDirectoryStream = null;
try {
if (glob != null) {
newDirectoryStream = Files.newDirectoryStream(path, glob);
} else {
newDirectoryStream = Files.newDirectoryStream(path);
}
for (Path directory : newDirectoryStream) {
System.out.println("path:" + directory.toString());
}
} finally {
if (newDirectoryStream != null) {
newDirectoryStream.close();
}
}
}
/**
* @param rootPath
* @param attr
* @throws Exception
*/
public static void createDirectory(String rootPath, String attr) throws Exception {
Path createDirectory = null;
if (StringUtils.isEmpty(attr)) {
Path path = Paths.get(rootPath);
createDirectory = Files.createDirectory(path);
} else {
Set<PosixFilePermission> attrSet = PosixFilePermissions.fromString(attr);
FileAttribute<Set<PosixFilePermission>> fileAttribute = PosixFilePermissions.asFileAttribute(attrSet);
Path path = Paths.get(rootPath);
createDirectory = Files.createDirectory(path, fileAttribute);
}
if (!Files.exists(createDirectory)) {
throw new Exception();
}
}
/**
* @param rootPath
* @param attr
* @throws Exception
*/
public static void createDirectories(String rootPath, String attr) throws Exception {
Path createDirectory = null;
if (StringUtils.isEmpty(attr)) {
Path path = Paths.get(rootPath);
createDirectory = Files.createDirectories(path);
} else {
Set<PosixFilePermission> attrSet = PosixFilePermissions.fromString(attr);
FileAttribute<Set<PosixFilePermission>> fileAttribute = PosixFilePermissions.asFileAttribute(attrSet);
Path path = Paths.get(rootPath);
createDirectory = Files.createDirectories(path, fileAttribute);
}
if (!Files.exists(createDirectory)) {
throw new Exception();
}
}
/**
* @param rootPath
* @throws IOException
*/
public static void removeDirectory(String rootPath) throws IOException {
Path directory = Paths.get(rootPath);
EnumSet<FileVisitOption> opts = EnumSet.of(FileVisitOption.FOLLOW_LINKS);
Files.walkFileTree(directory, opts, Integer.MAX_VALUE, new FileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.deleteIfExists(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
throw exc;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
if (exc != null) {
log.error("Failed to delete file of path {}", dir.toString());
throw exc;
}
Files.deleteIfExists(dir);
return FileVisitResult.CONTINUE;
}
});
}
public static void removeDirectoryRecursive(String rootPath) throws IOException {
Path directory = Paths.get(rootPath);
if (!Files.exists(directory)) {
return;
}
deleteDirectory(directory);
}
private static void deleteDirectory(Path directory) throws IOException {
if (!Files.isDirectory(directory)) {
Files.delete(directory);
return;
}
File[] files = directory.toFile().listFiles();
for (File file : files) {
deleteDirectory(file.toPath());
}
Files.delete(directory);
}
文件操作
实现类:FileSystemUtil
小文件操作
一次性读取到内存。
public static void printSmallFile(String filePath) throws IOException {
Path path = Paths.get(filePath);
System.out.println(Files.readString(path));
}
public static void printSmallFileByLine(String filePath) throws IOException {
Path path = Paths.get(filePath);
List<String> readAllLines = Files.readAllLines(path);
for (String line : readAllLines) {
System.out.println(line);
}
}
异步文件操作
AsynchronousFileChannel进行文件的读写。实现起来很复杂,一般不要用了。
public static void printAsync(String filePath) throws IOException, InterruptedException, ExecutionException {
Path file = Paths.get(filePath);
try (AsynchronousFileChannel channel = AsynchronousFileChannel.open(file)) {
// 从jdk7开始,支持数字中下划线,增强数字的可读性
// ByteBuffer buffer = ByteBuffer.allocate(4_000);
ByteBuffer buffer = ByteBuffer.allocate(4);
int position = 0;
while (true) {
Future<Integer> result = channel.read(buffer, position);
while (!result.isDone()) {
}
if (result.get() <= 0) {
System.out.println(" ");
System.out.println("all data done.");
break;
}
buffer.flip();
while (buffer.hasRemaining()) {
System.out.print((char) buffer.get());
}
position += 4;
buffer.clear();
}
System.out.println(" ");
}
}
public static void printAsyncHandler(String filePath) throws IOException {
Path file = Paths.get(filePath);
ByteBuffer buffer = ByteBuffer.allocate(4_000_000);
try (AsynchronousFileChannel channel = AsynchronousFileChannel.open(file)) {
int position = 0;
channel.read(buffer, position, buffer, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result, ByteBuffer attachment) {
attachment.flip();
while (attachment.hasRemaining()) {
System.out.print((char) attachment.get());
}
attachment.clear();
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
System.out.println("error" + exc.getLocalizedMessage());
}
});
}
}