1. I/O流
I/O就是Input/Output即输入和输出;
概念:内存与存储设备之间传输数据的通道
1.1 流的分类
-
按方向
- 输入流:将<存储设备>中的内容读入到<内存>中
- 输出流:将<内存>的内容写入到<存储设备>中
-
按单位
- 字节流:以字节为单位,可以读写所有数据
- 字符流:以字符为单位,只能读写文本数据
-
按功能
- 节点流:具有实际传输数据的读写功能
- 过滤流:在节点流的基础上增强功能
2. 字节流
- 字节流的父类(抽象类)
-
InputStream:字节输入流(读)
- 子类:FileInputStream
-
OutputStream:字节输出流(写)
- 子类 :FileOutputStream
-
2.1 FileInputStream类(读取)
read(int c)
单字节读取(读取并返回读取的字节个数,当读取完最后一个字节时返回-1)
read(byte[] b,int off,int len)
读取byte数组中从a位置到b位置的值
@Test
public void test2() throws IOException {
InputStream inputStream = new FileInputStream("D://abc.txt");
int a;
//单字节读取
//while((a=inputStream.read())!=-1){
//System.out.print((char) a);
//}
//byte数组读取
byte [] bytes =new byte[1024];
while ((a=inputStream.read(bytes))!=-1){
System.out.println(new String(bytes));
}
//关闭流
inputStream.close();
}
2.2 FileOutputStream(写入)
write(int c)
单个字节写入
write(byte[] b,int off,int len)
将byte数组a位置到b位置的值写入
@Test
public void test3() throws IOException{
//如果不想覆盖,多次保存追加的话,可以在构造方法第二个参数写true
OutputStream outputStream=new FileOutputStream("D://123.txt",true);
//单字节写入
outputStream.write('a');
outputStream.write(98);
//多字节写入
String hello="hello world";
outputStream.write(hello.getBytes());
outputStream.close();
}
2.3 复制图片
@Test
public void test4() throws IOException{
//创建字节输入和输出流
InputStream inputStream=new FileInputStream("D://qsface.gif");
OutputStream outputStream=new FileOutputStream("D://a.gif");
byte [] bytes =new byte[1024];
//利用输出流将图片的字节读取到byte数组中再利用输出流从数组写入到a.gif的文件中
while ((inputStream.read(bytes))!=-1){
outputStream.write(bytes);
}
inputStream.close();
outputStream.close();
}
3. Buffered字节缓冲流
- 缓冲流:BufferedInputStream / BufferedOutputStream
- 提高I/O效率,减少访问磁盘的次数
- 数据存储在缓冲区中,flush是将缓冲区中的的内容写入到文件中,也可以直接close
3.1 BufferedInputStream
@Test
public void test5() throws IOException{
//创建输入流
InputStream inputStream=new FileInputStream("D://abc.txt");
//创建缓冲输入流,并把输入流对象当参数
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
byte [] bytes =new byte[1024];
int a;
//直接调用缓冲输入流的read方法
while ((a=bufferedInputStream.read(bytes))!=-1){
System.out.println(new String(bytes,0,a));
}
bufferedInputStream.close();
}
3.2 BufferedOutputStream
@Test
public void test6() throws IOException{
//创建字节输出流
OutputStream outputStream=new FileOutputStream("D://123.txt");
//创建缓冲输出流
BufferedOutputStream bufferedOutputStream=new BufferedOutputStream(outputStream);
for (int i = 0; i <10 ; i++) {
bufferedOutputStream.write("Helloworld".getBytes());
}
bufferedOutputStream.flush();
bufferedOutputStream.close();
}
4. Object对象流(序列化)
- 对象流:ObjectInputStream / ObjectInputStream
-
增强了缓冲区的功能
-
增强了读写8种基本数据类型和字符串功能
-
增强了读写对象的功能
-
readObject() 从流中读取对象
-
writeObject() 向流中写入对象
-
-
(使用流传输对象的过程称为序列化,反序列化)
- 注意事项
- 要进行序列化和反序列化的类必须实现Serializable接口
- 类中的对象属性也必须实现Serializable接口
- 添加序列化版本ID(serialVersionUID)常量,保证序列化和反序列化的类是同一个类
- 使用transient修饰属性,这个属性是无法被序列化的
- 静态属性不能被序列化
- 使用集合实现一次序列化多个对象
4.1 ObjectOutputStream 对象输出流
创建了一个Strudent实体类
实现了Serializable接口,这个接口本身没有任何方法只是为了标注这个类可序列化
(注意想要实现序列化必须实现Serializable接口,否则会出现异常)
import java.io.Serializable;
public class Students implements Serializable {
String name;
int age;
public Students() {
}
public Students(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Students{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
使用ObjectOutputStream将对象序列化到文件中
writeObject()
参数类型为Object
@Test
public void test7() throws IOException{
//创建输出流
OutputStream outputStream=new FileOutputStream("D://stu.bin");
//创建对象输出流,并将输出流对象当参数
ObjectOutput objectOutput=new ObjectOutputStream(outputStream);
//创建student对象
Students students=new Students("张三",6);
//使用对象输出流的 writeObject()方法
objectOutput.writeObject(students);
objectOutput.close();
}
4.2 ObjectInputStream 对象输入流
将序列化的原始数据反序列化恢复为对象
readObject()
@Test
public void test8() throws IOException, ClassNotFoundException {
//创建输入流
InputStream inputStream=new FileInputStream("D://stu.bin");
//创建对象输入流
ObjectInput objectInput=new ObjectInputStream(inputStream);
//实例化Students
Students students =new Students();
//调用readObject()方法
students = (Students) objectInput.readObject();
System.out.println(students.toString());
objectInput.close();
}
5. 字符流
-
字符流的父类(抽象类)
-
Reader:字符输入流
- public void read(){} 读单个字符
- public void read(char [] c){} 读多个字符
- public void read(char [] c ,int off, int len){} 读多个字符的某一段
-
Writer:字符输出流
- public void write(int n){} 写一个字符
- public void write(String str){} 写一个字符串
- public void write(char [] c){} 写多个字符
- public void flush() 刷新缓冲区
-
5.1 FileReader 字符输入流
单字符读取
@Test
public void test9() throws IOException{
//创建字符输入流
Reader reader=new FileReader("D://abc.txt");
int a;
while ((a=reader.read())!=-1) {
System.out.println((char) a);
}
}
多字符读取
@Test
public void test10() throws IOException {
Reader reader =new FileReader("D://abc.txt");
char [] chars= new char[1024];
while (reader.read(chars)!=-1){
System.out.println(chars);
};
}
5.2 FileWrite 字符输出流
单字符写入
@Test
public void test11() throws IOException{
//创建字符输出流
Writer writer = new FileWriter("D://321.txt");
writer.write("你好");
//刷新缓冲
writer.flush();
writer.close();
}
多字符写入
@Test
public void test12() throws IOException{
Writer writer =new FileWriter("D://321.txt",true);
char [] char1 = {'张','三'};
char [] char2 = {'李','四'};
writer.write(char1);
writer.write(char2);
writer.flush();
writer.close();
}
复制字符文件
@Test
public void test13() throws IOException{
Reader reader = new FileReader("D://321.txt");
Writer writer = new FileWriter("D://4321.txt");
char [] chars= new char[1024];
while (reader.read(chars)!=-1){
writer.write(chars);
writer.flush();
}
reader.close();
writer.close();
}
6. 字符缓冲流
缓冲流:BufferedReader / BufferedWriter
- 高效读写
- 支持输入换行符
- 可一次读一行,写一行
6.1 BufferedReader 字符缓冲输入流
readline()
输出一行,返回值为String
@Test
public void test14() throws IOException{
//创建字符输入流流
Reader reader = new FileReader("D://123.txt");
//创建字符缓冲输入流
BufferedReader bufferedReader=new BufferedReader(reader);
String s ;
while ((s=bufferedReader.readLine())!=null){
System.out.println(s);
}
bufferedReader.close();
}
6.2 BufferedWriter 字符缓冲输出流
newLine()
换行符
@Test
public void test15() throws IOException{
//创建字符输出流
Writer writer = new FileWriter("D://1234.txt");
//创建字符缓冲输出流
BufferedWriter bufferedWriter =new BufferedWriter(writer);
bufferedWriter.write("你好世界");
bufferedWriter.newLine();
bufferedWriter.write("HelloWorld");
bufferedWriter.flush();
bufferedWriter.close();
}
7. 转换流
InputStreamReader 字节输入流(转换)字符输入流
OutputStreamWriter 字节输出流 (转换)字符输出流
7.1 InputStreamReader
getEncoding()
获取文本的编码格式
@Test
public void test16() throws IOException{
//创建字节输入流
InputStream inputStream = new FileInputStream("D://1234.txt");
//创建转换流,并加上编码格式
InputStreamReader inputStreamReader =new InputStreamReader(inputStream,"utf-8");
int data;
while((data=inputStreamReader.read())!=-1){
System.out.println((char) data);
}
//可以获取这个文本的编码格式
System.out.println(inputStreamReader.getEncoding());
inputStreamReader.close();
}
7.2 OutputStreamWriter
@Test
public void test17() throws IOException{
//创建字节流
OutputStream outputStream =new FileOutputStream("D://12345.txt");
//创建转换流
OutputStreamWriter outputStreamWriter=new OutputStreamWriter(outputStream,"utf-8");
outputStreamWriter.write("你好世界");
outputStreamWriter.flush();
outputStreamWriter.close();
}