各种流
各种流:
对象流
内存流
打印流
随机访问流
对象流:
对象流:将程序中的对象写入到文件,并且从文件中读取出对象到程序里。
class ObjectInputStream – 对象输入流
class ObjectOutputStream – 对象输出流
序列化(钝化):将程序里的对象写入到文件。
反序列化(活化):将文件里的对象读取到程序中。
tips:
- 如果对象想写入文件,对象所属的类就必须实现序列化接口(Serializable)。
- Serializable序列化接口没有任何的属性和方法,这种接口称之为标记型接口。
- 对象所属的类实现了序列化接口一定要添加序列化ID(serialVersionUID),不然改变对象所属的类就会报错,因为前后的对象所属的类的序列化ID不一致。
- 属性使用transient修饰,该属性不会随着对象而写入到文件中。
操作:
对象输入输出流:
写入数据:
利用对象输出流 向文件写入数据。
public static void main(String[] args) throws FileNotFoundException, IOException {
//1.创建流对象
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("io.txt"));
//2.写入数据
oos.writeInt(100);//写入int值
oos.writeDouble(123.123);//写入double值
oos.writeUTF("今天天气真好!");//写入字符串
oos.writeObject(new Date());//写入对象
//3.关闭资源
oos.close();
}
利用对象输出流 向文件写入自定义对象。
public static void main(String[] args) throws FileNotFoundException, IOException {
//1.创建流对象
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("io.txt"));
//2.写入自定义对象
oos.writeObject(new User("1234567890", "123123", "晴天", "晴天娃娃", "无极剑圣", 10000, 10000));
oos.writeObject(new User("1234543267", "111222", "雨天", "雨天娃娃", "九尾妖狐", 8000, 9000));
oos.writeObject(new User("1243657687", "123456", "多云", "伤心娃娃", "逆羽", 9000, 8000));
oos.writeObject(null);
//3.关闭资源
oos.close();
}
读取数据:
利用对象输入流 读取文件里的数据。
public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
//1.创建流对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("io.txt"));
//2.读取数据(读取顺序必须和写入顺序一致)
int readInt = ois.readInt();
double readDouble = ois.readDouble();
String str = ois.readUTF();
Date date = (Date) ois.readObject();
System.out.println(readInt);
System.out.println(readDouble);
System.out.println(str);
System.out.println(date);
//3.关闭资源
ois.close();
}
利用对象输入流 读取文件中的自定义对象。
import java.io.Serializable;
public class User implements Serializable{
//注意点1
private static final long serialVersionUID = 4907921883130742331L;
private String username;
//注意点2
private transient String password;
private String nickName;
private String name;
private String role;
private double hp;
private double mp;
public User() {
}
public User(String username, String password, String nickName, String name, String role, double hp, double mp) {
this.username = username;
this.password = password;
this.nickName = nickName;
this.name = name;
this.role = role;
this.hp = hp;
this.mp = mp;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public double getHp() {
return hp;
}
public void setHp(double hp) {
this.hp = hp;
}
public double getMp() {
return mp;
}
public void setMp(double mp) {
this.mp = mp;
}
@Override
public String toString() {
return "User [username=" + username + ", password=" + password + ", nickName=" + nickName + ", name=" + name
+ ", role=" + role + ", hp=" + hp + ", mp=" + mp + "]";
}
}
public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
//1.创建流对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("io.txt"));
//2.读取自定义对象
User user;
while((user = (User)ois.readObject()) != null){
System.out.println(user);
}
//3.关闭资源
ois.close();
}
内存流:
应用场景:项目中频繁使用的数据可以使用内存流备份一份。
class ByteArrayInputStream – 内存输入流
class ByteArrayOutputStream – 内存输出流
tips:
- 内存流是程序和内存交互,跟文件无关(与硬盘无关)。
- 内存流是程序到内存的通道,是关闭不掉的。
内存输出流:
public static void main(String[] args) throws IOException {
//1.创建流对象
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//2.写入数据 -- 将数据写入到baos对象中的byte数组里
//new 的数组在堆里面,在内存中。
baos.write("123abc木头人".getBytes());
//关闭资源(内存流是程序到内存的通道,是关闭不掉的)
//baos.close();
//获取流对象里的数据
System.out.println(new String(baos.toByteArray()));
System.out.println(baos.toString());
}
内存输入流:
public static void main(String[] args) throws IOException {
//1.创建流对象
ByteArrayInputStream bais = new ByteArrayInputStream("123abc木头人".getBytes());
//2.读取数据
byte[] bs = new byte[1024];
int len;
while((len = bais.read(bs)) != -1){
System.out.println(new String(bs, 0,len));
//关闭资源(内存流是程序到内存的通道,是关闭不掉的)
//bais.close();
}
}
打印流:
lass PrintStream – 字节打印流
class PrintWriter – 字符打印流
tips:
打印流实际上就是输出流,只有一个方向(程序->文件)。
PrintStream 和 PrintWriter 区别:
区别1: PrintStream是以字节为单位。
PrintWriter是以字符为单位。
区别2: PrintStream:将字节流转换为字节打印流。
PrintWriter:将字节流和字符流转换为字符打印流。
字节打印流:
public static void main(String[] args) throws IOException {
//1.创建流对象
//PrintStream ps = new PrintStream("io.txt");
//1.创建流对象(字节流 -> 字节打印流)
//PrintStream ps = new PrintStream(new FileOutputStream("io.txt"));
//1.创建流对象(字节流 -> 字节打印流) + 在末尾追加
PrintStream ps = new PrintStream(new FileOutputStream("io.txt",true));
//2.写入数据
ps.write("今天天气真好!".getBytes());
//3.关闭资源
ps.close();
}
字符打印流:
public static void main(String[] args) throws IOException {
//1.创建流对象
//PrintWriter pw = new PrintWriter("io.txt");
//1.创建流对象(字节流 -> 字节打印流)
//PrintWriter pw = new PrintWriter(new FileOutputStream("io.txt"));
//1.创建流对象(字节流 -> 字节打印流) + 在末尾追加
//PrintWriter pw = new PrintWriter(new FileOutputStream("io.txt",true));
//1.创建流对象(字符流 -> 字符打印流)
//PrintWriter pw = new PrintWriter(new FileWriter("io.txt"));
//1.创建流对象(字符流 -> 字符打印流) + 在末尾追加
//PrintWriter pw = new PrintWriter(new FileWriter("io.txt",true));
//1.创建流对象(设置编码格式 + 在末尾追加 + 考虑到效率)
//设置编码格式----->OutputStreamWriter
//在末尾追加------>FileOutputStream
//考虑到效率------>BufferedWriter
PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream("io.txt",true), "GBK")));
//2.写入数据
pw.write("今天天气真好!");
//3.关闭资源
pw.close();
}
随机访问流:
随机访问流:该流认为文件是一个大型的byte数组。有一个隐藏的指针(默认为0),其实就是下标,可以从指针的位置写入或读取,意味着该流两个方向(写入–>输出流,读取–>输入流)。
模式:r-读,rw-读写
class RandomAccessFile – 随机访问流
写入数据:
利用随机访问流 向文件写入数据。
需求1:向文件写入 数字、英文、中文数据。
public static void main(String[] args) throws IOException {
//1.创建流对象
RandomAccessFile w = new RandomAccessFile("io.txt", "rw");
//2.写入数据
w.write("123abc木头人".getBytes());
//3.关闭资源
w.close();
}
利用随机访问流 向文件写入数据。
需求1:向文件写入 数字、英文、中文数据。
需求2:在文件末尾追加。
public static void main(String[] args) throws IOException {
//1.创建流对象
File file = new File("io.txt");
RandomAccessFile w = new RandomAccessFile(file, "rw");
//设置指针的位置,把指针移到文件末尾
w.seek(file.length());
//2.写入数据
w.write("123abc木头人".getBytes());
//3.关闭资源
w.close();
}
读取数据:
利用随机访问流 读取文件里的数据。
需求1:读取数据。
public static void main(String[] args) throws IOException {
//1.创建流对象
RandomAccessFile r = new RandomAccessFile("io.txt", "r");
//2.读取数据
byte[] bs = new byte[1024];
int len;
while((len = r.read(bs)) != -1){
System.out.println(new String(bs, 0, len));
}
//3.关闭资源
r.close();
}
利用随机访问流 读取文件里的数据。
需求1:读取数据。
需求2:从英文处开始读取数据。
public static void main(String[] args) throws IOException {
//1.创建流对象
RandomAccessFile r = new RandomAccessFile("io.txt", "r");
//设置指针的位置
r.seek(3);
//2.读取数据
byte[] bs = new byte[1024];
int len;
while((len = r.read(bs)) != -1){
System.out.println(new String(bs, 0, len));
}
//3.关闭资源
r.close();
}
拷贝文件:
public static void main(String[] args) throws IOException {
RandomAccessFile r = new RandomAccessFile("Original.mp4", "r");
RandomAccessFile w = new RandomAccessFile(copy.mp4, "rw");
byte[] bs = new byte[1024];
int len;
while((len = r.read(bs)) != -1){
w.write(bs, 0, len);
}
r.close();
w.close();
}
断点续传!
public static void main(String[] args) throws IOException {
RandomAccessFile r = new RandomAccessFile("Original.mp4", "r");
File targetFile = new File("copy.mp4");
RandomAccessFile w = new RandomAccessFile(targetFile, "rw");
//设置指针
long fileLength = targetFile.length();
r.seek(fileLength);
w.seek(fileLength);
byte[] bs = new byte[1024];
int len;
while((len = r.read(bs)) != -1){
w.write(bs, 0, len);
}
r.close();
w.close();
}