1.练习回顾
①使用文件输出字节流将"hello world"输出到文件中;
②使用文件输入字节流将文件中的内容读取进来并打印到控制台中。
public static void main(String[] args) throws IOException {
File file = new File("e:/Desktop/mu.txt");
if(file.exists()){
file.delete();
}
String s = "Hello World";
OutputStream os = new FileOutputStream(file);
os.write(s.getBytes());
os.flush();
os.close();
InputStream is = new FileInputStream(file);
byte[] b = new byte[1024];
int count = is.read(b);
//String s1 = new String(b,0,count);
String s1 = new String(b);
System.out.println(s1);
is.close();
}
2.缓冲字节流(处理流/包装流)
缓冲流:缓冲流是一个处理流,在普通流的基础上添加了缓冲区,能够在传输数据的时候提升读取或写入效率。
好处:
①不带缓冲的流读取到一个字节或字符就直接输出;
②带有缓冲的流读取到一个字节或字符先不输出,等达到缓冲区容量再一次性写出。
BufferedInputStream和BufferedOutputStream可以增加内存缓冲区 :
①BufferedInputStream构造方法:
BufferedInputStream(InputStream in)//创建带有32个字节缓冲区的缓冲流
BufferedInputStream(InputStream in,int size)//按指定大小来创建缓冲区
②BufferedOutputStream构造方法:
BufferedOutputStream(OutputStream in)//创建带有32个字节缓冲区的缓冲流
BufferedOutputStream(OutoutStream in,int size)//按指定的大小来创建缓冲区
public static void main(String[] args) throws IOException {
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("e:/Desktop/mu.txt",true));//true:追加的方式写入
String s = "\n笑揖峰头月一轮";
bos.write(s.getBytes());
//清空缓冲区,关闭流
bos.flush();
bos.close();
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("e:/Desktop/mu.txt"));
byte[] b = new byte[1024];
bis.read(b);
System.out.println(new String(b));
bis.close();
}
缓冲流实现文件复制:
public class Test2 {
public void copyFile(String srcPath,String destPath) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcPath));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destPath));
byte[] b = new byte[1024];
while (bis.read(b)!=-1){
bos.write(b);
}
bos.flush();
bos.close();
bis.close();
}
public static void main(String[] args) throws IOException {
Test2 test2 = new Test2();
test2.copyFile("e:/Desktop/ren.png","e:/Desktop/mu.png");
}
}
3.对象流(处理流/包装流)
对象流:可以将内存中的对象数据序列化到磁盘文件中;
ObjectInputSream 将文件中的对象读取到程序中;
ObjectOutputStream 将程序中的对象写入到文件中。
3.1 序列化与反序列化
①序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程,在序列化期间,对象将其当前状态写入到临时或持久性存储区;以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象;(例如:存储游戏进度,下次再接着玩)②反序列化: 反向操作,将数据从存储状态恢复到内存中。
注:
①如果要将一个对象序列化到磁盘上,那么该对象必须实现Serializable接口;
②为了保证类的一致性,需要在类中定义版本序列号serialVersionUID;
idea自动生成序列化id的配置:File---》settings---》Editor--》 inspections--》java---》Serialization issues---》Serializable class without 'serialVersionUID'---》打对勾。
③如果类中的某个属性不需要序列化,可以给它标记transient。
3.2 使用
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Game g = new Game();
g.setName("目一个");
g.setLevel(7);
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("e:/Desktop/muyige.txt"));
oos.writeObject(g);
oos.close();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("e:/Desktop/muyige.txt"));
//读取的对象数据是 Object 需要强转为Game
Game g1= (Game)ois.readObject();
System.out.println(g1);
ois.close();
}
}
public class Game implements Serializable {
/**
* 配置序列号可以保证在该类做了修改之后,反序列化时仍然能够识别为原始的类型,保持类的一致性
*/
private static final long serialVersionUID = 220_021_219;
private String name;
private int level;
//增加的修改
private int score;
public static long getSerialVersionUID() {
return serialVersionUID;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
@Override
public String toString() {
return "Game{" +
"name='" + name + '\'' +
", level=" + level +
'}';
}
}
4.字符流
字符流:以字符为基本单位进行数据的传输
4.1 输入字符流
抽象类:Reader
实现类:FileReader
方法 | 描述 |
public abstract void close() | 关闭输入流 |
public int read() | 读取单个字符 |
public int read(char[ ] c) | 将内容读取到字符数组中,并返回读取的长度 |
4.2 输出字符流
抽象类:Writer
实现类:FileWriter
方法 | 描述 |
public abstract void close() | 关闭输出流 |
public void write(String str) | 输出字符串 |
public void write(char[] c) | 输出字符数组 |
public abstract void flush() | 强制清空缓存 |
public static void main(String[] args) throws IOException {
Writer writer = new FileWriter("e:/Desktop/wen.txt");
char[] b = "目小小小小小小小小小小小小小小小小小温".toCharArray();
//writer.write("目小小小小小小小小小小小小小小小小小温");
writer.write(b);
writer.flush();
writer.close();
Reader reader = new FileReader("e:/Desktop/wen.txt");
char[] cs = new char[1024];
int count =reader.read(cs);
System.out.println("读到的个数:"+count+" "+new String(cs));
reader.close();
}
4.3 缓冲字符流
BufferedReader:缓冲字符输入流
BufferedWriter:缓冲字符输出流
public static void main(String[] args) throws IOException {
BufferedWriter bw = new BufferedWriter(new FileWriter("e:/Desktop/wen.txt"));
bw.write("万事无如退步人,\n孤云野鹤自由身。");
//换行
bw.newLine();
bw.write("松风十里时来往,\n笑揖峰头月一轮。");
bw.flush();
bw.close();
BufferedReader br = new BufferedReader(new FileReader("e:/Desktop/wen.txt"));
String res;
while ((res=br.readLine())!=null){
System.out.println(res);
}
br.close();
}
5. 字节字符转换流(处理流/包装流)
InputStreamReader 将字节输入流转换成字符输入流
OutputStreamWriter 将字符输出流转为字节输出流
InputStreamReader(InputStream in,"gb2312") | 将读取的字节流转换成字符流,可指明编码格式 |
OutputStreamWriter(OutputStream os
,"utf-8")
| 将书写的字符流转换成字节流写到文件里,可指明编码格式 |
转换流就是对字节流的封装,将字节流封装成一个字符流,可以指明编码格式。(默认按GBK的编码转化)
注:字节流可以用来操作所有文件,字符流操作文本文件。
public static void main(String[] args) throws IOException {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("e:/Desktop/wen.txt"));
osw.write("今天有点热热的");
osw.flush();
osw.close();
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("e:/Desktop/wen.txt")));
String content;
while ((content= br.readLine())!=null){
System.out.println(content);
}
br.close();
}
6. 格式化打印流(对于输出流的功能进行增强)
PrintWriter:是Writer的子类,用于将格式化对象打印到一个文本输出流
public static void main(String[] args) throws FileNotFoundException {
PrintWriter pw = new PrintWriter("e:/Desktop/wen.txt");
pw.println("万事无如退步人,");
pw.println("孤云野鹤自由身。");
pw.println("松风十里时来往,");
pw.println("笑揖峰头月一轮。");
String name = "目小温";
String sex = "男";
double tall = 1.82;
//格式化输出: %s 字符串;%d 整数;%f 小数
pw.printf("姓名:%s 性别:%s 身高:%.2f",name,sex,tall);
pw.flush();
pw.close();
}