字节流
作用 :
称之为万能流, 图片, 视频, 音频...都可以使用字节流进行操作
弊端 :
操作纯文本文件时, 内部如果有中文汉字, 就可能会出现乱码问题.
字节输入流
InputStream 抽象类
(1)FileInputStream
构造方法 :
1. public FileInputStream(String pathname)
2. public FileInputStream(File pathname)
成员方法 :
public int read()
//一次读取一个字节, 读取到文件末尾返回 -1
public int read(byte[] bys)
//一次读取一个字节数组
//将读取到的字节存入数组, 返回读取到的有效字节个数, 读取到文件末尾返回 -1
public void close()
//关闭流释放资源
(2)BufferedInputStream
字节缓冲输入流
字节输出流
OutputStream 抽象类
(1)FileOutputStream
构造方法 :
public FileOutputStream(String pathname)
public FileOutputStream(String pathname, boolean append)
public FileOutputStream(File pathname)
public FileOutputStream(File pathname, boolean append)
成员方法 :
public void write(int i) //一次写出一个字节
public void write(byte[] bys) 一次写出一个字节数组
public void write(byte[] bys, int off, int len) //一次写出一个字节数组的一部分
public void close()
(2)BufferedOutputStream
字节缓冲输出流
文件拷贝
FileInputStream fis = new FileInputStream("D:\\A.txt");
FIleOutputStream fos = new FileOutputStream("E:\\A.txt");
byte[] bys = new byte[1024 * 8];
int len;
while( (len = fis.read(bys)) != -1 ){
fos.write(bys, 0, len);
}
fis.close();
fos.close();
不关流,数据写出?
Q:字节流写出数据, 如果没有调用close方法, 数据能不能写出?
A:字节流内部没有内置的缓冲区, 可以写出数据
追加写入数据
输出流关联文件
文件不存在 : 会自动创建
文件存在 : 会清空文件现有的内容, 然后再写入
如果想要实现追加写入, 需要在构造方法的第二个参数, 传入 true
字符流
作用 :
解决读取纯文本文件的中文乱码问题.
Reader输入流
FileReader
构造方法 :
public FileReader(String pathname)
public FileReader(File pathname)
//按照平台默认编码表进行读取
成员方法 :
public int read()
//一次读取一个字符, 读取到文件末尾返回 -1
public int read(char[] chs)
//一次读取一个字符数组,将读取到的多个字符存入数组,返回读取到的有效字节个数,读取到末尾也是返回 -1
BufferedReader
字符缓冲输入流, 特有读取方法 :
public String readLine()
//一次读取一整行字符串, 读取到文件末尾返回 null
InputStreamReader
作用 : 可以按照指定的编码读取数据
构造方法 :
public InputStreamReader(InputStream is, String chatsetName)
//参数1 : 字节输入流关联要读取的文件
//参数2 : 指定编码表
成员方法 :
字符流通用的读取方法
Writer输出流
FileWriter
构造方法 :
public FileWriter(String pathname)
public FileWriter(String pathname, boolean append)
public FileWriter(File pathname)
public FileWriter(File pathname, boolean append)
成员方法 :
public void write(int i)
//写出一个字符
public void write(char[] chs)
//写出一个字符数组
public void write(char[] chs, int off, int len)
//写出一个字符数组的一部分
public void write(String s)
//直接写出字符串
public void write(String s, int off, int len)
//写出字符串的一部分
public void flush()
//负责将缓冲区的数据刷出到文件
BufferedWriter
字符缓冲输出流, 特有的换行方法 :
public void newLine()
//写出换行符, 具有跨平台性
OutputStreamWriter
作用 : 可以按照指定的编码写出数据
构造方法 :
public OutputStreamWriter(OutputStream os, String charsetName)
//参数1 : 字节输出流关联要写出的文件
//参数2 : 指定编码表
成员方法 :
字符流通用的写出方法
字符流解决乱码
字符流 = (字节流 + 编码表)
铺垫 : 中文字符, 字节组成第一个肯定是负数, 后面的字节有可能是正数
读取过程 : 先读取一个字节, 判断是否是负数, 如果是负数说明正在读取中文 根据平台的默认编码表, 来决定再读取多少个字节
UTF-8 : 中文占用3个字节
GBK : 中文占用2个字节
如果是UTF-8, 再读取2个字节进行转换
如果是GBK, 再读取1个字节进行转换
但是如果读取到的第一个字节是正数, 说明读取的不是中文, 直接转换.
flush()和close()区别
铺垫 : 字符输出流中, 内置了一个char[]数组, 写出数据不会直接进入文件, 而是先到这个数组中, 也就是说, 如果只调用了write方法, 没有将数据刷出, 文件中就看不到写出的数据
flush() : 将缓冲区的数据刷出到文件的, 刷出之后可以继续写出
close() : 关闭流释放资源, 只不过再关闭之前, 会检查一下缓冲区是否有数据, 有的话, 刷出再关闭, 关流之后不允许再次写出数据了.
文件拷贝
FileReader fr = new FileReader("D:\\A.txt");
FileWriter fw = new FileWriter("E:\\A.txt");
char[] chs = new char[1024];
int len;
while((len = fr.read(chs)) != -1){
fw.write(chs, 0, len);
}
fr.clsoe();
fw.close();
BufferedReader br = new BufferedReader(new FileReader("D:\\A.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("E:\\A.txt"));
char[] chs = new char[1024];
int len;
while((len = br.read(chs)) != -1){
bw.write(chs, 0, len);
}
br.close();
bw.cl
文本排序
public class BufferedStreamTest1 {
/*
需求: 对出师表.txt进行排序
*/
public static void main(String[] args) throws IOException {
// 1. 创建输入流对象关联文件 (BufferedReader : 一次读取一整行)
BufferedReader br = new BufferedReader(new FileReader("src\\com\\itheima\\day12\\出师表.txt"));
// 2. 准备集合容器, 来存储读取到的每一行数据
TreeSet<String> ts = new TreeSet<>();
// 3. 读取
String line;
while((line = br.readLine()) != null){
ts.add(line);
}
// 4. 读取完毕了关流
br.close();
// 5. 创建输出流对象关联文件, 将集合的数据写出去
BufferedWriter bw = new BufferedWriter(new FileWriter("src\\com\\itheima\\day12\\出师表.txt"));
for (String s : ts) {
bw.write(s);
bw.newLine();
}
bw.close();
}
}
//出师表.txt
//3.侍中、侍郎郭攸之、费祎、董允等,此皆良实,志虑忠纯,是以先帝简拔以遗陛下。愚以为宫中之事,事无大小,悉以咨之,然后施行,必得裨补阙漏,有所广益。
//8.愿陛下托臣以讨贼兴复之效,不效,则治臣之罪,以告先帝之灵。若无兴德之言,则责攸之、祎、允等之慢,以彰其咎;陛下亦宜自谋,以咨诹善道,察纳雅言,深追先帝遗诏,臣不胜受恩感激。
//4.将军向宠,性行淑均,晓畅军事,试用之于昔日,先帝称之曰能,是以众议举宠为督。愚以为营中之事,悉以咨之,必能使行阵和睦,优劣得所。
//2.宫中府中,俱为一体,陟罚臧否,不宜异同。若有作奸犯科及为忠善者,宜付有司论其刑赏,以昭陛下平明之理,不宜偏私,使内外异法也。
//1.先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。然侍卫之臣不懈于内,忠志之士忘身于外者,盖追先帝之殊遇,欲报之于陛下也。诚宜开张圣听,以光先帝遗德,恢弘志士之气,不宜妄自菲薄,引喻失义,以塞忠谏之路也。
//9.今当远离,临表涕零,不知所言。
//6.臣本布衣,躬耕于南阳,苟全性命于乱世,不求闻达于诸侯。先帝不以臣卑鄙,猥自枉屈,三顾臣于草庐之中,咨臣以当世之事,由是感激,遂许先帝以驱驰。后值倾覆,受任于败军之际,奉命于危难之间,尔来二十有一年矣。
//7.先帝知臣谨慎,故临崩寄臣以大事也。受命以来,夙夜忧叹,恐付托不效,以伤先帝之明,故五月渡泸,深入不毛。今南方已定,兵甲已足,当奖率三军,北定中原,庶竭驽钝,攘除奸凶,兴复汉室,还于旧都。此臣所以报先帝而忠陛下之职分也。至于斟酌损益,进尽忠言,则攸之、祎、允之任也。
//5.亲贤臣,远小人,此先汉所以兴隆也;亲小人,远贤臣,此后汉所以倾颓也。先帝在时,每与臣论此事,未尝不叹息痛恨于桓、灵也。侍中、尚书、长史、参军,此悉贞良死节之臣,愿陛下亲之信之,则汉室之隆,可计日而待也。
功能流
序列化流 (对象流)
作用 : 可以在流中以字节的形式操作对象
序列化
ObjectOutputStream
构造方法 :
public ObjectOutputStream(OutputStream os);
成员方法 :
public void writeObject(Object o);
反序列化
ObjectInputStream
构造方法 :
public ObjectInputStream(InputStream is)
成员方法 :
public Object readObject();
注意事项
1. 对象要想被序列化, 实现 Serializable
2. 如果实现了 Serializable 接口, 类中就会自带一份序列版本号
序列化操作的时候, 会将对象信息和版本号一并保存到文件
反序列化的时候, 会拿着类的版本号和流中的版本号进行比对 不一致, 就会抛出异常, 起到提醒的作用.
避免麻烦事儿 : 可以手动写死序列版本号 (抄作业 String ArrayList)
“抄作业”指的是参考Java标准库中类(如String、ArrayList)的做法,在类中显式定义一个private static final long serialVersionUID常量
3. 如果类中的属性被 transient 进行修饰, 将不会参与序列化操作
4. 建议 : 今后对象的读写操作进行一次
打印流
(1)PrintStream
构造方法 :
public PrintStream(String pathname)
public PrintStream(File pathname)
public PrintStream(OutputStream os)
//想要追加写入的时候可以使用这个构造方法
成员方法 :
public void print(任意类型) ;
public void println(任意类型);
Comments NOTHING