字符流
字符流出现原因
一个汉字如果是GBK编码,占用2字节,如果是UTF-8编码,占用3个字节
编码表
字符集
采用什么规则编码,就得采用对应规则解码,否则就会出现乱码
字符串中的编码解码问题
//定义一个字符串
String s = "中国";
//byte[] getBytes();使用平台默认字符集将该String编码为一系列字节,将结果存储到新的字节数组中
byte[] bys = s.getBytes();
sout(Arrays.toString(bys));//输出-28 -72 -83 -27 -101 -67
//byte[] getBytes(String charsetName); 使用指定的字符集将该String编码为一系列字节,将结果存储到新的字节数组中
byte[] bys = s.getBytes(charsetName:"UTF-8");
sout(Arrays.toString(bys));//输出-28 -72 -83 -27 -101 -67
byte[] bys = s.getBytes(charsetName:"GBK");
sout(Arrays.toString(bys));//输出-42 -48 -71 -6
//解码
//String(byte[] bytes) 通过平台的默认字符集解码指定的字节数组来构建新的String
String ss = new String(bys);
sout(ss);
//String(byte[] bytes,String charsetName) 通过指定的字符集将该String编码为一系列字节,将结果存储到新的字节数组中
String ss = new String(bys,charsetName:"UTF-8");
sout(ss);
String ss = new String(bys,charsetName:"GBK");
sout(ss);
字符流中的编码解码问题
可以指定字符集
OutputStreamWriter 字符到字节,使用指定的编码将写入的字符编码为字节,使用的字符集可以由名称指定,也可以被明确指定,或者使用默认的
FileOutputStream fos = new FileOutputStream(name:"myCharStream\osw.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos);
//简化一下
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(name:"myCharStream\osw.txt"));//默认编码
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(name:"myCharStream\osw.txt",charsetName:"UTF-8"));//指定编码
osw.write(str:"中国");
osw.close();
//字节解码为字符
InputStreamReader isr = new InputStreamReader(new FileInputStream(name:"myCharStream\osw.txt"));//默认编码
InputStreamReader isr = new InputStreamReader(new FileInputStream(name:"myCharStream\osw.txt",charsetName:"UTF-8"));//指定编码
//一次读取一个字符数据
int ch;
while((ch = isr.read()) != -1){
System.out.print((char)by);
}
isr.close();
字符流写数据的5种方式
//创建一个使用默认字符编码的OutputStreamWriter
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(name:"myCharStream\osw.txt"));
//void write(int c) **写一个字符**
osw.write(c:97);//字符流写数据不能直接写到文件里去,现在还在缓冲区
//void flush() 刷新流
osw.flush();//刷新一下数据就到文件里去了 要想写进去就得刷新
//void write(char[] cbuf) **写一个字符数组**
char[] chs = {'a','b','c','d','e'};
osw.write(chs);
//void write(char[] cbuf,int off,int len) **写一个字符数组的一部分**
osw.write(chs,off:0,chs.length);
osw.write(chs,off:1,len:3);//从1索引开始写三个 就是bcd
//void write(String str) **写一个字符串**
osw.write(str:"abcde");
//void write(String str,int off,int len) **写一个字符串的一部分**
osw.write(str:"abcde",off:0,chs.length);
osw.write(str:"abcde",off:1,len:3);//从1索引开始写三个 就是bcd
osw.close();//关闭流会先刷新一下
flush刷新后还能写,close关闭前会刷新但是关闭了就不能写数据了
字符流读数据的2种方式
InputStreamReader isr = new InputStreamReader(new FileInputStream(name:"myCharStream\osw.txt"));//默认编码
//int read():一次读一个字符数据
int ch;
while((ch = isr.read()) != -1){
System.out.print((char)by);
}
//int read(char[] cubf):一次读一个字符数组数据
char[] chs = new char[1024];
int len;
while((len = isr.read(chs)) != -1){
System.out.print(new String(chs,offset:0,len));
}
isr.close();//关闭流会先刷新一下
字节流和字符流读数据的方式是一样的
复制java文件
把模块目录下的"ConversionStreamDemo.java"复制到模块目录下的"Copy.java"
//数据源创建字符输入流对象
InputStreamReader isr = new InputStreamReader(new FileInputStream(name:"myCharStream\\ConversionStreamDemo.java"));//默认编码
//目的地创建字符输出流对象
OutputStreamWriter
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(name:"myCharStream\\Copy.java"));
//读写数据复制文件
//一次读写一个字符数据
int ch;
while((ch = isr.read()) != -1){
osw.write(ch);
}
//一次读写一个字符数组数据
char[] chs = new char[1024];
int len;
while((len = isr.read(chs)) != -1){
osw.write(chs,off:0,len);
}
//释放资源
osw.close();
isr.close();
复制java文件改进版
把模块目录下的"ConversionStreamDemo.java"复制到模块目录下的"Copy.java"
//数据源创建字符输入流对象
FileReader fr = new FileReader(fileName:"myCharStream\\ConversionStreamDemo.java");
//目的地创建字符输出流对象
FileWriter fw = new FileWriter(fileName:"myCharStream\\Copy.java");
//读写数据复制文件
//一次读写一个字符数据
int ch;
while((ch = fr.read()) != -1){
fw.write(ch);
}
//一次读写一个字符数组数据
char[] chs = new char[1024];
int len;
while((len = fr.read(chs)) != -1){
fw.write(chs,off:0,len);
}
//释放资源
fw.close();
fr.close();
字符缓冲流
从字符输入流中读取文本,缓冲字符,可以指定缓冲区大小,或者使用默认大小
//BufferedWriter(Writer out)
FileWriter fw = new FileWriter(fileName:"myCharStream\\bw.txt");
BufferedWriter bw = new BufferedWriter(fw);
//综合
BufferedWriter bw = new BufferedWriter(new FileWriter(fileName:"myCharStream\\bw.txt"));//默认是8192字符的字符数组
bw.write(str:"hello\r\n");
bw.write(str:"world\r\n");
bw.close();
BufferedReader br = new BufferedReader(new FileReader(fileName:"myCharStream\\bw.txt"));
//一次读一个字符
int ch;
while((ch = br.read()) != -1){
System.out.print((char)ch);
}
//一次读取一个字符数组
char[] chs = new char[1024];
int len;
while((len = br.read(chs)) != -1){
System.out.print(new String(chs,offset:0,len));
}
复制java文件 字符缓冲流改进版
把模块目录下的"ConversionStreamDemo.java"复制到模块目录下的"Copy.java"
//数据源创建字符输入流对象
BufferedReader br = new BufferedReader(new FileReader(fileName:"myCharStream\\ConversionStreamDemo.java"));
//目的地创建字符输出流对象
BufferedWriter bw = new BufferedWriter(new FileWriter(fileName:"myCharStream\\Copy.java"));
//读写数据复制文件
//一次读写一个字符数据
int ch;
while((ch = br.read()) != -1){
bw.write(ch);
}
//一次读写一个字符数组数据
char[] chs = new char[1024];
int len;
while((len = br.read(chs)) != -1){
bw.write(chs,off:0,len);
}
//释放资源
bw.close();
br.close();
字符缓冲流特有功能
//创建字符缓冲输出流
BufferedWriter bw = new BufferedWriter(new FileWriter(fileName:"myCharStream\\bw.txt"));
//写数据
for(int i = 0;i < 10;i++){
bw.write(str:"hello"+i);
bw.write(str:"\r\n");
//或者不用上面的换行 用下面这种写法
bw.newwLine();
bw.flush();
}
//创建字符缓冲输入流
BufferedReader br = new BufferedReader(new FileReader(fileName:"myCharStream\\bw.txt"));
//public String readline():读一行文字
//第一次读取数据 到达结尾就输出null
String line = br.readLine();
sout(line);
//循环改进
String line;
while((line = br.readLine())!=null){
sout(line);//不包含换行符
}
//释放资源
bw.close();
复制java文件 字符缓冲流特有功能改进版
//数据源创建字符输入流对象
BufferedReader br = new BufferedReader(new FileReader(fileName:"myCharStream\\ConversionStreamDemo.java"));
//目的地创建字符输出流对象
BufferedWriter bw = new BufferedWriter(new FileWriter(fileName:"myCharStream\\Copy.java"));
//读写数据复制文件
//使用字符缓冲流特有功能实现
String line;
while((line = br.readLine())!=null){
bw.write(line);//不包含换行符 所有数据都在同一行
bw.newwLine();
bw.flush();
}
//释放资源
bw.close();
br.close();
IO流小结
案例 集合到文件
//创建ArrayList集合
ArrayList array = new ArrayList();
//往集合中存储字符串元素
array.add("Hello");
array.add("World");
array.add("Java");
//目的地创建字符缓冲输出流对象
BufferedWriter bw = new BufferedWriter(new FileWriter(fileName:"myCharStream\\array.txt"));
//遍历集合,得到每一个字符串数据
for(String s ;array){
//调用字符缓冲输出流对象的方法写数据
bw.write(s);//不包含换行符 所有数据都在同一行
bw.newwLine();
bw.flush();
}
//释放资源
bw.close();
案例 文件到集合
//数据源创建字符缓冲输入流对象
BufferedReader br = new BufferedReader(new FileReader(fileName:"myCharStream\\array.txt"));
//创建ArrayList集合对象
ArrayList array = new ArrayList();
//调用字符缓冲输入流对象的方法读数据
String line;
while((line = br.readLine())!=null){
array.add(line);
}
//释放资源
br.close();
//遍历集合
for(String s ;array){
sout(s);
}
案例 点名器
//数据源创建字符缓冲输入流对象
BufferedReader br = new BufferedReader(new FileReader(fileName:"myCharStream\\name.txt"));
//创建ArrayList集合对象
ArrayList array = new ArrayList();
//调用字符缓冲输入流对象的方法读数据
String line;
while((line = br.readLine())!=null){
//把读取到的数据存储到集合中
array.add(line);
}
//释放资源
br.close();
//使用Random产生一个随机数,随机数的范围在0-集合长度
Random r = new Random();
int index = r.nextInt(array.size());
//把上面产生的随机数作为索引到集合中获取值
String name = array.get(index);
//输出
sout(name);
案例 集合到文件改进版
//创建ArrayList集合
ArrayList array = new ArrayList();
//创建学生对象
Student s1 = new Student(sid:"itheima001",name:"林青霞",age:"30",address:"西安");
Student s2 = new Student(sid:"itheima002",name:"张曼玉",age:"35",address:"武汉");
Student s3 = new Student(sid:"itheima003",name:"王祖贤",age:"33",address:"郑州");
//把学生对象添加到集合中
array.add(s1);
array.add(s2);
array.add(s3);
//目的地创建字符缓冲输出流对象
BufferedWriter bw = new BufferedWriter(new FileWriter(fileName:"myCharStream\\Student.txt"));
//遍历集合,得到每一个学生对象
for(Student s ;array){
//把学生对象的数据拼接成指定格式的字符串
StringBuilder sb = new StringBuilder();
sb.append(s.getSid()).append(",").append(s.getName()).append(",").append(s.getAge()).append(",").append(s.getAddress());
//调用字符缓冲输出流对象的方法写数据
bw.write(sb.toString());//不包含换行符 所有数据都在同一行
bw.newwLine();
bw.flush();
}
//释放资源
bw.close();
案例 文件到集合改进版
//数据源创建字符缓冲输入流对象
BufferedReader br = new BufferedReader(new FileReader(fileName:"myCharStream\\Student.txt"));
//创建ArrayList集合对象
ArrayList array = new ArrayList();
//调用字符缓冲输入流对象的方法读数据
String line;
while((line = br.readLine())!=null){
//把读到的字符串数据用split()进行分割,得到一个字符串数组
String[] strArray = line.split(reqex:",");
//创建学生对象
Student s = new Student();
s.setSid(strArray[0]);
s.setName(strArray[1]);
s.setAge(Integer.parseInt(strArray[2]));
s.setAddress(strArray[3]);
//把学生对象添加到集合中
array.add(s);
}
//释放资源
br.close();
//遍历集合
for(Student s ;array){
sout(s.getSid()+","+s.getName()+","++s.getAge()+","+s.getAddress());
}