目录
1.为什么会出现字符流?
汉字存储问题:一个汉字存储,如果是GBK编码,占用2个字节;如果是UTF-8编码,占用三个字节。所以使用单个字节进行传输时,汉字会被拆分成两个或者三个字节单独输出,会变成乱码。为了解决这个问题,引入了字符流。
在使用字节流传输文字时,由于底层会自动拼接,也能传输汉字。系统判别字节是否是汉字的依据是,汉字存储时的第一个字节时负数,当检测到负数时,就代表这是汉字字符,进而进行字节拼接。得到汉字字符。
由于字节流操作中文不方便,因此,Java提供了字符流。字符流=字节流+编码表。
2.编码表
需要知道:计算机啊存储的信息都是用二进制表示的。
编码与解码。
字符编码;就是一套自然语言的字符与二进制数之间的对应规则。
字符集:系统支持的所有字符的集合,例如ASCII字符集,GBXXX字符集。
GB2313:GB2313是中华人民共和国使用的字符编码标准。这是一种支持多种汉字的2字节编码方案。GB2313包括简体中文和繁体中文,以及中文文本中常用的标点符号和其他符号。它于1980年由中国国家技术监督局首次引入,此后在中国大陆被广泛采用。
GBK:GB2313的扩展,最常用的,重点掌握。
Unicode字符集(Unicode Character Set)是一种用于表示文本字符的国际标准,旨在为世界上所有已知的书写系统提供一个唯一的数字代码,以便在任何计算机或设备上进行交换和处理。这个标准涵盖了大量字符集,包括拉丁字母、希腊字母、西里尔字母、中文、日文、韩文等等。Unicode字符集的编码格式可以为UTF-8、UTF-16和UTF-32等。在计算机领域中,Unicode字符集得到了广泛的应用,特别是在网页设计、软件开发、数据库处理等方面。
UTF-8是一种变长的字符编码标准,它可以表示Unicode标准中的任意字符,它使用1到4个字节来表示一个字符,具体长度取决于字符的Unicode编码值。UTF-8编码的特点是向后兼容ASCII码,即使用UTF-8编码的文本可以被ASCII编码的软件直接处理,同时也支持多语言字符集,因此被广泛应用于互联网上的各种应用和协议中。
UTF-8是一种可变长度字符编码,用于Unicode字符集的编码。它的编码规则如下:
-
对于0x0000到0x007F之间的字符,用一个字节表示,最高位为0;
-
对于0x0080到0x07FF之间的字符,用两个字节表示,最高位为110,次高位为10;
-
对于0x0800到0xFFFF之间的字符,用三个字节表示,最高位为1110,次高位为10,第三位为10;
-
对于0x10000到0x10FFFF之间的字符,用四个字节表示,最高位为11110,次高位为10,第三位为10,第四位为10。
UTF-8编码的优点是兼容ASCII编码,对于ASCII字符只需要一个字节表示,而对于非ASCII字符则需要多个字节表示。同时,UTF-8编码也支持任意Unicode字符。
3.字符串的编码解码问题
String s = "中国";
byte[] bytes = s.getBytes("GBK");//[-42, -48, -71, -6]
String ss = new String(bytes,"GBK");//中国
编码与解码使用的字符集需一致。反例如下:
String s = "中国";
byte[] bytes = s.getBytes("GBK");//[-42, -48, -71, -6]
String ss = new String(bytes,"UTF-8");//�й�乱码
4.字符流的编码解码问题
字符流抽象类:
Reader:字符输入流的抽象类
Writer:字符输出流的抽象类
相关类:
InputStreamReader:从字节流到字符流,使用的字符集可以指定
OutputStreamWriter:从字符流到字节流,字符集可以指定
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("myCharStream\\osw.txt"));
osw.write("中文");
osw.close();
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("myCharStream\\osw.txt"),"GBK");
osw.write("中文");
osw.close();
InputStreamReader isr = new InputStreamReader(new FileInputStream("myCharStream\\osw.txt"),"GBK");
int ch;
while((ch = isr.read())!= -1) {
System.out.print((char)ch);//中文
}
isr.close();
5.字符流写数据的5种方式
01
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("myCharStream\\osw.txt"));
osw.write(97);
osw.close();
02
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("myCharStream\\osw.txt"));
char [] arr = {'a','b','c','d','e'};
osw.write(arr);
osw.close();
03
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("myCharStream\\osw.txt"));
char [] arr = {'a','b','c','d','e'};
osw.write(arr,1, 3);
osw.close();
04
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("myCharStream\\osw.txt"));
String s = "abcde";
osw.write(s);
osw.close();
05
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("myCharStream\\osw.txt"));
String s = "abcde";
osw.write(s,1,4);
osw.close();
6.字符流读数据的两种方式
01
InputStreamReader isr = new InputStreamReader(new FileInputStream("myCharStream\\osw.txt"));
int ch;
while ((ch = isr.read()) != -1) {
System.out.print((char) ch);
}
isr.close();
02
InputStreamReader isr = new InputStreamReader(new FileInputStream("myCharStream\\osw.txt"));
char [] chars = new char[1024];
int len;
while ((len = isr.read(chars))!= -1) {
System.out.println(new String(chars,0,len));
}
isr.close();
7.案例:复制Java文件
package com.itheima03;
import java.io.*;
//需求
//把模块目录下的ConversionStreamDemo.java复制到模块目录下的Copy.java
public class Demo {
public static void main(String[] args) throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream("myCharStream\\src\\com\\itheima02\\ConversionStreamDemo.java"));
OutputStreamWriter osr = new OutputStreamWriter(new FileOutputStream("myCharStream\\Copy.java"));
//读取字符数组
// char [] chars = new char[1024];
// int len;
// while ((len = isr.read(chars))!= -1) {
// osr.write(chars,0,len);
// }
// 读取一个字符
int ch;
while ((ch = isr.read()) != -1) {
osr.write(ch);
}
osr.close();
isr.close();
}
}
8.改进案例
FileWriter与FileReader
package com.itheima03;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Demo02 {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("myCharStream\\src\\com\\itheima02\\ConversionStreamDemo.java");
FileWriter fw = new FileWriter("myCharStream\\Copy.java");
// int ch;
// while ((ch = fr.read())!= -1) {
// fw.write(ch);
// }
char[] chars = new char[1024];
int len;
while ((len = fr.read(chars)) != -1) {
fw.write(chars, 0, len);
}
fr.close();
fw.close();
}
}
9.字符缓冲流
package com.itheima04;
import java.io.*;
public class BufferedStreamDemo01 {
public static void main(String[] args) throws IOException {
// BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream\\bw.txt"));
// bw.write("hello\n");
// bw.write("world\n");
// bw.write("java\n");
// bw.close();
BufferedReader br = new BufferedReader(new FileReader("myCharStream\\bw.txt"));
// int ch;
// while ((ch = br.read())!= -1) {
// System.out.print((char) ch);
// }
char[] chars = new char[1024];
int len;
while ((len = br.read(chars)) != -1) {
System.out.print(new String(chars, 0, len));
}
br.close();
}
}
10.案例(字符缓冲流改进版)
package com.itheima04;
import java.io.*;
public class Demo01 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("myCharStream\\src\\com\\itheima02\\ConversionStreamDemo.java"));
BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream\\Copy.java"));
//01
// int ch;
// while ((ch = br.read())!= -1) {
// bw.write(ch);
// }
//02
char[] chars = new char[1024];
int len;
while ((len = br.read(chars)) != -1) {
bw.write(chars, 0, len);
}
br.close();
bw.close();
}
}
11.字符缓冲流的特有功能
package com.itheima04;
import java.io.*;
public class Demo02 {
public static void main(String[] args) throws IOException {
/* BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream\\bw.txt"));
for (int i=0;i<10;i++) {
bw.write("hello"+i);
bw.newLine();
bw.flush();
}
bw.close();*/
BufferedReader br = new BufferedReader(new FileReader("myCharStream\\bw.txt"));
String line;
while ((line = br.readLine())!= null) {
System.out.println(line);
}
br.close();
}
}
12.案例(字符缓冲流特有功能改进)
import java.io.*;
public class Demo03 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("myCharStream\\src\\com\\itheima02\\ConversionStreamDemo.java"));
BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream\\Copy.java"));
String line;
while ((line = br.readLine())!= null) {
bw.write(line);
bw.newLine();
bw.flush();
}
br.close();
bw.close();
}
}
13.IO流小结
字节流可以复制任意文件数据,有4种方式一般采用字节缓冲流一次读写一个字节数组的方式。
字符流只能复制文本数据,有5种方式,一般采用字符缓冲流的特有功能。
14.集合到文件
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
//集合到文件
public class Demo {
public static void main(String[] args) throws IOException {
ArrayList<String> list = new ArrayList<>();
list.add("hello");
list.add("world");
list.add("Java");
BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream\\list.txt"));
for (String s : list) {
bw.write(s);
bw.newLine();
bw.flush();
}
bw.close();
}
}
15.文件到集合
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.AbstractList;
import java.util.ArrayList;
public class Demo02 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("myCharStream\\list.txt"));
AbstractList<String> list = new ArrayList<>();
String line;
while ((line = br.readLine())!= null) {
list.add(line);
}
br.close();
System.out.println(list);
}
}
16.点名器
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Random;
public class Demo03 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("myCharStream\\name.txt"));
ArrayList<String> list = new ArrayList<>();
String s;
while ((s = br.readLine())!= null) {
list.add(s);
}
br.close();
Random random = new Random();
int index = random.nextInt(0, list.size());
String name = list.get(index);
System.out.println(name);
}
}
17.集合到文件(改进)
import java.util.Objects;
public class Student {
private String sid;
private String name;
private int age;
private String ads;
public Student() {
}
public Student(String sid, String name, int age, String ads) {
this.sid = sid;
this.name = name;
this.age = age;
this.ads = ads;
}
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAds() {
return ads;
}
public void setAds(String ads) {
this.ads = ads;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
if (age != student.age) return false;
if (!Objects.equals(sid, student.sid)) return false;
if (!Objects.equals(name, student.name)) return false;
return Objects.equals(ads, student.ads);
}
@Override
public int hashCode() {
int result = sid != null ? sid.hashCode() : 0;
result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + age;
result = 31 * result + (ads != null ? ads.hashCode() : 0);
return result;
}
}
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) throws IOException {
ArrayList<Student> list = new ArrayList<>();
Student s1 = new Student("23001", "路飞", 23, "风车村");
Student s2 = new Student("23002", "山治", 23, "巴拉蒂");
Student s3 = new Student("23003", "娜美", 23, "橘子镇");
Student s4 = new Student("23004", "乔巴", 23, "磁鼓国");
Student s5 = new Student("23005", "弗兰奇", 23, "水之都");
list.add(s1);
list.add(s2);
list.add(s3);
list.add(s4);
list.add(s5);
BufferedWriter bw = new BufferedWriter(new FileWriter("myCharStream\\student.txt"));
for (Student s : list) {
StringBuilder sb = new StringBuilder();
sb.append(s.getSid()).append(',').append(s.getName()).append(',').append(s.getAge()).append(',').append(s.getAds());
String line = sb.toString();
bw.write(line);
bw.newLine();
bw.flush();
}
bw.close();
}
} }
}
23001,路飞,23,风车村
23002,山治,23,巴拉蒂
23003,娜美,23,橘子镇
23004,乔巴,23,磁鼓国
23005,弗兰奇,23,水之都
18.文件到集合(改进)
package com.itheima06;
import java.util.Objects;
public class Student {
private String sid;
private String name;
private int age;
private String ads;
public Student() {
}
public Student(String sid, String name, int age, String ads) {
this.sid = sid;
this.name = name;
this.age = age;
this.ads = ads;
}
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAds() {
return ads;
}
public void setAds(String ads) {
this.ads = ads;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
if (age != student.age) return false;
if (!Objects.equals(sid, student.sid)) return false;
if (!Objects.equals(name, student.name)) return false;
return Objects.equals(ads, student.ads);
}
@Override
public int hashCode() {
int result = sid != null ? sid.hashCode() : 0;
result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + age;
result = 31 * result + (ads != null ? ads.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "Student{" +
"sid='" + sid + '\'' +
", name='" + name + '\'' +
", age=" + age +
", ads='" + ads + '\'' +
'}';
}
}
package com.itheima06;
import java.io.*;
import java.util.ArrayList;
public class Demo02 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("myCharStream\\student.txt"));
ArrayList<Student> list = new ArrayList<>();
String line;
while ((line = br.readLine()) != null) {
String[] strings = line.split(",");
Student s = new Student();
s.setSid(strings[0]);
s.setName(strings[1]);
s.setAge(Integer.parseInt(strings[2]));
s.setAds(strings[3]);
list.add(s);
}
br.close();
for (Student s : list) {
System.out.println(s);
}
}
}
Student{sid='23001', name='路飞', age=23, ads='风车村'}
Student{sid='23002', name='山治', age=23, ads='巴拉蒂'}
Student{sid='23003', name='娜美', age=23, ads='橘子镇'}
Student{sid='23004', name='乔巴', age=23, ads='磁鼓国'}
Student{sid='23005', name='弗兰奇', age=23, ads='水之都'}
19.集合到文件(数据排序改进版)
public class Student {
private String name;
private int lit;
private int math;
private int eng;
public Student() {
}
public Student(String name, int lit, int math, int eng) {
this.name = name;
this.lit = lit;
this.math = math;
this.eng = eng;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getLit() {
return lit;
}
public void setLit(int lit) {
this.lit = lit;
}
public int getMath() {
return math;
}
public void setMath(int math) {
this.math = math;
}
public int getEng() {
return eng;
}
public void setEng(int eng) {
this.eng = eng;
}
public int sum() {
return lit + math + eng;
}
}
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;
public class Demo {
public static void main(String[] args) throws IOException {
BufferedWriter br = new BufferedWriter(new FileWriter("myCharStream\\rankList"));
TreeSet<Student> set = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
int sum = s2.sum() - s1.sum();
int sum2 = (sum == 0) ? s2.getLit() - s1.getLit() : sum;
int sum3 = (sum2 == 0) ? s2.getMath() - s1.getMath() : sum2;
int sum4 = (sum3 == 0) ? s2.getName().compareTo(s1.getName()) : sum3;
return sum4;
}
});
for (int i = 0; i < 5; i++) {
System.out.println("请录入第" + (i + 1) + "位学生");
Student s = getScore();
set.add(s);
}
for (Student s : set) {
StringBuilder sb = new StringBuilder();
sb.append(s.getName()).append(",").append(s.getLit()).append(",").append(s.getMath()).append(",").append(s.getEng());
String line = sb.toString();
br.write(line);
br.newLine();
br.flush();
}
br.close();
}
public static Student getScore() {
Student s = new Student();
Scanner sc = new Scanner(System.in);
System.out.println("请输入学生姓名");
String name = sc.nextLine();
s.setName(name);
System.out.println("请输入语文成绩");
int lit = sc.nextInt();
s.setLit(lit);
System.out.println("请输入数学成绩");
int math = sc.nextInt();
s.setMath(math);
System.out.println("请输入英语成绩");
int eng = sc.nextInt();
s.setEng(eng);
System.out.println("录入完毕");
return s;
}
}
20.案例:复制单级文件夹
import java.io.*;
public class Demo {
public static void main(String[] args) throws IOException {
//创建数据源目录数据对象
File scrFolder = new File("E:\\itcast");
//获取数据源目录File对象的名称
String scrFolderName = scrFolder.getName();
//创建目的地目录File对象
File destFolder = new File("myCharStream", scrFolderName);
//判断目的地目录对应的File是否存在,如果不存在就创建
boolean exists = destFolder.exists();
if (!exists) {
destFolder.mkdir();
}
//获取数据源目录下的所有文件的File数组
File[] files = scrFolder.listFiles();
//遍历File数组,得到每一个File对象,其实就是数据源文件
for (File scrFile : files) {
//数据源文件:E:\\itcast\\mn.jpg
String scrFileName = scrFile.getName();
//获取目的地文件File对象,路径名是目的地目录+filename组成
File destFile = new File(destFolder, scrFileName);
//复制文件
copyFile(scrFile, destFile);
}
}
public static void copyFile(File scrFile, File destFile) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(scrFile));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));
//复制文件
byte[] bytes = new byte[1024];
int len;
while ((len = bis.read(bytes)) != -1) {
bos.write(bytes,0,len);
}
bos.close();
bis.close();
}
}
21.案例:复制多级文件夹
import java.io.*;
public class Demo {
public static void main(String[] args) throws IOException {
//创建源文件,目的地文件
File scrFile = new File("E:\\itcast");
File destFile = new File("F:\\");
//写方法实现文件夹的复制
copyFolder(scrFile, destFile);
}
public static void copyFile(File scrFile, File destFile) throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(scrFile));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));
byte[] bytes = new byte[1024];
int len;
while ((len = bis.read(bytes)) != -1) {
bos.write(bytes, 0, len);
}
bis.close();
bos.close();
}
//复制文件夹
public static void copyFolder(File scrFile, File destFile) throws IOException {
if (scrFile.isDirectory()) {
String scrFolderName = scrFile.getName();
File newFolder = new File(destFile, scrFolderName);
if (!newFolder.exists()) {
newFolder.mkdir();
}
File[] files = scrFile.listFiles();
for (File file : files) {
//把该File作为数据源File对象,递归调用复制文件夹的方法
copyFolder(file,newFolder);
}
} else {
File newFile = new File(destFile,scrFile.getName());
copyFile(scrFile, newFile);
}
}
}