缓冲流:
缓冲流其实是一个包装流,基于基本输入和输出流,提供程序读写的效率。
字节缓冲流:底层的读和写还是依赖于InputStream和OutputStream
字符缓冲流:底层的渡河写还是依赖于Reader和Writer
字节缓冲流
//把a.flv内容复制到b.flv中
//使用BufferedInputStream 对InputStream进行包装
BufferedInputStream bis=new BufferedInputStream(new FileInputStream("C:\\Users\\WANGQI\\Desktop\\a.flv"));
//使用BufferedOuputStream, 对OutputStream进行包装
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("C:\\Users\\WANGQI\\Desktop\\b.flv"));
byte[] bs=new byte[1024];
int len;
while((len=bis.read(bs))!=-1){
bos.write(bs,0,len);
}
bis.close();
bos.close();
字符缓冲流
//把a.txt内容复制到b.txt中
//使用BufferedReader 对 FileReader进行包装
BufferedReader br=new BufferedReader(new FileReader("day10-code\\a.txt"));
//使用BufferedWriter 对 FileWriter进行包装
BufferedWriter bw=new BufferedWriter(new FileWriter("day10-code\\b.txt"));
//一次读取一行的方式 readLine()
String line; //记录每次读取的一行数据
while((line=br.readLine())!=null){
bw.write(line);
bw.newLine(); //写换行付(可以跨平台)
bw.flush();
}
//释放资源
bw.close();
br.close();
缓冲流练习
public class Demo3 {
public static void main(String[] args) throws IOException {
//1. 读文件到集合
ArrayList<String> list=new ArrayList<>();
BufferedReader br=new BufferedReader(new FileReader("day10-code\\a.txt"));
String line;
while ((line=br.readLine())!=null){
list.add(line);
}
br.close();
//2. 对集合进行排序
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
//o1-o2 升序
//o2-o1 降序
return o2.compareTo(o1);
}
});
//3. 把集合中的元素,写入到a.txt文件中覆盖即可
BufferedWriter bw=new BufferedWriter(new FileWriter("day10-code\\a.txt"));
for (String s : list) {
bw.write(s);
bw.newLine();
bw.flush();
}
bw.close();
}
}
了解几种常用的编码表
ASCII码表: 包含一些字母、符号、数字
一个符号占用一个字节
GBK码表:兼容ASCII码表,包含汉字
一个汉字占2个字节
UTF-8码表: 兼容ASCII码表,包含汉字也包含其他国家的文字
一般情况一个汉字占3个字节
由编码表引出的问题:
由于中文简体Windows操作系统使用的编码表是GBK,如果使用系统新建一个文本文件默认编码表就是GBK.
如果使用Java代码读取这个文件,就会有乱码。因为Intellij IDEA使用的UTF-8编码。
【乱码的原因:编码和解码的字符集不是同一个,就会产生乱码】
转换流:
可以使用指定的编码进行读和写的操作
背景:任何文件底层其实都是字节,IDE默认使用的是UTF-8 编码对文本文件进行读和写的操作。如果不是UTF-8 文件就会读写错误
为了解决这个问题,我们可以使用转换流指定编码进行读和写的操作。
/*
把a.txt文件(GBK编码)中的内容,复制到b.txt文件(UTF-8编码)中
数据源: a.txt文件(GBK编码)
使用GBK读取a.txt文件中的内容
数据目的: b.txt文件(UTF-8编码)
把读取到的内容通过UTF-8编码写到b.txt文件中去
*/
//使用GBK读取a.txt文件中的内容
InputStreamReader isr=new InputStreamReader(new FileInputStream("day10-code\\a.txt"),"GBK");
//把读取到的内容通过UTF-8编码写到b.txt文件中去
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("day10-code\\b.txt"),"UTF-8");
char[] chs=new char[1024];
int len=0;
while((len=isr.read(chs))!=-1){
osw.write(chs,0,len);
}
isr.close();
osw.close();
Properties集合:
属于Map集合的实现类,也是一个双列集合。【注意:键和值都是String类型】
Properties常用方法
Object setProperty(String key, String value)
添加建值对到集合。如果键重复,把原来的值覆盖。
String getProperty(String key)
根据键获取值
Set<String> stringPropertyNames()
获取所有的键,把所有的键存储到Set集合。
void load(Reader reader)
把文件中的键值对,加载到Properties中
void store(Writer writer, String comments)
把Properties集合中的键值对,存储到文件中
代码演示:
Properties pro=new Properties();
pro.setProperty("name","LOL");
pro.setProperty("date","2018-08-08");
//把集合中的键值对,存储到config.pro文件中。
pro.store(new FileWriter("day10-code\\config.pro"),null);
//把config.pro文件中的键值对,读取到Properties集合中
pro.load(new FileReader("day10-code\\config.pro"));
//获取所有的键
Set<String> keys=pro.stringPropertyNames();
for(String key:keys){
//通过键获取值
String value=pro.getProperty(key);
System.out.println(key+"="+value);
}
程序结束后,看config.txt文件中的内容如下(#代表注释,不会被读取)
#Wed Aug 22 10:11:58 CST 2018
date=2018-08-08
name=LOL
一、标准的输入输出流
System.out: 标准的输出流,数据会输出到控制台
System.in:标准的输入流,用来读取键盘录入的数据
二、打印流
只关注数据的输出目的,不关注数据源。【只能写,不能读】
PrintWriter和PrintStream
//只关注数据的输出目的,不关注数据源。【只能写,不能读】
//输出目的是控制台
PrintWriter pw=new PrintWriter(System.out);
pw.println(true);
pw.close();
//输出目的是文件路径
PrintWriter pw1=new PrintWriter("day10-code\\b.txt");
pw1.write("hello");
pw1.close();
//输出目的可以是File对象
PrintWriter pw2=new PrintWriter(new File("day10-code\\b.txt"));
pw2.write("hello");
pw2.close();
//输出目的可以是流对象
PrintWriter pw3=new PrintWriter(new FileOutputStream("day10-code\\b.txt"));
pw3.write("wrold");
pw3.close();
除了可以使用write方法往对应的目的地写数据,还有两个特殊的方法
print(...) 可以把想要的数据,原样输出。
println(...) 可以把想要的数据,原样输出。还可以自动换行;还可以自动刷新,但是要写一个true标记。
三、对象流(序列化流)
对象流是用来往文件中存储对象或者从文件中读取对象的
ObjectOutputStream:存储对象(序列化)
writeObject(Object obj) 往文件写对象
ObjectInputStream:读取对象(反序列化)
Object readObject() 读取文件中的对象
注意事项:
1. 被序列化的类必须实现Serializable,否则会报错NotSerializableException
2. 读和写的序列化必须保持一致,否则就会出现无效的类异常InvalidClassException
解决办法:写一个固定的序列号,不会被改变。
private static final long serialVersionUID = 8683488581122892189L;
今日重点总结:
一、Properties集合
属于Map集合的实现类,也是一个双列集合。【注意:键和值都是String类型】
Properties一般和配置文件结合起来使用。
Properties pro=new Properties();
pro.setProperty("name","LOL");
pro.setProperty("date","2018-08-08");
//把集合中的键值对,存储到config.pro文件中。
pro.store(new FileWriter("day10-code\\config.pro"),null);
//把config.pro文件中的键值对,读取到Properties集合中
pro.load(new FileReader("day10-code\\config.pro"));
//获取所有的键
Set<String> keys=pro.stringPropertyNames();
for(String key:keys){
//通过键获取值
String value=pro.getProperty(key);
System.out.println(key+"="+value);
}
二、缓冲流
缓冲流其实是一个包装流,基于基本输入和输出流,提供程序读写的效率。
字节缓冲流:底层的读和写还是依赖于InputStream和OutputStream
字符缓冲流:底层的渡河写还是依赖于Reader和Writer
//把a.txt内容复制到b.txt中
//使用BufferedReader 对 FileReader进行包装
BufferedReader br=new BufferedReader(new FileReader("day10-code\\a.txt"));
//使用BufferedWriter 对 FileWriter进行包装
BufferedWriter bw=new BufferedWriter(new FileWriter("day10-code\\b.txt"));
//一次读取一行的方式 readLine()
String line; //记录每次读取的一行数据
while((line=br.readLine())!=null){
bw.write(line);
bw.newLine(); //写换行付(可以跨平台)
bw.flush();
}
//释放资源
bw.close();
br.close();
三、转换流
/*
把a.txt文件(GBK编码)中的内容,复制到b.txt文件(UTF-8编码)中
数据源: a.txt文件(GBK编码)
使用GBK读取a.txt文件中的内容
数据目的: b.txt文件(UTF-8编码)
把读取到的内容通过UTF-8编码写到b.txt文件中去
*/
//使用GBK读取a.txt文件中的内容
InputStreamReader isr=new InputStreamReader(new FileInputStream("day10-code\\a.txt"),"GBK");
BufferedReader br=new BufferedReader(isr);
//把读取到的内容通过UTF-8编码写到b.txt文件中去
OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("day10-code\\b.txt"),"UTF-8");
BufferedWriter bw=new BufferedWriter(osw);
String line;
while((line=br.readLine())!=null){
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
br.close();