文件
概念
文件就是保存数据的地方,万物皆文件。
文件流
文件在程序中以流的形式来操作的
流: 数据在数据源(文件)和程序(内存)之间经历的路径
输入流: 数据从数据源(文件)到程序(内存)的路径
输出流:数据从程序(内存)到数据源(文件)的路径
常用文件操作
创建文件
//创建文件对象相关构造器和方法
new File(String pathname)//根据路径构建一个File对象
new File(File parent,String child)//根据父目录文件+子路径构建
new File(String parent,String child) //根据父目录+子路径构建
createNewFile() //创建新文件
/**
* 3.new File(String parent,String child)
* 要求两个字符串要符合文件名字的类型不然汇报创建失败
* */
获取文件相关信息
getName() | 获取文件名称 |
getAbsolutePath() | 获取文件的绝对路径 |
getParent() | 返回父目录文件路径 |
exists() | 文件是否存在 |
length() | 文件的大小(字符返回) |
isFile() | 是不是文件 |
isDirectory() | 是不是文件夹 |
---|---|
delete() | 删除文件 |
目录操作
在java编程中,目录也是一种文件处理方式。
- 先判断是否存在
- 在进行添加或者删除操作
目录创建 | |
---|---|
mkdir() | 创建一级目录 |
mkdirs() | 创建多级目录 |
IO原理以及流的分类
IO原理
- I/O是Input /Output的缩写 ,IO技术是非常实用的技术,用于数据的处理。如写文件,读文件
- java程序中,对于数据的输入输出操作以”流“的方式进行
- java.io包下提供了各种”流“的类和接口,用于获取不同类型的数据,并通过方法输入输出数据。
流的分类
- 按操作数据单位不同分为:字节流(8 bit)二进制文件,字符流(按字符)
字节流 | 用于处理二进制文件:视频,声音,word文件, |
---|---|
字符流 | 文本文件 |
- 按数据流的流向不同分为:输入流,输出流。
- 按流的角色的不同分为:节点流,处理流/包装流
抽象基类 | 字节流 | 字符流 |
---|---|---|
输入流 | InputStream | Reader |
输出流 | OutputStream | Writer |
节点流和处理流(重点)
节点流可以从一个特定的数据源读取数据,如FileReader,FileWriter
处理流也叫包装流,是连接已存在的流之上,微程序提供更强大的读写功能如,BUfferedReader,BufferedWriter
两个区别
节点流是一种底层流,直接跟数据源相接
处理流报装节点流,既可以下厨不同节点流的实现差异,也可以更加方便
的方法来完成输入输出
处理流对节点进行包装,使用了修饰器设计模式,不会直接与数据源相连**(模拟修饰器设计模式)**
修饰器设计模式模拟
//使用java中继承和动态绑定的机制,将一些处理数据源的节点流方式是成一个基类,或者抽象类,然后用一个类重写构造器,传入该类,就可以把很多类包装到一起
abstract class reader_ {
public abstract void readFile();
public abstract void readString();
}
class bufferReader { //包装好的可使用的
private reader_ reader;
public bufferReader(reader_ reader) {
this.reader = reader;
}
}
class Stringreader extends reader_{
@Override
public void readFile() {
}
@Override
public void readString() {
}
}
class Filereader extends reader_ {
@Override
public void readFile() {
}
@Override
public void readString() {
}
}
**字符处理流-**BUfferedReader,BufferedWriter
处理文本文件有很大优势。(字符)
**字节处理流-**BufferedinputStream和BufferedOutputStream
处理二进制文件【声音,视频,doc,pdf】(字节)
实列
@Test
public void bufferreader() {
String filepath = "D:\\ajava.txt";
try {
BufferedReader bufferedReader = new BufferedReader(new FileReader(filepath));
String line;
//默认读取的文件是以UTF-8这种编码方式进行读取的
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void bufferWriter() {
String filepath = "D:\\a.txt";
try {
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filepath));
String str = "你好韩顺平";
bufferedWriter.write(str);
bufferedWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
对象处理流-
ObjectInputStream和ObjectOutputStream
处理数据不是保存值,而是将数据的值和数据类型都进行保存到文件中,这样处理方便文件恢复,同时可以做到基本数据或者对象数据的序列化和反序列化
序列化和反序列化
-
序列化就是在保存数据时,保存数据的值和类型
-
反序列化就是在回复数据的时候,可以恢复数据的值和数据类型
-
需要让某个对象支持序列化机制,则必须让其类时可序列化的,为了让某个类时可序列化的。该类必须实现如下两个接口之一:
Serializable//这是一个标记接口,没有方法
Externalizable//该接口有方法需要实现,因此我们一般实现上面的
ObjectInputStream和ObjectOutputStream 提供了对基本类型或者对象类型的序列化和反序列化的方法
示例
@Test
public void ObjectoutputStream() {
String filepath = "D:\\ajava.dat";
try {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filepath, true));
//序列化数据到 D:\ajava.dat
oos.writeInt(100); //int -> integer
oos.writeBoolean(true);
oos.writeChar('a');
oos.writeUTF("韩顺平, 教育");
oos.writeObject(new Dog("小孩", 15));
Dog dog3 = new Dog("小组", 13);
oos.writeObject(dog3);
oos.close();
System.out.println("数据序列化完毕");
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void ObjectinputStream() {
String filepath = "D:\\ajava.dat";
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filepath));
System.out.println(ois.readInt());
System.out.println(ois.readBoolean());
System.out.println(ois.readChar());
System.out.println(ois.readUTF());
Object o = ois.readObject();
System.out.println("运行类型:" + o.getClass());
System.out.println(o);
ois.close();
//反序列化:读取的顺序要一致,否则会有异常
ois.close();
System.out.println("数据反序列化完毕");
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
class Dog implements Serializable {
//提高序列化 的兼容性,就是他不会因为你的类添加了一个属性,就是一个陌生的类
private static final long serialVersionUID = 1L;
private String name;
int age;
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
}
对象处理流的细节
- 读写顺序一致
- 要求实现序列化或反序列化对象,需要实现Serializable
- 序列化的类中建议添加SerializableUID,为了提高版本的兼容性
- 序列化对象时,默认将里边所有属性进行序列化,但除了static或transient修饰的成员
- 序列化对象时,要求里面属性的类型也需要实现序列化接口
- 序列化具备继承性,也就是如果某类已经实现了序列化,则它的所有子类也已经默认实现了序列化
标准输入输出流
类型 | 默认设备 | |
---|---|---|
System.in标准输入 | InputStream | 键盘 |
System.out标准输出 | PrintStream | 显示器 |
@Test
public void system() {
//System.in
//public final static InputStream in = null; 编译类型时InputStream
//运行类型时BufferedInputStream
System.out.println(System.in.getClass());
//System.out
// public final static PrintStream out = null;; 编译类型时PrintStream
//运行类型时 PrintStream
System.out.println(System.out.getClass());
}
转换流
就是将字节流转换成字符流。
作用: 字节读取的时候默认的编码格式是UTF-8,如果为了防止出现文件乱码等现象,可以使用 转换流进行读写操作,该流中可以规定文件读取的编码格式并转换成对应的字符流。
InputStreamReader 和 OutputStreamWriter
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dpujY11t-1648566722951)(E:\qq文件\image\java进阶\inputStreamReader.jpg)] |
---|
- InputStreamReader:Reader的子类,可以将InputStream(字节流)包装成Reader(字符流)
- OutputStreamWriter:Writer的子类,实现将OutputStream(字节流)包装成Writer(字符流)
- 当处理纯文本数据时,如果使用字符流效率更高,并且可以有效解决中文,所以建议将字节流转换成字符流
使用操作:
//1.把FileInputStream 转成InputStreamReader
InputStreamReader gbk = new InputStreamReader(new FileInputStream(ser), "UTF-8");//2. 指定编码
//3.把InputStreamReader 传入 BufferedReader :将转换流转换成字符流
BufferedReader bufferedReader = new BufferedReader(gbk);
打印流
打印流只有输出流 没有输入流
PrintStream和 PrintWriter(字节流)
/**
* 演示PrintStream_ (字节打印流)
*/
@Test
public void PrintStream_() throws FileNotFoundException {
//System.out;底层就是PrintStream,所以可以直接赋值
PrintStream out = System.out;
//在默认情况下,PrintStream 输出的位置就是标准输出:显示器
out.println("你好");
//我们可以修改打印输出的位置/设备
System.setOut(new PrintStream("e:\\a.txt"));//设置输出的路径
System.out.println("你好");//该句话就不会打印在显示器,而是编程上边设置的输出路径
}
/**
* 演示PrintWriter_ (字节打印流)
*/
@Test
public void PrintWriter_ () throws IOException {
PrintWriter printWriter = new PrintWriter(new FileWriter("D:\\a.txt"));
printWriter.write("你好");
printWriter.checkError();//如果不关闭就不会把数据输出
}
字节流
InputStream(字节)
常用子类
1.FilelnputStream:文件输入流
2.BufferedInputStream:缓冲字节输入流
3.ObjectlnputStream:对象字节输入流
FilelnputStream的使用
-
创建
FileInputstream fileInputStream = null;
-
打开文件,读取(流和文件进行绑定)
//从该输入流读取一个字节的数据。如果没有输入可用,此方法将阻止。/如何返回-1,表示读取完毕 //read():一个字节一个字节的读取 while ((readData = fileInputstream.read()) != -1) { System.out.println((char)readData);//转成char显示 } //read(byte[] b):按照byte最大的数组进行读取,不在一个一个 //fileInputstream.read(buff)的返回值是实际读取的字节数,如果读完返回-1 int readLength byte[] buff = new byte[127] while ((readLength = fileInputstream.read(buff)) != -1) { System.out.println(new String(buff,0,readLength));//转成char显示 }
-
释放
fileInputstream.close();
OutputStream
FileOutputStream的使用和FilelnputStream使用方式类似,不同的是一个输出一个输入
字节输出流
- 单字节输出 fileoutputstream.write()
- char数组输出 fileoutputstream.write(byte[] str )
FileOutputStream在进行输出到文件中时,如果该文件不存在就会创建该文件。
字符流
Reader(字符) Writer(字符)
字符流的基类。
FileReader和FileWriter
FileWriter常用方法 | |
---|---|
1) new FileWriter(File/String) | 覆盖模式,相当于流的指针在首端 |
new FileWriter(File/String,true): | 追加模式,相当于流的指针在尾端 |
write(int) | 写入单个字符 |
write(char) | 写入指定数组 |
write(char0.off,len) | 写入指定数组的指定部分 |
write (string) | 写入整个字符串 |
write(string,off,len) | 写入字符串的指定部分 |
注意
FileWriter使用后,必须关闭或者刷新flush,否则写入不到指定文件
Properties类
多用于配置文件,格式: 键=值,默认是String类型
常用方法
load :加载配置文件的键值对到Properties对象
list:将数据显示到指定设备
getProperties(key):根据键获取到值
setProperties(key,value):设置键值到Properties对象
store:将Properties中的键值对存储到配置文件中,保存配置信息,如果含有中文,就存储Unicode码
实列
@Test
public void Properties_() throws IOException {
String filepath = "src\\Mysql.properties";
//以下是传统方法,对配置文件的处理方式
/* BufferedReader bufferedReader = new BufferedReader(new FileReader(filepath));
String str;
//为空则读取完成
while ((str = bufferedReader.readLine()) != null) {
System.out.println(str);
}
bufferedReader.close();*/
Properties properties = new Properties();
//加载
properties.load(new FileReader(filepath));
//配置显示设备
properties.list(System.out);
//如果没有k-v就是添加
//如果有就是修改
properties.setProperty("user","zzx");
//保存修改内容到配置文件
properties.store(new FileWriter(filepath,false),null);
properties.clear();
//如果要求指定的得到某个对应的数据,就可以用Properties
}