字节流
字节流的父类(抽象类):
java.lang.Object ---> java.io.InputStream
java.lang.Object ---> java.io.OutputStream
-
InputStream:字节输入流
此抽象类是表示字节输入流的所有类的超类。
部分方法:
public int read(){}
public int read(byte[] b){}
public int read(byte[] b, int off, int len){}
-
OutputStream:字节输入流
此抽象类是表示输出字节流的所有类的超类。
部分方法:
public int write(){}
public int write(byte[] b){}
public int write(byte[] b, int off, int len){}
字节流抽象类的子类:文件字节流
java.io.InputStream ---> java.io.FileInputStream
java.io.OutputStream ---> java.io.FileOutputStream
-
FileInputStream: 从文件系统中的某个文件中获得输入字节
- public int read() // 从此输入流中读取一个数据字节。如果达到文件的尾部,则返回-1。
- public int read(byte[] b) //从流中读取多个字节,将读到内容存入b数组,返回实际读到的字节数;如果达到文件的尾部,则返回-1。
- public int read(byte[] b, int off, int len) //从此输入流中将最多 len个字节的数据读入一个 byte 数组中。
-
FileOutputStream:
- public void write(int b) // 将指定字节写入此文件输出流。
- public void write(byte[] b) //一次写多个字节,将b数组中所有字节,写入输出流。
- public void write(byte[] b, int off, int len) // 将指定 byte 数组中从偏移量 off 开始的 len个字节写入此文件输出流。
FileInputStream案例代码:
package com.wlw.io;
import java.io.FileInputStream;
import java.util.Arrays;
/**
* 演示FileInputStream的使用
* 文件字节输入流
*/
public class FileInputStreamDemo {
public static void main(String[] args) throws Exception{
//1.创建文件字节输入流,通过路径名来指定文件(也可以是File file)
FileInputStream fis = new FileInputStream("D:\\Program Files\\IDEAworkspace\\aaa.txt");
//2.读取文件
//2.1 用read()一个字节一个字节读
/*
int data = 0;//read()返回的是数据的ASCII码,如果达到文件的尾部,则返回-1。
while ((data = fis.read())!= -1){//读完数据
System.out.print((char) data); //转成字符输出
}
*/
//2.2用read(byte[] b)读取,一次读取多个字节
// 将读到内容存入b数组,返回实际读到的字节数;如果达到文件的尾部,则返回-1。
byte[] buf = new byte[1024];//用来接收数据
int count = 0; //存放读到的字节数
while ((count = fis.read(buf)) != -1){//读完数据
System.out.println(new String(buf,0,count));
}
//3.关闭流
fis.close();
System.out.println();
System.out.println("执行完毕");
}
}
FileOutputStream案例代码:
package com.wlw.io;
import java.io.FileOutputStream;
/**
* 演示FileOutputStream的使用
* 文件字节输出流
*/
public class FileOutputStreamDemo {
public static void main(String[] args) throws Exception{
//1.创建文件字节输出流,可以通过路径来指定(没有的话会自动创建),(也可以是File file)
FileOutputStream fos = new FileOutputStream("D:\\Program Files\\IDEAworkspace\\bbb.txt");
//上面的创建方式在写入时,会把原文件覆盖,下面的创建方式是添加
//FileOutputStream fos = new FileOutputStream("D:\\Program Files\\IDEAworkspace\\bbb.txt",true);
//2.写入
//2.1 write(int b) // 将指定字节写入此文件输出流
/*
fos.write(97);//a
fos.write('b');
fos.write('c');
*/
//2.2write(byte[] b) //一次写多个字节,将b数组中所有字节,写入输出流。
String str = "HelloWorld";
fos.write(str.getBytes());
//3.关闭流
fos.close();
}
}
文件字节流复制文件:
package com.wlw.io;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
* 使用文件字节流实现文件的复制
*/
public class FileCopyDemo {
public static void main(String[] args) throws Exception{
//1.创建流
//1.1创建文件输入流
FileInputStream fis = new FileInputStream("D:\\Program Files\\IDEAworkspace\\复制文件.png");
//1.2创建文件输出流
FileOutputStream fos = new FileOutputStream("D:\\Program Files\\IDEAworkspace\\复制文件1.png");
//2.复制(一边读,一边写)
byte[] bytes = new byte[1024];//存储数据
int count = 0;//存放读取的字节数
while ((count = fis.read(bytes)) != -1){//读完数据
fos.write(bytes,0,count);//不多写,读多少 写多少
}
//关闭流
fis.close();
fos.close();
System.out.println("复制完毕");
}
}
过滤流的子类:字节缓冲流
java.io.InputStream --> java.io.FilterInputStream---> java.io.BufferedInputStream
java.io.OutputStream --> java.io.FilterOutputStream---> java.io.BufferedOutputStream
缓冲流: BufferedInputStream/ BufferedOutputStream
-
提高I0效率,减少访问磁盘的次数;
-
数据存储在缓冲区中,flush是将缓存区的内容写入文件中,也可以直接close。
-
BufferedInputStream:为另一个输入流添加一些功能,为其他流增强功能,需要传入其他流
- 构造方法:BufferedInputStream (InputStream in)
-
BufferedOutputStream:该类实现缓冲的输出流。通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必针对每次字节写入调用底层系统。
- 构造方法:BufferedPutputStream (OutputStream out)
- void flush() //刷新此缓冲的输出流。
BufferedInputStream案例代码:
package com.wlw.io;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
/**
* 使用字节缓冲流读取
* BufferedInputStream
* 可以提高读取的效率
*/
public class BufferedInputStreamDemo {
public static void main(String[] args) throws Exception{
//1.创建BufferInputStream,需要往里面传入一个节点流
FileInputStream fis = new FileInputStream("D:\\Program Files\\IDEAworkspace\\aaa.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
//2.读取,字节缓冲流里面有个8k的缓冲区,先把数据读到缓冲区里
/*
int data = 0;
while ((data = bis.read()) != -1){//读完会返回-1
System.out.print((char)data);
}
*/
//自己写一个缓冲区
byte[] buf = new byte[1024];
int count = 0;
while ((count = bis.read(buf)) != -1){
System.out.println(new String(buf,0,count));
}
//3.关闭流
bis.close();//它会帮我们关闭fis
}
}
BufferedOutputStream案例代码:
package com.wlw.io;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
/**
* 使用字节缓冲流写入文件
* BufferedOutputStream
*/
public class BufferOutputStreamDemo {
public static void main(String[] args) throws Exception{
//1.创建字节缓冲流,需要往里面传入一个节点流
FileOutputStream fos = new FileOutputStream("D:\\Program Files\\IDEAworkspace\\bufferOut.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
//2.写入文件
for (int i = 0; i < 10; i++) {
bos.write("HelloWorld\r\n".getBytes());//写入到8k的缓冲区中,还没有写入到文件中
bos.flush();//将数据写入到存储设备(硬盘,我们指定的文件中)
}
//3.关闭流
bos.close();//此方法内部也会调用flush()方法
}
}
字节流抽象类的子类:对象流
java.io.InputStream ---> java.io.ObjectInputStream
java.io.OutputStream ---> java.io.ObjectOutputStream
//对象流,对 对象 进行操作
对象流: Object0utputStream/ ObjectInputStream
-
增强了缓冲区功能
-
增强了读写8种基本数据类型和字符串功能
-
增强了读写对象的功能:
- read0bject() //从流中读取一个对象
- write0bject (Object obj) //向流中写入一个对象
-
使用流传输对象的过程称为序列化、反序列化:
-
序列化:把内存中的对象写入到文件中(流中),write0bject (Object obj) ,
同时要求我们的对象(序列化类)要实现Serializable接口(一个标记作用,说明这个类可以序 列化)
-
反序列化:从文件(流)中读取对象,read0bject()
-
- ObjectInputStream:
- 构造方法:ObjectInputStream (InputStream in)
- Object0utputStream:
- 构造方法:ObjectOutputStream (OutputStream out)
- void flush() //刷新该流的缓冲。
代码:
package com.wlw.io.demo02;
import java.io.Serializable;
//序列化类
public class Student implements Serializable {
private String name;
private int age;
public Student() {}
public Student(String name, int age) {
this.name = name;
this.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;}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
package com.wlw.io.demo02;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
/**
* 使用ObjectOutputStream实现对象的序列化(写入)
* 要求:我们的对象(序列化类)要实现Serializable接口(一个标记作用,说明这个类可以序列化)
*/
public class ObjectOutputStreamDemo {
public static void main(String[] args) throws Exception{
//1.创建对象流,需要传入一个节点流
FileOutputStream fos = new FileOutputStream("D:\\Program Files\\IDEAworkspace\\Student.bin");
ObjectOutputStream oos = new ObjectOutputStream(fos);
//2.序列化(写入文件)
Student zhangsan = new Student("张三",20);
oos.writeObject(zhangsan);
//3.关闭流
oos.close();//会调用flush() 方法
System.out.println("序列化完毕");
}
}
package com.wlw.io.demo02;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
/**
* 使用ObjectInputStream反序列化(读取重构成对象)
*/
public class ObjectInputStreamDemo {
public static void main(String[] args) throws Exception{
//1.创建对象流,需要传入一个节点流
FileInputStream fis = new FileInputStream("D:\\Program Files\\IDEAworkspace\\Student.bin");
ObjectInputStream ois = new ObjectInputStream(fis);
//2.读取(反序列化)
Object object = ois.readObject(); //读完不能重复读,否则会抛异常java.io.EOFException
Student student = (Student) object;
//3.关闭流
ois.close();//内部也会关闭 fis
System.out.println("反序列化完毕");
System.out.println(student.toString());
}
}
序列化与反序列化的注意事项:
- 序列化类必须要实现Serializable接口。
- 序列化类中对象属性要求实现Serializable接口。
- 序列化版本号ID ,serialVersionUID, 保证序列化的类和反序列化的类是同一个类。
- 使用transient (瞬间的)修饰属性,这个属性不能序列化。
- 静态属性不能被序列化。
- 序列化多个对象,可以借助集合实现。麻烦点的可以一个一个序列化,再一个一个反序列化。
代码:
package com.wlw.io.demo02;
import com.sun.org.apache.xalan.internal.res.XSLTErrorResources_it;
import java.io.Serializable;
//序列化类
public class Student implements Serializable {
/**
* serivalVersionUID:序列化版本号ID
*/
private static final long serivalVersionUID = 10L;
private String name;
//private Address address; //对象属性 也要实现Serializable接口。
private transient int age;
private static String country = "中国";
public Student() {}
public Student(String name, int age) {
this.name = name;
this.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;}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
package com.wlw.io.demo02;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
/**
* 使用ObjectOutputStream实现对象的序列化(写入)
* 要求:我们的对象(序列化类)要实现Serializable接口(一个标记作用,说明这个类可以序列化)
*/
public class ObjectOutputStreamDemo {
public static void main(String[] args) throws Exception{
//1.创建对象流,需要传入一个节点流
FileOutputStream fos = new FileOutputStream("D:\\Program Files\\IDEAworkspace\\Student.bin");
ObjectOutputStream oos = new ObjectOutputStream(fos);
//2.序列化(写入文件)
Student zhangsan = new Student("张三",20);
Student lisi = new Student("李四",20);
ArrayList<Student> arrayList = new ArrayList<>();
arrayList.add(zhangsan);
arrayList.add(lisi);
oos.writeObject(arrayList);
//oos.writeObject(zhangsan);
//oos.writeObject(lisi);
//3.关闭流
oos.close();//会调用flush() 方法
System.out.println("序列化完毕");
}
}
package com.wlw.io.demo02;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.ArrayList;
/**
* 使用ObjectInputStream反序列化(读取重构成对象)
*/
public class ObjectInputStreamDemo {
public static void main(String[] args) throws Exception{
//1.创建对象流,需要传入一个节点流
FileInputStream fis = new FileInputStream("D:\\Program Files\\IDEAworkspace\\Student.bin");
ObjectInputStream ois = new ObjectInputStream(fis);
//2.读取(反序列化)
//Student student = (Student)ois.readObject(); //读完不能重复读,否则会抛异常java.io.EOFException
//Student student2 = (Student)ois.readObject();
ArrayList<Student> arrayList = (ArrayList<Student>) ois.readObject();
//3.关闭流
ois.close();//内部也会关闭 fis
System.out.println("反序列化完毕");
//System.out.println(student.toString());
//System.out.println(student2.toString());
System.out.println(arrayList.toString());
}
}
Java IO流详解
2825

被折叠的 条评论
为什么被折叠?



