目录
Java 中 针对文件的操作 ,主要分为两类:
(1) 文件系统的操作 : File
创建文件,删除文件,判定文件是否存在,判定文件类型,重命名……
(2) 文件内容的操作 :流对象 ( InputStream,OutputStream )
读,写 文件
下面我们先来了解 对文件系统的操作。
1. File
1.1 属性
pathSeparator 是 File 类中的一个属性,由于 在不同的系统中,分隔符可能就有些差异,所以,pathSeparator 就是用来 表示分割符的; 在Windows 上,分割符使用 / 和 \ 都可以,但是在Linux或者 Mac 上,就只支持 / 作为分割符。
1.2 构造方法
我们从代码中可以清楚知道,File 中最常用的就是下面三种:
(1)File(String pathname): 通过给定的路径名创建一个新的 File 实例。
(2)File(String parent, String child): 根据指定的父路径名字符串和子路径名字符串创建一个新的 File 实例。
(3)File(File parent, String child): 根据指定的父抽象路径名和子路径名字符串创建一个新的 File 实例。
1.3 方法
下面,我将用代码来实现一些常用的方法。
(1) String s=files.getName() --- 获取 file 对象的父目录 名
String s0=files.getParent() --- 获取 file对象 的父目录 文件路径
String s1=files.getPath() --- 获取 file对象 的文件路径
String s2=files.getAbsolutePath() --- 获取 file对象 的绝对路径
String s3=files.getCanonicalPath() --- 获取 file对象 修饰过的绝对路径
public class Main {
public static void main(String[] args) throws IOException {
// 这里创建的 file对象输入的(相对/绝对)路径 可以 不一定在 你电脑中存在
File files=new File("e:\\淮北\\aaa\\aaa");
// 获取 file 对象的父目录 名
String s=files.getName();
System.out.println(s);
// 获取 file对象 的父目录 文件路径
String s0=files.getParent();
System.out.println(s0);
// 获取 file对象 的文件路径
String s1=files.getPath();
System.out.println(s1);
// 获取 file对象 的绝对路径
String s2=files.getAbsolutePath();
System.out.println(s2);
// 获取 file对象 修饰过的绝对路径 :
// 这里看似结果跟 getAbsolutePath() 得到的一样,其实,这跟你创建file对象 给的路径有关
String s3=files.getCanonicalPath();
System.out.println(s3);
// 当我们给一个 相对路径时,就发现,它会帮你 将 . 给优化掉
// 当你没有写明基准路径的时候
File file=new File(".\\ccc");
System.out.println(file.getAbsolutePath());
System.out.println(file.getCanonicalPath());
// 当写了 基准路径的时候
File file1=new File("e:\\淮北\\aaa\\.\\ccc");
System.out.println(file1.getAbsolutePath());
System.out.println(file1.getCanonicalPath());
}
}
运行结果:
aaa
e:\淮北\aaa
e:\淮北\aaa\aaa
e:\淮北\aaa\aaa
E:\淮北\aaa\aaa
E:\javs-ee\HomeWork\.\ccc
E:\javs-ee\HomeWork\ccc
e:\淮北\aaa\.\ccc
E:\淮北\aaa\ccc
(2) boolean b0=f.exists() --- 判断我们 创建的 file对象 描述的文件是否 真实存在
boolean b1=f.mkdir() --- 当我们 创建的 file对象 描述的文件 不存在的时候,我们可以调用 这个方法进行构建文件 , 不过这个方法 存在一些缺陷,当中间 目录不存在时,就会创建失败
boolean b2=f.mkdirs() --- 相对于 mkdir 来说,mkdirs 就可以创建多层 目录,因为它在必要 条件下就会创建中间目录
boolean b3=f.createNewFile() --- 根据 file对象 创建一个空文件
boolean b4=f.isDirectory() --- 判断 file对象 代表的文件是否是一个目录
boolean b5=f.isFile() --- 判断 file对象 代表的文件是否是一个 普通文件
boolean b6=f.delete() --- 删除 file对象 代表的文件
public class Main{
public static void main03(String[] args) throws IOException {
File f=new File("e:/aaa/test");
// 判断我们 创建的 file对象 描述的文件是否 真实存在
boolean b0=f.exists();
System.out.println(b0);
// 当我们 创建的 file对象 描述的文件 不存在的时候,我们可以调用这个方法进行构建文件
// 不过这个方法 存在一些缺陷,中间目录不存在就会创建失败
boolean b1=f.mkdir();
System.out.println(b1);
// 相对于 mkdir 来说,mkdirs 就可以创建多层 目录,因为它在必要条件下就会创建中间目录
boolean b2=f.mkdirs();
System.out.println(b2);
// 根据 file对象 创建一个空文件,主要用来判断文件是否创建成功
boolean b3=f.createNewFile();
System.out.println(b3);
// 判断 file对象 代表的文件是否是一个目录
boolean b4=f.isDirectory();
System.out.println(b4);
// 判断 file对象 代表的文件是否是一个 普通文件
boolean b5=f.isFile();
System.out.println(b5);
// 删除 file对象 代表的文件
boolean b6=f.delete();
System.out.println(b6);
}
}
(3) String[] s=f.list() --- 获取 当前 f目录 下所有的文件名 , 并以 字符串的形式返回
File[] files=f.listFiles() --- 获取 f对象 下所有的文件 ,并以 File对象 返回
public class Main{
public static void main(String[] args) {
File f=new File("E:/淮北");
// 获取 当前 f目录 下所有的文件名 , 并以 字符串的形式返回
String[] s=f.list();
for(String str : s){
System.out.println(str);
}
// 获取 f对象 下所有的文件 ,并以 File对象 返回
File[] files=f.listFiles();
for(File file : files){
System.out.println(file);
}
// 这个是等 整个线程结束了,才会进行删除操作(无返回值)
//f.deleteOnExit();
}
}
此处运行截图由于 结果太长就不展示了。
介绍 文件系统的操作,接下来就看看 文件内容的操作:
2. 数据流
数据流其实就跟水流差不多:
输入流: InputStream 输出流:OutputStream
输入、输出流均以 二进制 的形式进行传递。
2.1 InputStream(输入流)
(1)方法
read ( ) : 每次读取一个字节长度
read ( byte[ ] b ) : 每次读取 b 的最大长度,并存储在 b 中
read ( byte[ ] b , int offset , int len) : 每次读取 b 的最大长度,从 offset 位置开始放置 len 长度。
close ( ) : 关闭字节流。
(2)FileInputStream(构造方法)
FileInputStream ( File file ) : 利用 file 对象构建 文件输入流
FileInputStream ( String s ) : 利用 文件路径 构建 文件输入流
示例一:
public class Main{
public static void main05(String[] args) throws IOException {
File file=new File("E:\\淮北/test.txt");
try(InputStream inputStream=new FileInputStream(file)) {
while (true) {
byte[] bt = new byte[3];
int a = inputStream.read(bt);
if (a == -1) {
break;
}
for(int i=0;i<a;i++){
System.out.print(bt[i]);
}
}
}
}
}
这里并没有输出 “ 你好 ” 是因为,当我们以输入流读取数据的时候,是以一个一个字节来进行读取的。
示例二:
要想输出字符串类型的数据,只需要将这些 字节 转换成 字符串类型即可。
public class Main{
public static void main(String[] args) throws IOException {
File file=new File("E:\\淮北/test.txt");
try(InputStream inputStream=new FileInputStream(file)) {
while (true) {
byte[] bt = new byte[1024];
int a = inputStream.read(bt);
if (a == -1) {
break;
}
String s=new String(bt,0,a);
System.out.print(s);
}
}
}
}
注意:示例二存在些许问题,如果,你给的byte数组长度如果给得太小,恰好你读取的文档中存在 字符(像'a'这种,占一个字节),那此时,代码如果不做修改,就会出现乱码情况。所以,尽量将 byte 数组长度定大一些。
2.2 OutputStream ( 输出流 )
(1)方法
write ( int a ) : 写入 a 转化为 字符串 的数据
write ( byte[ ] by ) : 将字节数组 中的字节 转化为字符串,再写入文件
write ( byte[ ] by ,int off , int len ) : 将 将字节数组 中 从 off 开始的 长len 的 字节转化为 字符串后写入文件
flush ( ) : 当我们进行 write 之后,并不会立即写入文件,而是先写在一个内存的某个指定区域(缓冲区),当该区域填满了 或者主动调用 flush 方法才会写入文件中。
示例一:覆盖原本字符串
public static Main{
public static void main(String[] args) throws IOException, InterruptedException {
try(OutputStream outputStream=new FileOutputStream("E:\\淮北/test.txt") ){
String s="你好呀,淮北";
outputStream.write(98); // 98 经查表可知是: b
outputStream.write(s.getBytes());
outputStream.flush();
}
}
}
示例二: 示例一中的代码 是 覆盖掉 原文本中的字符串 ,如果你想 在 原字符串的基础上进行增加字符串 ,你只需要 以下操作:
当我们按照上述修改之后,再查看 test.txt,就可以看到所添加的 字符串 在原字符串后面:
示例三:利用 PrintWriter 类代替 OutputStream 进行输出
用 PrintWriter 类来实现 写入的 功能,主要是 该类中提供了我们熟悉的 print 等一系列方法。