目录
一、文件和目录
File类: 文件和目录的封装。
File的每个实例都是用来图标是一个文件或目录
实际上表示的是一个抽象路径,如果该路径存在对应的文件或目录则表示他们,否则仅表示该路径。
使用File可以:
1:访问其表示的文件或目录的属性信息(文件名,大小等信息)
2:创建或删除文件,目录
3:访问一个目录中所有的子文件 *
注意:(但是不能访问文件数据)
1、文件
示例:
public static void main(String[] args) throws IOException {
// String : 路径
File f = new File("f:\\data\\a.txt");//原来的文件夹中没有a.txt
// 方式一:
// File f = new File("f:/data/a.txt");
// 方式二:父路径,子路径
// File f = new File("f:/data/","a.txt");
// 方式三:父路径,子路径
File ff = new File("f:/data/");
File f = new File(ff,"a.txt");
// 1. 文件是否存在,存在true
System.out.println(f.exists());// false
// 2. 新建文件
f.createNewFile();
System.out.println(f.exists());// true
// 3. 获得文件的名字
System.out.println(f.getName());// a.txt
// 4. 获得文件所在的路径
System.out.println(f.getPath());// f:\data\a.txt
// 5. 文件是否可以被读取
System.out.println(f.canRead());// true
// 6. 文件是否可以被修改
System.out.println(f.canWrite());// true
// 7. 是否是文件
System.out.println(f.isFile());// true
// 8. long 获得文件的长度 (文件内容的字节数)
System.out.println(f.length());// 0
// 9. 删除文件
f.delete();
System.out.println(f.exists());
}
2、目录
示例:
/**目录:文件夹*/
public class TestFile2 {
public static void main(String[] args) {
// 封装了一个目录
File f = new File("f:/data");
// 1. 文件夹 是否存在
System.out.println(f.exists());// true
// 2. 是否是目录,是 true
System.out.println(f.isDirectory());
// 3. 获得 目录下的 子目录 和 文件的名称数组
String [] strs = f.list();
for(String s : strs) {
System.out.println(s);
}
// 4.获得 目录下的 子目录 和 文件的File数组
File [] fs = f.listFiles();
for(File ff : fs) {
if(ff.isDirectory()) {
System.out.println(ff.getPath());
}else if(ff.isFile()) {
System.out.println(ff.getName());
}
}
// 5. 新建目录
File f1 = new File("f:/data1");
// (1)新建目录 (父路径不存在创建失败)
f1.mkdir();
File f2 = new File("f:/data2/data3");
// (2) 新建目录(父路径不存在 ,也可以创建)
f2.mkdirs();
}
}
二、流
类,提供了一些功能 (方法) ,对文件内容进行读写操作。
1.分类
1)按照流的数据类型:分为字节流和字符流
字节单位
字符单位
2)按照方向:输入和输出
输入: (读) 磁盘 文件 -》 内存
输出:(写) 内存 -》 磁盘文件
String s = "hello" - > a.txt
3)按照功能:节点流和处理流
节点流:又称低级流,是真实连接程序与另一端的“管道”,负责实际搬运数据的流 *读写一定是建立在节点流的基础上进行了。
处理流:又称高级流或过滤流,不能独立存在,必须连接在其他流上,这样当数据 流经当前流是可以对其做某种加工处理,来简化我们对该数据的操作
1.字节流:
字节流: 以字节为单位处理数据信息
在这个图中
FileInputStream 与 FileOutputStream 是节点流,接触最底层数据
BufferInputStream 与 BufferOutputStream 是缓冲流(处理流)
ObjectInputStream 与 ObjectOutputStream 是对象流
1.1 文件流 (低级流)
文件流:FileInputStream和FileOutputStream
文件流是一对低级流,用于读写文件中的数据。
示例:FileInputStream(输入流)
public static void main(String[] args) throws IOException {
// 把 f:/data/a.txt 内容在控制台上显示出来
// 1. 读(输入)
// 引发异常: FileNotFoundException
// FileInputStream fin = new FileInputStream("f:/data/a.txt");
File f = new File("f:/data/a.txt");
FileInputStream fin = new FileInputStream(f);
// 2. 读 GBK 英文1字节, 中文2字节
// 引发: IOException
// 一次读一个 System.out.println((char)fin.read());
// System.out.println((char)fin.read());
// System.out.println(fin.read());// 读到文件末尾返回 -1
// 循环简化
int temp;
while((temp = fin.read()) != -1) {
System.out.print((char)temp);
}
// 3. 关闭流
fin.close();
}
示例:FileOutputStream(输出流)
public static void main(String[] args) throws IOException {
// String s = "hello你好"; -> f:/data/b.txt
// 输出 (写)
// 1. 对象
// true:追加,false:覆盖 (默认false)
FileOutputStream fout = new FileOutputStream("f:/data/b.txt",true);
// 2. 写
// 写一个字节
// fout.write(97);
String s = "hello郭靖";
byte [] b = s.getBytes();
fout.write(b);
// 3. 关
fout.close();
}
1.2 缓冲流(高级流)
BufferedInputStream
BufferedOutputStream
提供缓冲区 字节数组 8192B,提高效率
示例:
public static void main(String[] args) throws IOException {
// 1. 创建流对象
FileInputStream fin = new FileInputStream("f:/data/aoteman.jpg");
// 提供一个 字节数组:读缓冲区 new byte[size]
BufferedInputStream bfin = new BufferedInputStream(fin);
FileOutputStream fout = new FileOutputStream("f:/data/aotemannew.jpg");
// 提供了一个字节数组: 写缓冲区 new byte[size]; 8192
BufferedOutputStream bfout = new BufferedOutputStream(fout);
// 2. 读,写
int temp;
while((temp = bfin.read()) != -1) {
bfout.write(temp);
}
bfout.flush();// 强制刷新缓冲区
// 3. 关流
bfin.close();
bfout.close();
}
1.3 对象流(高级流)
ObjectInputStram:反序列化。 把文件中的 对象还原。
ObjectOutputStream:序列化。 把对象 存到 文件中。
作用:(主要功能就是将对象与字节相互转换)永久性的 保存对象。
示例:(序列化)ObjectOutputStream:对象输出流
String name = "睿睿";
int age = 18;
String gender = "男";
String[] otherInfo = {"吃饭啊","睡觉啊","打豆豆啊"};
Person p = new Person(name,age,gender,otherInfo);
System.out.println(p.toString());
//将Person对象写入文件person.obj中
FileOutputStream fos = new FileOutputStream("person.obj");
ObjectOutputStream sso = new ObjectOutputStream(fos);
sso.writeObject(p);
System.out.println("写出完毕!!!");
//关闭流
sso.close();
示例:(反序列化)ObjectInputStram:对象输入流
//将person.obj文件中的Person读取回来
FileInputStream fis = new FileInputStream("person.obj");
ObjectInputStream ois = new ObjectInputStream(fis);
/*
readObject方法是将读取到的字节按照结构还原为对象
这个过程也称为:对象的反序列化
*/
Object p =ois.readObject();
System.out.println(p);
ois.close();
对象流的写出对象方法:writeObject在实际写操作时可能抛出 异常
异常:NotSerializableException 这是因为写出的对象所属的类没有实现序列化接口:Serializable
在调用下面的writeObject方法时,对象会经过两个流:
对象流:首先对象流会将该对象按照其结构转换为一组字节 (这个过程称为对象的序列化),然后在将这组字节 通过对象流连接(这里是文件流)的流写出。
文件流:将对象流所转换的字节写入文件(写入了磁盘) (将数据写入磁盘的过程称为:数据持久化)
2、字符流
以字符类单位进行读写。
2.1 文件流
节点流: FileReader
FileWriter
示例:FileReader读:
public static void main(String[] args) throws IOException {
// 读
// f:/data/a.txt
// 1.
FileReader fr = new FileReader("f:/data/a.txt");
// 2
// System.out.println((char)fr.read());
// System.out.println((char)fr.read());
// System.out.println((char)fr.read());
// System.out.println(fr.read());// -1 读到文件末尾
// 循环简化
// 读一个字符,
/* int temp;
while((temp = fr.read()) != -1) {
// 展示一个字符在控制台
System.out.print((char)temp);
}*/
// 把读到的字符连接成一个字符串,然后把字符串整体展示在控制台。
/* String s = "";
int temp;
while((temp = fr.read()) != -1) {
s = s + (char)temp;// s -> "ab你” “a“,”ab","ab你“
}
System.out.println(s);*/
// 效率高StringBuilder
StringBuilder sr = new StringBuilder();
int temp;
while((temp = fr.read()) != -1) {
sr.append((char)temp);
}
System.out.println(sr);
// 3.
fr.close();
}
示例:FilerWriter写:
public static void main(String[] args) throws IOException {
// String s = "hello郭靖” -》 f:/data/b.txt
// 1. true追加写入,false覆盖(默认覆盖)
FileWriter fw = new FileWriter("f:/data/b.txt",true);
// 2
String s = "hello郭靖";
fw.write(s);
// 3.
fw.close();
}
2.2转换流
java.io.InputStreamReader
java.io.OutputStreamWrite
它们是字符流的一对实现流,在实际 开发中我们几乎不会直接操作这两个流,但是在流连接中它们是非常重要的一环。
实际开发中我们发现其他的高级字符流有一个特点:只能连接其他字符流,这就意味着字符流 是不能连接在字节流上的,但是常用的低级流都是字节流,而转换流是唯一可以连接在字节流 上的字符流,它本身又是字符流,因此可以通过它衔接字节流和字符流,起到“转换器”的作用。
示例:OutputStreamWrite
//向osw.txt文件中写入字符串
FileOutputStream fos = new FileOutputStream("osw.txt",true);
//创建转换流
OutputStreamWriter osw = new OutputStreamWriter(fos,"utf-8");
osw.write("我喜欢你");
osw.close();
示例:InputStreamReader
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("osw.txt");
InputStreamReader isr = new InputStreamReader(fis,"utf-8");
int a = 0;
while ((a = isr.read())!=-1){
System.out.println((char)a);
}
isr.close();
}
int read()
字符流的该方法是读取一个字符,实际读取几个字节取决于字符集以及该字符编码。
eg:读取的字符是UTF-8编码吗的一个中国字,那么实际读取3个字节,但是到了java
内部统一转换为char(unicode编码)2字节保存。
2.3 缓冲字符流
java.io.BufferedWrite
java.io.BufferedReader
缓冲字符流是利用块读写文本数据提高读写字符的效率, 并且缓冲字符流可以按照行读写字符串
作用:提供了缓冲区 ,和 更高效的 读取方式 readLine();
示例:BufferedReader
FileReader fr = new FileReader("f:/data/Demo1.java");
// 缓冲流
BufferedReader bfr = new BufferedReader(fr);
// 2
// 一次读一行
// System.out.println(bfr.readLine());
// System.out.println(bfr.readLine());
// System.out.println(bfr.readLine());
// System.out.println(bfr.readLine());
// 读取所有的内容
String s ;
while((s = bfr.readLine()) != null ) {
System.out.println(s);
}
// 3.关闭流
bfr.close();
2.4 文本输出流
PrintWriter : 打印输入字符流
示例:
PrintWriter pw = new PrintWriter("pw.txt","utf-8");
pw.println("让我在看你一眼");
pw.println("从南到北");
System.out.println("写出完毕");
pw.close();
java.io.PrintWirter
具有自动刷新的缓冲字符输出流,内部总是连接BufferedWrite 作为其缓冲加速作用。
PW支持直接对文件操作的构造器:
PrintWriter(String fileName)
PrintWriter(File file)
以上两个构造器都支持在传入一个参数用来指定字符集的名字,这样可以按照 该字符集写入文本数据。