java.io包
pathname文件地址
一个File类的对象,可以表示计算机硬盘上一个具体的文件或目录(文件夹)
通过File类的对象 来获取文件/目录的相关信息(例如创建时间,是否可写...),但是不能读取文件中的内容
输入输出是相对于程序的
输入是读 Input
输出是写 Output
java中把用于对文件输入和输出的类称为流
有一些类用于输入数据的,有一些类用于输出数据
有一些类以字节为单位读取的读取数据的,有一些类是以字符为单位读取数据的
字节流
读取时以字节为单位 可以读取任意的文件.mp3.xlsx
字节输入流:从程序中读 InputStream
FileInputStream 文件输入字节流
BufferedInputStream 缓冲字节输入流
DataInputStream
字节输出流:从程序中往外写 OutputStream
FileOutputStream 文件输出字节流
BufferedOutputStream 缓冲字节输出流
DataOutputStream
File
File类:一个File类的对象可以表示一个具体的文件或目录
构造方法
File f1 = new File("E:/test");
表示E盘中的文件夹test
File f2 = new File("E:/test.txt");
表示E盘中的txt文件test
常用方法
file.canRead();
返回文件是否可读
file.canWrite();
返回文件是否可写
f.exists();
返回文件或目录是否存在
file.getAbsoluteFile();
获取文件绝对地址
file.isHidden();
返回文件/目录是否是隐藏模式
file.isDirectory();
判断是否是目录
file.isFile();
判断是否是文件
file.lastModified();
返回文件最后修改的时间,long类型
new Date(file.lastModified());
把long类型的时间转为Date对象
file.getName();
获取文件名
file.length();
文件字节长度
file.createNewFile();
创建新的文件,需抛去异常IOException
异常处理
if(!f.exists()){
try {
f.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
抛去IOException
if(!f.exists()){
System.out.println(f.createNewFile());//创建文件,成功返回true
}
多级目录(文件夹)构造方法
File file = new File("D:/download/a/b");
file.mkdir();
创建单级文件夹
file.mkdirs();
创建多级文件夹
file.delete();
删除文件或文件夹,删除文件夹时,文件夹必须是空的
file.listFiles();
File[] files = file.listFiles();
获取当前给定目录的子级文件或文件夹
输出文件夹内容
for (File f1:files) {
System.out.println(f1);
}
节点流
直接封装的是文件,数据(最基础读数据的流)
FileInputStream与FileOutputStream
输入:从硬盘上把文件读入到程序
构造方法
File file = new File("E:/test.txt");
FileInputStream inputStream = new FileInputStream(file);
输入管道
FileInputStream inputStream = new FileInputStream("E:/test.txt");
输出管道
FileOutputStream outputStream = new FileOutputStream("E:/test.txt");
常用方法
inputStream.read();
读取文件中的内容,返回内容对应的int类型的值,结束返回-1
读取文件全部内容(每次读取一个字节)
int b = 0;
while ((b = inputStream.read())!= -1){//每次读一个字节
System.out.println(b);
}
读取文件全部内容(每次读取byte数组长度个字节内容,写入size个字节)
byte[] bytes = new byte[10];
int size = 0;//每次实际往数组中装入的元素
while ((size = inputStream.read(bytes))!= -1){
//read(bytes):一次读byte数组长度个字节,文件内容读取完毕返回-1
outputStream.write(bytes,0,size);
}
inputStream.close();
outputStream.close();
inputStream.close();outputStream.close();
关闭通道
注意:file.delete();通道关闭后才能删除文件
处理流/包装流
封装的是其他节点流对象,在节点流基础上,可以提供缓冲功能
缓冲区大小默认为8192个字节,可以自定义缓冲区大小
BufferedInputStream与BufferedOutputStream
构造方法
缓冲字节输入流
FileInputStream fileInputStream = new FileInputStream("D:/test.txt");
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
缓冲字节输出流
FileOutputStream fileOutputStream = new FileOutputStream("E:/test.txt");
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
DataInputStream与DataOutputStream
构造方法
DataInputStream dataInputStream = new DataInputStream(fileInputStream);
DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream);
优点
String message = "你干嘛";
FileOutputStream fileOutputStream = new FileOutputStream("E:/test.txt");
fileOutputStream.write(message.getBytes());
需要我们自己将字符串转为byte数组输出,比较麻烦
DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream);
dataOutputStream.writeUTF(message);
直接将字符串写出(内部进行转换)
FileInputStream fileInputStream = new FileInputStream("E:/test.txt");
DataInputStream dataInputStream = new DataInputStream(fileInputStream);
String s = dataInputStream.readUTF();
可以直接将读取到的数据转为String
字符流
只能读文本文件,会将读到的字节结合编码表转换为一个字符编码
Reader
FileReader
字符输入流
BufferedReader
缓冲字符输入流
InputStreamReader转换流
将字节转换为字符的桥
Writer
FileWriter
字符输出流
BufferedWriter
缓冲字符输出流
OutputStreamWriter转换流
将字符转换为字节
构造方法
FileReader reader = new FileReader("D:/test.txt");
FileWriter writer = new FileWriter("E:/test.txt",true);
,true 保留原来的内容,在原内容的基础上向后追加(续写)
不加在写入数据时会覆盖原来的数据
构造时需抛去IOException异常
BufferedReader bufferedReader = new BufferedReader(reader);
BufferedWriter bufferedWriter = new BufferedWriter(writer);
将原文件的内容写入新文件
public class Main {
public static void main(String[] args) throws IOException {
FileReader reader = new FileReader("D:/test.txt");
FileWriter writer = new FileWriter("E:/test.txt",true);
BufferedReader bufferedReader = new BufferedReader(reader);
BufferedWriter bufferedWriter = new BufferedWriter(writer);
String line = null;
while ((line = bufferedReader.readLine())!=null){
bufferedWriter.write(line);
bufferedWriter.newLine();
}
bufferedReader.close();
bufferedWriter.flush();
bufferedWriter.close();
}
}
bufferedWriter.newLine();
写入文件时,插入换行符
对象输入输出流
ObjectOutputStream
把Java中的对象输出到文件中
ObjectInputStream
从文件中把对象输入到程序中
为什么要把对象输出到文件中
new Student(); 数据存储在对象中,对象是在内存中存储,一旦程序运行结束,对象就会被销毁
有时需要将对象的信息长久保存,就需要将对象输入到文件中,长久保持
例:系统升级,关闭服务器时将对象保存起来,升级完毕,重新再把数据还原回来
把对象输出到文件的过程也称为对象的序列化
把对象从文件输入到程序的过程称为对象的反序列化
反序列时会生成一个新的对象,所以反序列化也是创建对象的一种方式
对象输出
public static void main(String[] args) throws IOException{
String s = new String("abc");
Date date = new Date();
//需抛去IOException
FileOutputStream fileOutputStream = new FileOutputStream("E:/obj.txt");
ObjectOutputStream objectoutputStream = new ObjectOutputStream(fileOutputStream);
objectoutputStream.writeObject(s);
objectoutputStream.writeObject(date);
objectoutputStream.flush();
objectoutputStream.close();
}
对象输入 对象反序列化
public static void main(String[] args) throws IOException, ClassNotFoundException {
FileInputStream fileInputStream = new FileInputStream("E:/obj.txt");//需抛去IOException
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
String s = (String) objectInputStream.readObject();//需抛去ClassNotFoundException
Date date = (Date) objectInputStream.readObject();
System.out.println(s);
System.out.println(date);
objectInputStream.close();
}
如果一个类需要被序列化到文件中,那么这个类就需要实现Serializable接口,实现后,会自动为该类生成一个序列化编号
public class Student implements Serializable{
private static final long serialVersionUID = 4958303379818630271L;
}
编号是类的唯一标识
但是自动生成的编号在类信息改变后,会重新为类生成一个编号
可以在类中显示的生成的一个编号,这样类信息修改后,也不会改变
在IDEA中设置步骤
File->Settings->Inspections->Java->Serialization issues->Serializable class without 'serialVersionUID'