注意: 我们接下来要讲的文件操作,是对硬盘进行操作,Mysql中的操作也是主要操作硬盘。
对于文件的管理,我们可以通过自己的电脑发现,我们文件是按层级结构进行存储的,类似于数据结构中的树形结构。这样,一种专门用来存放管理信息的特殊文件诞生了,也就是我们平时的文件夹(folder),专业术语称为目录(directory)的概念。
所以我们如何找到我们的文件?
对于文件的查找方式我们有绝对路径和相对路径。
如:D:\qq\Bin\TXSSO
如:./src/刷题/day8.java
其中 .在相对路径中,表示当前目录。…表示当前目录的上级目录。
一般来说: 文件系统中的任何一个文件,对应的路径是唯一的,但是在Linux上可能存在一个文件有两个不同的路径能找到它,在Windows上不存在。
在普通文件中,根据存储的内容不同,我们分为文本文件和二进制文件。
Java中提供一个File类对文件(包括目录)进行抽象描述,在内存中创建一个对应的对象,通过操作对象来间接操作硬盘中的文件。
使用过程:
第一种对文件进行操作:
File file = new File("./1.txt");
System.out.println(file.getParent());
//得到绝对路径
System.out.println(file.getAbsolutePath());
System.out.println(file.getName());
System.out.println(file.getPath());
//文件创建
File file2 = new File("./hello_world.txt");
System.out.println(file2.exists());
System.out.println(file2.isDirectory());
System.out.println(file2.isFile());
file2.createNewFile();//不存时在项目下创建
System.out.println(file2.isFile());
System.out.println(file2.exists());
System.out.println(file2.isDirectory());
//删除文件
file2.delete();
第二种对目录进行操作:
使用如下:
//创建目录
File file5 = new File("test-dir");
file5.mkdir();//创建一级目录
//创建多级目录
File file3 = new File("test-dir/aaa/bbb");
file.mkdirs();
//再创建一个对象,获取多级目录的内容
File file4 = new File("test-dir");
String[] results = file4.list();//返回String数组
System.out.println(Arrays.toString(results));//打印数组
File[] results2 = file4.listFiles();//返回File数组
System.out.println(Arrays.toString(results2));
//重命名,新建一个file对象,将旧的重命名给新的,就能重命名。
File dest = new File("./test-dir2");
file4.renameTo(dest);
本文上面对于文件介绍中提到根据文件内容不同分为文本文件和二进制文件,所以我们在对内容进行操作时也提供了两组类。对文本文件我们使用字符流,对应Reader、Writer。对二进制文件 我们使用字节流,对应InputStream、OutPutStream。
二者都是抽象类,我们通过new对应的子类来对文件内容进行操作。
InputStream的用法:
//第一种写法,可以避免走不到close,但是不美观
// InputStream inputStream =null;
// try {
// inputStream = new FileInputStream("d:/1.txt");
//
// }finally {
// inputStream.close();
// }
//更优雅的写法,自动进行资源释放
try (InputStream inputStream = new FileInputStream("d:/1.txt")){
//读文件
//read返回的是字节1,但是此处用int接收
// int b = inputStream.read();//无参的read,一次读一个字节
while (true){
int b = inputStream.read();
if (b==-1){
break;//结束
}
System.out.printf("%x\n",b);//16进制输出
}
}
执行结果: 内容是hello,一个字符对应一个字节,我们读出来的是字符对应的ASCII编码
内容是你好,一个汉字对应三个字节,我们输出的就是6个编码,这个一般对应的是utf-8字符集。
OutputStream的用法:
package IO;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* @author zq
* outputStream的用法,写文件
*/
public class IODemo3 {
public static void main(String[] args) {
try (OutputStream outputStream = new FileOutputStream("d:/1.txt")){
//一个字节的写入
outputStream.write(97);
outputStream.write(98);
outputStream.write(99);
outputStream.flush();//保证缓冲区数据刷新到设备中
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
执行结果: 我们写入时会将原有内容删除。
注意: read和write方法还有另外两种用法。我们可以使用byte[]来写入和读取多个字节。read会尽可能将数组填满,write会把数组内容都写入文件。**write(byte[]b, int off,int len)**方法可以将 b 这个字符数组中从 off 开始的数据写入 os 中,一共写 len 个。read(byte[] b,int off, int len) 方法最多读取 len - off 字节的数据到 b 中,放在从 off 开始,返回实际读到的数量;-1 代表以及读完了
如图:
最多读取数组长度的内容到数组中,方法返回实际读取的数量。
这两个的用法与字节流使用方法类似,接下来展示具体用法。
Reader的使用:
try(Reader reader = new FileReader("D:\\java\\bit\\java_bit\\src\\2.txt")) {
while (true){
int c = reader.read();
if (c==-1){
break;
}
char ch = (char)c;
System.out.print(ch);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Writer的使用:
writer.write(97);
writer.write(98);//这个写会把之前的内容清空写。
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}