一、字符集
理解:字符集是计算机中每一个字符和编码之间的对应关系
ASCII字符集:一个字母占1个字节,没有汉字
GBK字符集:一个字母占1个字节,1个汉字占2个字节
Unicode字符集的UTF-8编码方案:一个字母占1个字节,一个汉字占3个字节
二、IO流
理解:IO流是用来对数据进行读写操作的
IO流分类
字节流
字节输入流:InputStream
--FileInputStream: 读取文件中的字节(读字节)
字节输出流:OutputStream
--FileOutputStream:往文件中写入字节(写字节)
字符流
字符输入流: Reader
--FileReader:读取文件中的字符(读字符)
字符输出流: Writer
--FileWriter:往文件中写入字符(写字符)
三、字节流
1.字节流读数据
1)一次读取一个字节
//第一步:创建流对象,由于我要做读取数据的操作,所以选择使用字节输入流
FileInputStream fis = new FileInputStream("day09—io\\a.txt");
//第二步:调用read方法读取一个字节,如果结果返回-1说明读取到了文件末尾
int b; //记录每次读取到的那一个字节
//(b=fis.read()): 把读取到的一个字节,赋值给b
//(b=fis.read())!=-1: 判断b的结果是否等于-1,如果不等于-1就说明没有
到达文件末尾
while ((b=fis.read())!=-1){
System.out.println((char)b);
}
//第三步:关闭流
fis.close();
2)一次读取一个字节数组
//第一步:创建FileInputStream流对象,关联一个文件路径
FileInputStream fis = new FileInputStream("day09—io\\a.txt");
//第二步:每次读取多个字节,这多个字节需要有一个数组来存储
byte[] bytes = new byte[1024]; //1024在电脑中是一个特殊的数字,
1024个字节正好表示1KB. (10月24日是程序员接)
int len; //用来记录每次读取的有效字节个数
while ((len = fis.read(bytes))!=-1){
//把读取到的有效字节,转换为字符串
//从bytes数组的0索引开始,去len个字节,转换为一个字符串
String str = new String(bytes,0,len);
System.out.println(str);
}
//第三步:关闭流
fis.close();
3)依次读取全部字节
//需求:一次性把a.txt文件中的所有字节读完
FileInputStream fis = new FileInputStream("day09—io\\a.txt");
byte[] bytes = fis.readAllBytes();
//把字节数组全部转换为字符串
String str = new String(bytes);
System.out.println(str);
2.字节流写数据
//1.创建FileOutputStream流对象
//注意1: 创建字节输出流对象时,如果文件存在,则会用新的文件覆盖
旧的文件; 如果不存在,则会新建文件。
//注意2:如果文件的父路径不存在,则无法创建文件,有异常
FileOutputStream fos = new FileOutputStream("day09—io\\a.txt",true);
//2.调用write方法写数据
//一次写一个字节
fos.write(97);
fos.write(98);
fos.write(99);
//一次写多个字节
byte[] bytes = {97,98,99};
fos.write(bytes);
//一次写一个字节数组的一部分
byte[] bytes1 = {97,98,99,100,101,102}; //abcdef
//从bytes1数组中的1索引位置开始,写4个字节到文件中
fos.write(bytes1, 1, 4);
//往文件中写入字符串数据(必须把字符串转换为字节数据才可以)
fos.write("你好世界".getBytes());
fos.write("\r\n".getBytes());
fos.write("世界你好".getBytes());
//3.调用close方法关闭流
fos.close();
3.字节流复制文件
//原理文件:a.txt,需要使用FileInputStream流对象来读取
FileInputStream fis = new FileInputStream("day09—io\\a.jpg");
//目标文件:b.txt,需要使用FileOutputStream流对象来写入
FileOutputStream fos = new FileOutputStream("day09—io\\b.jpg");
//一边读一边写(一次读取一个字节数组、一次写一个字节数组)
byte[] bytes = new byte[1024];
int len; //记录每次读取的字节个数
while ((len = fis.read(bytes))!=-1){
//把读取到的有效字节,写入到目标文件中
fos.write(bytes,0,len);
}
//关闭流
fos.close();
fis.close();
四、字符流
1.字符流读数据
//1.创建字符输入流对象(FileReader对象)
FileReader fr = new FileReader("day09—io\\a.txt");
//2.调用read(char[] chs)读取文件中的多个字符
char[] chs = new char[1024];
int len; //记录每次读取的有效字符的个数
while ((len =fr.read(chs))!=-1){
//把读取到的有效字符数据转换为字符串
//把chs数组中从0索引开始的len个字符转换为字符串
String str = new String(chs,0,len);
System.out.println(str);
}
//3.释放资源
fr.close();
2.字符流写数据
//1.创建字符输出流对象(FileWriter),指定路径文件路径
FileWriter fw = new FileWriter("day09—io\\a.txt");
//2.调用write方法写字符数据
fw.write(97); //97对应就是字符'a'
fw.write('a');
//写字符串
fw.write("helloworld");
fw.write("你好世界");
//写整个字符串数组
char[] chs = {'A','a','1','汉'};
fw.write(chs);
//写字符数组的一部分
fw.write(chs,2,2); //1汉
//写字符串的一部分
fw.write("你好世界", 1, 2);
fw.write("\r\n");
//3.释放资源
//前面的write方法写数据时,并没有直接将字符写到文件中,而是在内存中有缓存
//当调用close方法时,会把缓存的数据,刷新到文件中
//fw.flush(); //手动刷新
fw.close(); //close方法会先刷新,再关流
3.字符流复制文件
//源文件:a.txt,需要使用FileReader来读
FileReader fr = new FileReader("day09—io\\a.txt");
//目标文件:b.txt,需要使用FileWriter类写
FileWriter fw = new FileWriter("day09—io\\b.txt");
//一边读,一边写(一次读写一个字符数组的方式)
char[] chs = new char[1024];
int len; //记录每次读取的字符个数
while ((len = fr.read(chs))!=-1){
//把读取到的有效字符写到目标文件中去
fw.write(chs,0,len);
}
//释放资源
fr.close();
fw.close();
五、缓冲流
作用:对基础的流进行封装,提高基础的读、写性能
1.字符缓冲流
BufferedReader: 对Reader的子类对象进行封装,提高读字符的性能
BufferedWriter:对Writer的子类对象进行封装,提高写字符的性能
2.字节缓冲
BufferedInputStream:对InputStream的子类对象进行封装,提高读字节的性能
BufferedOutputStream:对OutputStram的子类对象进行封装,提高写字节的性能
3.关于缓冲流需要掌握两个复制
1)字符缓冲流复制文件
//第一步:创建输入、输出流对象
BufferedReader br = new BufferedReader(new FileReader("文件路径"));
BufferedWriter bw = new BufferedWriter(new FileWriter("文件路径"));
//第二步:读一行,写一行
String line; //记录每次读取的一行字符串
while((line = br.readLine())!=null){
bw.write(line);
bw.newLine(); //写换行
}
//第三步:释放资源
br.close();
bw.close();
2)字节缓冲流复制文件
//第一步:创建输入、输出流对象
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("文件路径"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("文件路径"));
//第二步:读一个字节数组,写一个字节数组
byte[] bytes = new byte[1024];
int len;
while((len = bis.read(bytes))!=-1){
bos.write(bytes,0,len);
}
//第三步:释放资源
bis.close();
bos.close();
六、转换流
作用:按照指定的编码对文件中的数据进行读、写操作
InputStreamReader: 字符输入转换流,它可以把字节输入流(InputStream)转换为
字符流输入(Reader),同时可以指定编码。
OutputStreamWriter: 字符输出转换流,它可以把字节输出流(OutputStream)转换
为字符输出流(Writer),同时可以指定编码。
把a.txt(GBK格式)文件中的内容,复制到b.txt(UTF-8)文件中
//创建输入、输出流对象
//指定GBK格式,读取a.txt文件
BufferedReader br = new BufferedReader(
new InputStreamReader(new FileInputStream("day10-io\\a.txt"), "GBK"));
//指定UTF-8格式,写入b.txt文件
BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(new FileOutputStream("day10-io\\b.txt"), "UTF-8"));
//读取一行,写入一行
String line; //记录读取的每一行
while ((line = br.readLine())!=null){
bw.write(line);
bw.newLine();
}
//关闭流
br.close();
bw.close();
七、对象流
ObjectOutputStream: 往文件中写对象
ObjectInputStream: 读取文件中的对象
演示代码如下:
//需求:把Student对象写到a.txt文件中
Student s1 = new Student("张三",20);
//创建对象输出流对象,用于把对象写到文件中(序列化)
ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("day10-io\\a.txt"));
oos.writeObject(s1);
oos.close();
//如果想要读取a.txt文件中的对象,我们必须使用ObjectInputStream反序列才可以
ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("day10-io\\a.txt"));
//Object obj = ois.readObject(); 读取的对象默认是Object类型
Student stu = (Student) ois.readObject();
System.out.println(stu);
ois.close();
注意点:
1)想要对象被序列化,必须让对象的类实现一个Serilizable接口
2)序列化和反序列化的序列号必须一致,否则会出异常
解决办法:把序列号写死
private static final long serialVersionUID = -6849794470754667711L;
八、打印流
PrintStream: 字节打印流,可以用来往文件中打印任意类型的数据
PrintWriter: 字符打印流,可以用来往文件中打印任意类型的数据
print(任意类型的数据): 打印不换行
println(任意类型的数据): 打印并换行
打印语句的底层原理:
//System.out其实就是一个打印流,这个打印流的默认目的地是控制台
//所以:调用println方法,可以往控制台打印任意类型的数据
System.out.println("hello");
修改打印语句的目的地
System.setOut(new PrintStream("day10-io\\b.txt"));
九、Properties集合
Properties是属于Map集合的一个子类,用来存储键和值,但是它的键和值都是String类型。
常用方法有下面几个
public String setProperty(String key, String value)
添加键和值到集合,如果键重复了,会把旧覆盖掉,再返回旧值
public String getProperty(String key)
根据键获取值
public Set<String> stringPropertyNames()
获取所有的键,把所有的键存储在Set集合中,并返回
public void store(Writer w, String comments)
把Properties集合中的键和值,写入到文件中
参数1:字符输出流对象、字节输出流也可以
参数2:对文件进行解释的注释,一般指支持英文,不想写用null代替
public void load(Reader r)
把文件中的键和值,读取到Properties集合中
参数:字符输入流,字节输入流也可以