Java NIO文件操作

文件系统文件操作

代码:github CommonTest

文件路径拼接

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());
                }
            });
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值