文件
目录
一、File对象
注意:
- Windows平台使用
作为路径分隔符,在Java字符串中需要用
\
表示一个 - Linux平台使用
/
作为路径分隔符 - 若传入的是相对路径,可以用
.
表示当前目录,..
表示上级目录
1、创建对象
File f = new File("/home/up/IdeaProjects/test_project");
2、对象方法
getPath() // 返回构造方法传入的路径
getAbsolutePath() // 返回绝对路径
getCanonicalPath() // 它和绝对路径类似,但是返回的是规范路径
isFile() // 判断该File对象是否是一个已存在的文件
isDirectory() // 判断该File对象是否是一个已存在的目录
boolean canRead() // 是否可读
boolean canWrite() // 是否可写
boolean canExecute() // 是否可执行
long length() // 文件字节大小
createNewFile() // 创建一个新文件
delete() // 删除该文件
createTempFile() // 创建一个临时文件
deleteOnExit() // 在JVM退出时自动删除该文件
mkdir() 或者 mkdirs() // 创建目录或多级目录
3、遍历文件
list() // 列出目录下的所有文件和子目录
listFiles() // 列出当前目录下的所有文件
二、Path类
1、对象方法
Path p1 = Paths.get(".", "project", "study"); // 构造一个Path对象
// toAbsolutePath 转为绝对路径
p1.toAbsolutePath();
// normalize 转为规范路径
p1.normalize();
// toFile 转为File对象
p1.toFile();
三、读写文件
字节流 | 字符流 | |
---|---|---|
输入流 | InputStream | Reader |
输出流 | OutputStream | Writer |
-
InputStream和OutputStream读写数据的单位是一个字节
-
Reader和Writer读写数据的单位是一个字符
1、InputStream输入流——读文件
(1)常用方法
read()
// 读取一个字节,以整数形式返回;读到末尾则返回-1
read(byte[] b, int off, int len)
// 从文件中最多读取 len个字节的数据,从b[off]处开始存入b
skip(long n)
// 跳过输入流的n个字节
(2)案例
// try(resource) 会自动关闭文件
public void readFile() throws IOException {
try (InputStream input = new FileInputStream("src/readme.txt")) {
int n;
while ((n = input.read()) != -1) {
System.out.println(n);
}
} // 编译器在此自动为我们写入finally并调用close()
}
2、OutputStream输出流——写文件
(1)常用方法
write(int b)
// 向输出流中写入
write(byte[] b, int off, int len)
// 将数组从 off索引开始的len个字节写入输出流
flush()
// 将输出流中缓冲的数据全部写到目标位置
(2)案例
public void writeFile() throws IOException {
try (OutputStream out = new FileOutputStream("b.txt")){
out.write("hello".getBytes());
}catch (Exception e){
System.out.println(e);
} // 编译器在此自动为我们写入finally并调用close()
}
3、Reader——读文件
Reader
是一个字符流,即以char
为单位读取
- 在创建文件对象时,要指定字符编码,否则会读出乱码
public void readFile() throws IOException {
// 创建一个FileReader对象:
try(Reader reader = new FileReader("b.txt", StandardCharsets.UTF_8)){
while (true){
int res = reader.read();
System.out.println((char) res);
if (res == -1){
break;
}
}
}catch (Exception e){
System.out.println(e);
}
}
4、Writer——写文件
- 在创建文件对象时,要指定字符编码,否则会读出乱码
void write(int c) // 写入一个字符(0~65535)
void write(char[] c) // 写入字符数组的所有字符
void write(String s) // 写入String表示的所有字符
try(Writer writer = new FileWriter("b.txt", StandardCharsets.UTF_8)){
writer.write("好的");
}catch (Exception e){
System.out.println(e);
}
四、Zip文件
1、读取zip文件
创建一个ZipInputStream
,通常是传入一个FileInputStream
作为数据源,然后,循环调用getNextEntry()
,直到返回null
,表示zip流结束
try (ZipInputStream zip = new ZipInputStream(new FileInputStream("a.zip"))) {
ZipEntry entry = null;
while ((entry = zip.getNextEntry()) != null) {
String name = entry.getName();
if (!entry.isDirectory()) {
int n;
while ((n = zip.read()) != -1) {
...
}
}
}
}
2、写入zip文件
创建一个ZipOutputStream
,通常是包装一个FileOutputStream
,然后,每写入一个文件前,先调用putNextEntry()
,然后用write()
写入byte[]
数据,写入完毕后调用closeEntry()
结束这个文件的打包
try (ZipOutputStream zip = new ZipOutputStream(new FileOutputStream("a.zip"))) {
File[] files = ...
for (File file : files) {
zip.putNextEntry(new ZipEntry(file.getName()));
zip.write(getFileDataAsBytes(file));
zip.closeEntry();
}
}
五、序列化与反序列化
1、序列化
序列化是指把一个Java对象变成二进制内容,本质上就是一个byte[]
数组。序列化后可以把byte[]
保存到文件中,或者把byte[]
通过网络传输到远程,这样,就相当于把Java对象存储到文件或者通过网络传输出去了。
ObjectOutputStream
可以把一个Java对象写入一个字节流
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
try (ObjectOutputStream output = new ObjectOutputStream(buffer)) {
// 写入int
output.writeInt(12345);
// 写入String
output.writeUTF("Hello");
// 写入Object
output.writeObject(Double.valueOf(123.456));
}
System.out.println(Arrays.toString(buffer.toByteArray()));
2、反序列化
ObjectInputStream
负责从一个字节流读取Java对象
try (ObjectInputStream input = new ObjectInputStream(...)) {
int n = input.readInt();
String s = input.readUTF();
Double d = (Double) input.readObject();
}