目录
Java所有的I/O机制都是基于数据流进行输入输出的,这些数据流表示了字符或者字节数据的流动序列:
-
可以从中读入一个字节序列的对象称为输入流;
-
可以向其写入一个字节序列的对象称为输出流。
I/O体系
输入输出流大体可分为字符流与字节流两大类:
-
字节流:以字节为单位从stream中读取或写入信息;抽象类
InputStream
和OutputStream
构成了其基础; -
字符流:以Unicode字符为导向的stream;通过
Reader
和Writer
及其子类,把流操作转换为字符操作;
输入输出流体系如下图所示:
InputStream
InputStream
是输入字节数据的类,提供了:
-
read:读取数据,三种重载方法(读字节、字节数组、和指定长度字节数组);
-
available:判断是否有可读取字节;
-
skip:忽略流中的字节;
-
close:关闭流;
OutputStream
OutputStream
是输出字节数据的类,提供了:
-
write:写数据;
-
flush:刷新缓冲区(保证数据真正输出);
-
close:关闭流;
输入输出流子类
InputStream
和OutputStream
是抽象类,不能创建对象,只能通过对应的子类来进行:
-
FileInputStream和FileOutputStream:处理磁盘上的文件,只需构造时传入文件名即可。
-
DataInputStream和DataOutputStream:可方便用于处理二进制数据。
-
ZipInputStream和ZipOutputStream:可方便地处理ZIP文档。
字符流操作
Reader
和Writer
及其子类用来处理字符操作。处理字符时就涉及到了字符编码,在StandardCharsets类中定义了所有Java虚拟机都支持的编码类型的静态变量(如StandardCharsets.UTF_8
)。
Reader
Reader用于读取字符,常用子类:
-
FileReader:用于读取文件;
-
InputStreamReader:把字节流(Stream)转换为字符;
-
BufferReader:缓冲读,
readline
可方便地读取一行;
Writer
Writer用于写字符,常用子类:
-
FileWriter:写字符到文件;
-
PrintWriter:便于格式化输出;
文件操作
JDK1.7中引入新的IO操作(java.nio.file包下):
-
Path接口:表示目录(包括文件)序列;
-
Paths:静态类,通过get方法可以方便地组合路径;
-
Files:提供处理文件和目录、以及读写文件的静态方法,并可以创建流对象;
Path
Path用于表示目录和文件,有多种创建方式:
-
FileSystem.getPath(…)
:把字符串转换为路径; -
Paths.get(…)
:可以接收一个或多个字符串,然后用系统默认路径连接符连接起来;
Path中封装了一些常用的路径操作方法:
-
isAbsolute:判断是否为绝对路径;
-
getFileName:返回文件(目录)名,若无(只有根路径)则返回null;
-
p.resolve(q):把q解析为绝对路径;当q是相对路径时,在p的基础上构造出q的绝对路径;
-
p.relative(q):获取q相对p的相对路径(即从q中去掉前缀p);
Files
包含对文件、目录或其他类型文件进行操作的静态方法(获取文件属性、大小,创建、删除,复制、移动等)。
遍历文件
与Path配合使用可以方便地遍历文件:
-
Files.list:获取指定目录下的所有文件(目录),以Stream<Path>的方式返回。
-
Files.walk:获取指定目录及其子目录下的所有文件。
-
Files.newDirectoryStream:返回DirectoryStream<Path>,且可以使用通配符(glob)进行模式匹配。
-
Files.walkFileTree:以目录树的方式操作目录。
枚举目录下的所有文件:
final String File_Dir = "C:\\Users\\guodx\\Desktop\\pic\\java";
try (Stream<Path> files = Files.list(Paths.get(File_Dir))) {
String allFile = files.map(Path::toString).collect(Collectors.joining("\n"));
System.out.println(allFile);
} catch (Exception ex) {
ex.printStackTrace();
}
// Only get the pictures
System.out.println();
try (DirectoryStream<Path> streamFile = Files.newDirectoryStream(Paths.get(File_Dir), "*.{png,jpg}")) {
for (Path p : streamFile) {
System.out.println(p);
}
} catch (Exception ex) {
ex.printStackTrace();
}
删除文件
删除目录(需要先删除目录下的所有文件,再删除目录):
Path dir = Paths.get("C:\\Users\\guodx\\Desktop\\xugd\\test");
try {
Path rootPath = Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
System.out.println(file + ": " + (attrs.isDirectory() ? "dir" : "file"));
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException ex) throws IOException {
if (ex != null)
throw ex;
System.out.println("postDir: " + dir.toString());
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
});
System.out.println(rootPath.toString());
} catch (Exception ex) {
ex.printStackTrace();
}
FileSystem
FileSystem用于处理文件系统,可根据需要加载所需的文件;ZIP文件也可以看作是一个文件系统,通过Files对里面的文件进行处理
final String File_Dir = "C:\\Users\\guodx\\Desktop\\pic\\pic.zip";
try (FileSystem fs = FileSystems.newFileSystem(Paths.get(File_Dir), null)) {
Files.walkFileTree(fs.getPath("/"), new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException{
System.out.println(file);
return FileVisitResult.CONTINUE;
}
});
} catch (Exception ex) {
ex.printStackTrace();
}