在学习文件系统之前,需要了解下Java在I/O上的发展史:在Java7之前,打开和读取文件需要编写特别笨拙的代码,涉及到很多的InputStream、OutputStream等组合起来使用,每次在使用时或许都需要查一下文档才能记得如何打开一个文件;而在Java 7面世后,这些被人诟病的设计得到了巨大的改进,这些新元素被打包放在了java.nio.file之下。这个包对Java对文件的操作提升到了可以与其他编程语言媲美的程度。
本篇文章就主要学习记录下操作文件的两个基本组件:
Path对象代表的是一个文件或目录的路径,它是在不同的操作系统和文件系统之上的抽象。它的目的是,我们不必要注意底层的操作系统,我们的代码不需要重写就能在不同的操作系统上工作 —来自:《OnJava-基础篇》
介绍完Path出现的目的后,我们再来看下如果获取Path。正是java.nio.file.Paths类下重载的static get方法,这个方法的参数可以是接受一个String序列(也就是全路径,系统能够找到的);也可以是一个统一的资源标识符(URI),然后将其转换为Path
下面是对Path以及Files工具类的使用示例
package com.markus.java.file;
import com.markus.java.file.constant.FileConstant;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
/**
* @Author: zhangchenglong06
* @Date: 2023/2/7
* @Description:
*/
public class PathInfo {
static void show(String id, Object p) {
System.out.println(id + p);
}
static void info(Path path) {
show("toString: \n", path);
// 路径是否存在
show("Exists: ", Files.exists(path));
// 是否是常规文件,也就是我们常规意义上的文件,例如.txt .png等,而非目录
show("RegularFile: ", Files.isRegularFile(path));
// 是否是目录
show("Directory: ", Files.isDirectory(path));
// 展示绝对路径
show("Absolute: ", path.toAbsolutePath());
// 展示文件名(最后一级)
show("FileName: ", path.getFileName());
// 展示父路径
show("Parent: ", path.getParent());
// 展示根路径
show("Root: ", path.getRoot());
System.out.println("****************************************************************************************");
}
public static void main(String[] args) {
System.out.println(System.getProperty("os.name"));
info(FileSystems.getDefault().getPath(""));
info(Paths.get("io/src/main/resources", "file", "file.txt"));
Path path = Paths.get(FileConstant.CURRENT_BASE_PATH, "/PathInfo.java");
info(path);
Path ap = path.toAbsolutePath();
info(ap);
info(ap.getParent());
try {
info(ap.toRealPath());
} catch (IOException e) {
System.out.println(e);
}
URI uri = path.toUri();
System.out.println("URI:\n" + uri);
Path pathUri = Paths.get(uri);
System.out.println(Files.exists(pathUri));
// 不要被骗了
File f = ap.toFile();
}
}
/** 输出
* Mac OS X
* toString:
*
* Exists: true
* RegularFile: false
* Directory: true
* Absolute: /Users/zhangchenglong/IdeaProjects/OnJava8-Examples
* FileName:
* Parent: null
* Root: null
* ****************************************************************************************
* toString:
* io/src/main/resources/file/file.txt
* Exists: false
* RegularFile: false
* Directory: false
* Absolute: /Users/zhangchenglong/IdeaProjects/OnJava8-Examples/io/src/main/resources/file/file.txt
* FileName: file.txt
* Parent: io/src/main/resources/file
* Root: null
* ****************************************************************************************
* toString:
* io/src/main/java/com/markus/java/file/PathInfo.java
* Exists: true
* RegularFile: true
* Directory: false
* Absolute: /Users/zhangchenglong/IdeaProjects/OnJava8-Examples/io/src/main/java/com/markus/java/file/PathInfo.java
* FileName: PathInfo.java
* Parent: io/src/main/java/com/markus/java/file
* Root: null
* ****************************************************************************************
* toString:
* /Users/zhangchenglong/IdeaProjects/OnJava8-Examples/io/src/main/java/com/markus/java/file/PathInfo.java
* Exists: true
* RegularFile: true
* Directory: false
* Absolute: /Users/zhangchenglong/IdeaProjects/OnJava8-Examples/io/src/main/java/com/markus/java/file/PathInfo.java
* FileName: PathInfo.java
* Parent: /Users/zhangchenglong/IdeaProjects/OnJava8-Examples/io/src/main/java/com/markus/java/file
* Root: /
* ****************************************************************************************
* toString:
* /Users/zhangchenglong/IdeaProjects/OnJava8-Examples/io/src/main/java/com/markus/java/file
* Exists: true
* RegularFile: false
* Directory: true
* Absolute: /Users/zhangchenglong/IdeaProjects/OnJava8-Examples/io/src/main/java/com/markus/java/file
* FileName: file
* Parent: /Users/zhangchenglong/IdeaProjects/OnJava8-Examples/io/src/main/java/com/markus/java
* Root: /
* ****************************************************************************************
* toString:
* /Users/zhangchenglong/IdeaProjects/OnJava8-Examples/io/src/main/java/com/markus/java/file/PathInfo.java
* Exists: true
* RegularFile: true
* Directory: false
* Absolute: /Users/zhangchenglong/IdeaProjects/OnJava8-Examples/io/src/main/java/com/markus/java/file/PathInfo.java
* FileName: PathInfo.java
* Parent: /Users/zhangchenglong/IdeaProjects/OnJava8-Examples/io/src/main/java/com/markus/java/file
* Root: /
* ****************************************************************************************
* URI:
* file:///Users/zhangchenglong/IdeaProjects/OnJava8-Examples/io/src/main/java/com/markus/java/file/PathInfo.java
* true
*
* Process finished with exit code 0
*/
所谓Path片段即是Path对象路径的各个部分,例如/Users/zhangchenglong/IdeaProjects/OnJava8-Examples/io/src/main/java/com/markus/java中每个//之间的内容都是一个片段
package com.markus.java.file;
import com.markus.java.file.constant.FileConstant;
import java.nio.file.Path;
import java.nio.file.Paths;
/**
* @Author: zhangchenglong06
* @Date: 2023/2/7
* @Description:
*/
public class PartsOfPaths {
public static void main(String[] args) {
System.out.println(System.getProperty("os.name"));
Path p = Paths.get(FileConstant.CURRENT_BASE_PATH, "/PartsOfPaths.java");
for (int i = 0; i < p.getNameCount(); i++) {
System.out.println(p.getName(i));
}
System.out.println("ends with '.java': " + p.endsWith(".java"));
for (Path path : p) {
System.out.print(path + ": ");
System.out.print(p.startsWith(path) + " : ");
System.out.println(p.endsWith(path));
}
System.out.println("Starts with " + p.toAbsolutePath().getRoot() + " " + p.toAbsolutePath().startsWith(p.toAbsolutePath().getRoot()));
}
}
/** 输出
* Mac OS X
* io
* src
* main
* java
* com
* markus
* java
* file
* PartsOfPaths.java
* ends with '.java': false
* io: true : false
* src: false : false
* main: false : false
* java: false : false
* com: false : false
* markus: false : false
* java: false : false
* file: false : false
* PartsOfPaths.java: false : true
* Starts with / true
*/
我们还可以对片段进行添加和删除,需要学习api如下:
package com.markus.java.file;
import com.markus.java.file.constant.FileConstant;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
/**
* @Author: zhangchenglong06
* @Date: 2023/2/8
* @Description: 添加或删除路径片段
* relativize 删除基准路径
* resolve 增加路径
*/
public class AddAndSubtractPaths {
static Path base = Paths.get("..", "..", "..").toAbsolutePath().normalize();
static void show(int id, Path result) {
if (result.isAbsolute()) {
// result 在 路径首部删除base基准路径形成新的路径
System.out.println("(" + id + ")r" + base.relativize(result));
} else {
System.out.println("(" + id + ")" + result);
}
try {
System.out.println("RealPath: " + result.toRealPath());
} catch (IOException e) {
System.out.println(e);
}
}
public static void main(String[] args) {
System.out.println(System.getProperty("os.name"));
System.out.println(base);
Path p = Paths.get(FileConstant.CURRENT_BASE_PATH, "/AddAndSubtractPaths.java").toAbsolutePath();
show(1, p);
Path convoluted = p.getParent().getParent().resolve("strings").resolve("..").resolve(p.getParent().getFileName());
show(2, convoluted);
show(3, convoluted.normalize());
Path p2 = Paths.get("..", "..");
show(4, p2);
// normalize 意为删除了冗余名称元素的路径
// 例如 ./ 直接删除即可
// 例如 strings/../ 直接删除两个元素即可
show(5, p2.normalize());
show(6, p2.toAbsolutePath());
Path p3 = Paths.get(".").toAbsolutePath();
// p3在自身路径后面追加p2组成新的路径
Path p4 = p3.resolve(p2);
show(7, p4);
show(8, p4.normalize());
Path p5 = Paths.get("").toAbsolutePath();
show(9, p5);
show(10, p5.resolveSibling("strings"));
show(11, Paths.get("nonexistent"));
}
}
/** 输出
* Mac OS X
* /Users
* (1)rzhangchenglong/IdeaProjects/OnJava8-Examples/io/src/main/java/com/markus/java/file/AddAndSubtractPaths.java
* RealPath: /Users/zhangchenglong/IdeaProjects/OnJava8-Examples/io/src/main/java/com/markus/java/file/AddAndSubtractPaths.java
* (2)rzhangchenglong/IdeaProjects/OnJava8-Examples/io/src/main/java/com/markus/java/strings/../file
* java.nio.file.NoSuchFileException: /Users/zhangchenglong/IdeaProjects/OnJava8-Examples/io/src/main/java/com/markus/java/strings/../file
* (3)rzhangchenglong/IdeaProjects/OnJava8-Examples/io/src/main/java/com/markus/java/file
* RealPath: /Users/zhangchenglong/IdeaProjects/OnJava8-Examples/io/src/main/java/com/markus/java/file
* (4)../..
* RealPath: /Users/zhangchenglong
* (5)../..
* RealPath: /Users/zhangchenglong
* (6)rzhangchenglong/IdeaProjects/OnJava8-Examples/../..
* RealPath: /Users/zhangchenglong
* (7)rzhangchenglong/IdeaProjects/OnJava8-Examples/./../..
* RealPath: /Users/zhangchenglong
* (8)rzhangchenglong
* RealPath: /Users/zhangchenglong
* (9)rzhangchenglong/IdeaProjects/OnJava8-Examples
* RealPath: /Users/zhangchenglong/IdeaProjects/OnJava8-Examples
* (10)rzhangchenglong/IdeaProjects/strings
* java.nio.file.NoSuchFileException: /Users/zhangchenglong/IdeaProjects/strings
* (11)nonexistent
* java.nio.file.NoSuchFileException: nonexistent
*/
Files工具类包含了操作目录和文件所需要的大部分操作,但其中缺乏删除目录树的工具方法,这里我们做个删除目录树工具的练习
package com.markus.java.file;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
/**
* @Author: zhangchenglong06
* @Date: 2023/2/9
* @Description:
*/
public class RmDir {
public static void rmdir(Path dir) throws IOException {
Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
/**
* 在这个目录下的每个文件上运行
* @param file
* @param attrs
* @return
* @throws IOException
*/
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
/**
* 先进入当前目录下的文件和目录(包括所有的子目录),最后在当前目录上运行
* @param dir
* @param exc
* @return
* @throws IOException
*/
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
/**
* 先在当前目录上运行,然后进入这个目录下的文件和目录
* @param dir
* @param attrs
* @return
* @throws IOException
*/
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
return super.preVisitDirectory(dir, attrs);
}
/**
* 当文件无法访问时调用
* @param file
* @param exc
* @return
* @throws IOException
*/
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
return super.visitFileFailed(file, exc);
}
});
}
}
下面来检验下删除工具的有效性
package com.markus.java.file;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static com.markus.java.file.constant.FileConstant.CURRENT_BASE_PATH;
/**
* @Author: zhangchenglong06
* @Date: 2023/2/9
* @Description:
*/
public class Directories {
static Path test = Paths.get(CURRENT_BASE_PATH, "test");
static String sep = FileSystems.getDefault().getSeparator();
static List<String> parts = Arrays.asList("foo", "bar", "baz", "bag");
static Path makeVariant() {
// 移动指定列表的元素 distance 位
// 例如 [1, 2, 3, 4, 5] 执行Collections.rotate(list.subList(1,4),1)
// 结果 [1, 4, 3, 4, 5]
Collections.rotate(parts, 1);
return Paths.get(CURRENT_BASE_PATH, "test", String.join(sep, parts));
}
static void refreshTestDir() throws IOException {
// 如果文件存在则删除,否则创建目录
if (Files.exists(test)) {
RmDir.rmdir(test);
}
if (!Files.exists(test)) {
Files.createDirectory(test);
}
}
static void populateTestDir() throws IOException {
for (int i = 0; i < parts.size(); i++) {
Path variant = makeVariant();
if (!Files.exists(variant)) {
Files.createDirectories(variant);
Files.copy(Paths.get(CURRENT_BASE_PATH, "Directories.java"), variant.resolve("File" + i + ".txt"));
Files.createTempFile(variant, null, null);
}
}
}
public static void main(String[] args) throws IOException {
// 刷新测试目录
refreshTestDir();
// 在test路径下增加Hello.txt文件路径 并创建此路径文件
Files.createFile(test.resolve("Hello.txt"));
// 创建文件
Path variant = makeVariant();
try {
// 创建一级目录的函数,当创建多级目录时会抛出文件不存在的异常
Files.createDirectory(variant);
} catch (Exception e) {
System.out.println("Nope, that doesn't work." + e);
}
populateTestDir();
Path tempDir = Files.createTempDirectory(test, "DIR_");
Files.createTempFile(tempDir, "pre", ".non");
// newDirectoryStream 只显示指定目录下的子目录或文件
Files.newDirectoryStream(test).forEach(System.out::println);
System.out.println("********************");
// walk 可以浏览指定目录下的所有内容(目录树)
Files.walk(test).forEach(System.out::println);
}
}
/** 控制台
* Nope, that doesn't work.java.nio.file.NoSuchFileException: io/src/main/java/com/markus/java/file/test/bag/foo/bar/baz
* io/src/main/java/com/markus/java/file/test/DIR_260744175083605522
* io/src/main/java/com/markus/java/file/test/foo
* io/src/main/java/com/markus/java/file/test/baz
* io/src/main/java/com/markus/java/file/test/bar
* io/src/main/java/com/markus/java/file/test/bag
* io/src/main/java/com/markus/java/file/test/Hello.txt
* ********************
* io/src/main/java/com/markus/java/file/test
* io/src/main/java/com/markus/java/file/test/DIR_260744175083605522
* io/src/main/java/com/markus/java/file/test/DIR_260744175083605522/pre7111318949801779914.non
* io/src/main/java/com/markus/java/file/test/foo
* io/src/main/java/com/markus/java/file/test/foo/bar
* io/src/main/java/com/markus/java/file/test/foo/bar/baz
* io/src/main/java/com/markus/java/file/test/foo/bar/baz/bag
* io/src/main/java/com/markus/java/file/test/foo/bar/baz/bag/File2.txt
* io/src/main/java/com/markus/java/file/test/foo/bar/baz/bag/2694156263661518806.tmp
* io/src/main/java/com/markus/java/file/test/baz
* io/src/main/java/com/markus/java/file/test/baz/bag
* io/src/main/java/com/markus/java/file/test/baz/bag/foo
* io/src/main/java/com/markus/java/file/test/baz/bag/foo/bar
* io/src/main/java/com/markus/java/file/test/baz/bag/foo/bar/File0.txt
* io/src/main/java/com/markus/java/file/test/baz/bag/foo/bar/6305328343447758907.tmp
* io/src/main/java/com/markus/java/file/test/bar
* io/src/main/java/com/markus/java/file/test/bar/baz
* io/src/main/java/com/markus/java/file/test/bar/baz/bag
* io/src/main/java/com/markus/java/file/test/bar/baz/bag/foo
* io/src/main/java/com/markus/java/file/test/bar/baz/bag/foo/File1.txt
* io/src/main/java/com/markus/java/file/test/bar/baz/bag/foo/5478658539929705751.tmp
* io/src/main/java/com/markus/java/file/test/bag
* io/src/main/java/com/markus/java/file/test/bag/foo
* io/src/main/java/com/markus/java/file/test/bag/foo/bar
* io/src/main/java/com/markus/java/file/test/bag/foo/bar/baz
* io/src/main/java/com/markus/java/file/test/bag/foo/bar/baz/File3.txt
* io/src/main/java/com/markus/java/file/test/bag/foo/bar/baz/5014150493260271159.tmp
* io/src/main/java/com/markus/java/file/test/Hello.txt
*/
FileSystems(文件系统)可以获得两个的API:
下面我们看下代码示例:
package com.markus.java.file;
import com.markus.java.file.constant.FileConstant;
import java.io.IOException;
import java.nio.file.*;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
/**
* @Author: zhangchenglong06
* @Date: 2023/2/10
* @Description:
*/
public class PathWatcher {
static Path test = Paths.get(FileConstant.CURRENT_BASE_PATH, "test");
static void delTxtFiles() {
try {
Files.walk(test)
.filter(
f -> f.toString().endsWith(".txt")
).forEach(
f -> {
System.out.println("deleting " + f);
try {
Files.delete(f);
} catch (IOException e) {
throw new RuntimeException(e);
}
});
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) throws IOException, InterruptedException {
// 刷新目录
Directories.refreshTestDir();
// 创建目录下的文件
Directories.populateTestDir();
Files.createFile(test.resolve("Hello.txt"));
WatchService watcher = FileSystems.getDefault().newWatchService();
// 只能监听到当前目录下操作,子目录下的文件操作不会被监听到
test.register(watcher, ENTRY_DELETE);
Executors.newSingleThreadScheduledExecutor().schedule(PathWatcher::delTxtFiles, 250, TimeUnit.MILLISECONDS);
WatchKey key = watcher.take();
for (WatchEvent<?> evt : key.pollEvents()) {
System.out.println("evt.context(): " + evt.context() +
"\nevt.count(): " + evt.count() +
"\nevt.kind(): " + evt.kind());
System.exit(0);
}
}
}
/** 控制台
* deleting io/src/main/java/com/markus/java/file/test/foo/bar/baz/bag/File3.txt
* deleting io/src/main/java/com/markus/java/file/test/baz/bag/foo/bar/File1.txt
* deleting io/src/main/java/com/markus/java/file/test/bar/baz/bag/foo/File2.txt
* deleting io/src/main/java/com/markus/java/file/test/bag/foo/bar/baz/File0.txt
* deleting io/src/main/java/com/markus/java/file/test/Hello.txt
* evt.context(): Hello.txt
* evt.count(): 1
* evt.kind(): ENTRY_DELETE
*/
上面的代码会有个缺陷,就是它只能监听到当前目录的操作,而无法查找当前目录下所有的子目录的操作行为,如果想监听整个目录树,则必须在整个树的每个子目录上设置一个WatchService
package com.markus.java.file;
import com.markus.java.file.constant.FileConstant;
import java.io.IOException;
import java.nio.file.*;
import java.util.concurrent.Executors;
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
/**
* @Author: zhangchenglong06
* @Date: 2023/2/10
* @Description:
*/
public class TreeWatcher {
static void watchDir(Path dir) {
try {
WatchService watcher = FileSystems.getDefault().newWatchService();
dir.register(watcher, ENTRY_DELETE);
Executors.newSingleThreadScheduledExecutor().submit(() -> {
try {
WatchKey key = watcher.take();
for (WatchEvent<?> evt : key.pollEvents()) {
System.out.println("evt.context(): " + evt.context() +
"\nevt.count(): " + evt.count() +
"\nevt.kind(): " + evt.kind());
System.exit(0);
}
} catch (InterruptedException e) {
return;
}
});
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) throws IOException {
Directories.refreshTestDir();
Directories.populateTestDir();
Files.walk(Paths.get(FileConstant.CURRENT_BASE_PATH, "test"))
.filter(Files::isDirectory)
.forEach(TreeWatcher::watchDir);
PathWatcher.delTxtFiles();
}
}
/** 控制台
* deleting io/src/main/java/com/markus/java/file/test/foo/bar/baz/bag/File3.txt
* deleting io/src/main/java/com/markus/java/file/test/baz/bag/foo/bar/File1.txt
* deleting io/src/main/java/com/markus/java/file/test/bar/baz/bag/foo/File2.txt
* deleting io/src/main/java/com/markus/java/file/test/bag/foo/bar/baz/File0.txt
* evt.context(): File1.txt
* evt.count(): 1
* evt.kind(): ENTRY_DELETE
* evt.context(): File0.txt
* evt.count(): 1
* evt.kind(): ENTRY_DELETE
*/
package com.markus.java.file;
import com.markus.java.file.constant.FileConstant;
import java.io.IOException;
import java.nio.file.*;
/**
* @Author: zhangchenglong06
* @Date: 2023/2/10
* @Description:
*/
public class Find {
public static void main(String[] args) throws IOException {
Path test = Paths.get(FileConstant.CURRENT_BASE_PATH, "test");
Directories.refreshTestDir();
Directories.populateTestDir();
Files.createDirectory(test.resolve("dir.tmp"));
PathMatcher matcher = FileSystems.getDefault()
.getPathMatcher("glob:**/*.{tmp,txt}");
Files.walk(test)
.filter(matcher::matches)
.forEach(System.out::println);
System.out.println("*******************");
PathMatcher matcher2 = FileSystems.getDefault()
.getPathMatcher("glob:*.tmp");
Files.walk(test)
.map(Path::getFileName)
.filter(matcher2::matches)
.forEach(System.out::println);
System.out.println("*******************");
Files.walk(test)
.filter(Files::isRegularFile)
.map(Path::getFileName)
.filter(matcher2::matches)
.forEach(System.out::println);
}
}
/** 控制台
* io/src/main/java/com/markus/java/file/test/foo/bar/baz/bag/File3.txt
* io/src/main/java/com/markus/java/file/test/foo/bar/baz/bag/2767500121528410890.tmp
* io/src/main/java/com/markus/java/file/test/baz/bag/foo/bar/File1.txt
* io/src/main/java/com/markus/java/file/test/baz/bag/foo/bar/5789074899285883862.tmp
* io/src/main/java/com/markus/java/file/test/dir.tmp
* io/src/main/java/com/markus/java/file/test/bar/baz/bag/foo/File2.txt
* io/src/main/java/com/markus/java/file/test/bar/baz/bag/foo/5458649986440731775.tmp
* io/src/main/java/com/markus/java/file/test/bag/foo/bar/baz/File0.txt
* io/src/main/java/com/markus/java/file/test/bag/foo/bar/baz/5568292198534480479.tmp
* *******************
* 2767500121528410890.tmp
* 5789074899285883862.tmp
* dir.tmp
* 5458649986440731775.tmp
* 5568292198534480479.tmp
* *******************
* 2767500121528410890.tmp
* 5789074899285883862.tmp
* 5458649986440731775.tmp
* 5568292198534480479.tmp
*/
在上面,主要学习记录了对路径目录的操作,现在来学习下如果操作文件本身的内容,也就是如何进行读写文件:
package com.markus.java.file;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
/**
* @author: markus
* @date: 2023/2/15 10:39 PM
* @Description:
* @Blog: https://markuszhang.com
* It's my honor to share what I've learned with you!
*/
public class ListOfLines {
public static void main(String[] args) throws IOException {
Files.readAllLines(Paths.get("io/src/main/resources/file_writer.txt"))
.forEach(System.out::println);
}
}
/** 控制台
* Hello,IO
*/
package com.markus.java.file;
import com.markus.java.file.constant.FileConstant;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.Random;
/**
* @author: markus
* @date: 2023/2/16 10:33 PM
* @Description:
* @Blog: https://markuszhang.com
* It's my honor to share what I've learned with you!
*/
public class Writing {
static Random rand = new Random(47);
static final int SIZE = 1000;
public static void main(String[] args) throws IOException {
// 将字节写入一个文件
byte[] bytes = new byte[SIZE];
rand.nextBytes(bytes);
// Files.write(Paths.get(FileConstant.CURRENT_BASE_PATH, "bytes.txt"), bytes, Charset.forName("charset"));
Files.write(Paths.get(FileConstant.CURRENT_BASE_PATH, "bytes.txt"), bytes);
System.out.println("bytes.txt: " + Files.size(Paths.get(FileConstant.CURRENT_BASE_PATH, "bytes.txt")));
// 将实现了Iterable接口的类的对象写入一个文件
List<String> lines = Files.readAllLines(Paths.get("io/src/main/resources/file_writer.txt"));
Files.write(Paths.get("io/src/main/resources/file_writer.txt"), lines);
System.out.println("file_writer.txt: " + Files.size(Paths.get("io/src/main/resources/file_writer.txt")));
}
}
/**
* 控制台
* bytes.txt: 1000
* file_writer.txt: 9
*/
package com.markus.java.file;
import com.markus.java.file.constant.FileConstant;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
/**
* @author: markus
* @date: 2023/2/16 10:47 PM
* @Description:
* @Blog: https://markuszhang.com
* It's my honor to share what I've learned with you!
*/
public class ReadLineStream {
public static void main(String[] args) throws IOException {
Files.lines(Paths.get(FileConstant.CURRENT_BASE_PATH, "PathInfo.java"))
.skip(13)
.findFirst()
.ifPresent(System.out::println);
}
}
/** 控制台
* * @Author: zhangchenglong06
*/
package com.markus.java.file;
import com.markus.java.file.constant.FileConstant;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Stream;
/**
* @author: markus
* @date: 2023/2/16 10:52 PM
* @Description:
* @Blog: https://markuszhang.com
* It's my honor to share what I've learned with you!
*/
public class StreamInAndOut {
public static void main(String[] args) {
try (
Stream<String> input = Files.lines(Paths.get(FileConstant.CURRENT_BASE_PATH, "StreamInAndOut.java"));
PrintWriter writer = new PrintWriter(FileConstant.CURRENT_BASE_PATH + "StreamInAndOut.txt");
) {
input.map(String::toUpperCase)
.forEachOrdered(writer::println);
} catch (IOException e) {
e.printStackTrace();
}
}
}
本文记录了基于Path、Paths、File、Files等抽象对文件、目录相关的操作,摒弃了传统的Java I/O操作类,它使得我们对文件等的操作更加简单,它屏蔽了用户与底层的交互,也使得代码可以跨平台运行。