一、字符流概述
1.字符流 就是用于来读写字符操作的流
2.字符流使用的原因: 使用字节流来读取文件中中文会出现乱码 因为中文不是一个字节组成的
所以读取中文的时候 需要使用字符流 字符实际上也是使用字节流来进行读取 只是字符流底层进行了
转换
字符流 = 字节流+ 编码表 通过字节流进行读取 通过编码表来进行转换
3. 所有的中文不管在那种编码表下 第一个字节都是负数 所以根据这个规律就可以进行转换
二、编码表
1.字符集: 也就是包含全世界国家的语言或者是字符的集合
2.计算在存储所有国家的语言字符的时候, 都是根据一个具体的码表来进行对应的存储
一个字符集 必然对应的是一种码表 只有明确码表才能进行相互的转换
3.常见的码表
ASCLL码表 == >范围 0-127 包含的是西方国家的一些符号 或者是字符
所以的码表0-127的范围都是与ASCLL码表对应上的
GBK码表 == >使用GB2312 延伸的一种码表 主要包含中文(繁体) 日文 韩文的字符
Unicode码表== > 万国码表 包含所有国家通用的字符 范围就是字符的范围 0-65535 字符的范围
主要统一国际化进行管理
UTE-8== > 支持中文的码表 可以转换大量的中文汉字 现在市面进行数据交互传输的格式 都是使用
utf-8
一个中文 ==>三个字节 GBK => 一个中文 两个字节
三、字符串的编码解码
public class Test {
public static void main(String[] args) throws UnsupportedEncodingException {
String str ="中国";
byte [] b1 = str.getBytes();
System.out.println(Arrays.toString(b1));
byte [] b2 = str.getBytes("GBK");
System.out.println(Arrays.toString(b2));
byte [] b3 = str.getBytes("UTF-8");
System.out.println(Arrays.toString(b3));
String s1 = new String(b3,"UTF-8");
System.out.println(s1);
String s2 = new String(b3);
System.out.println(s2);
}
}
四、字符流-写
1.Writer 写入字符流的抽象类。子类必须实现的方法仅有 write(char[], int, int)、flush() 和
close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能
2.子类 FileWriter
(1)用来写入字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是可接受
的。
要自己指定这些值,可以先在 FileOutputStream 上构造一个 OutputStreamWriter
(2) FileWriter 用于写入字符流。要写入原始字节流,请考虑使用 FileOutputStream
3.常用的构造方法
4.常规的方法
public class Test01 {
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("3.txt");
fw.write(new char[]{'a','b','c'});
fw.write(new char[]{'d','e','f'},0,1);
fw.write(97);
fw.write("刘正武");
fw.write("付函",0,1);
fw.flush();
fw.close();
}
}
五、字符流-读
1.Reader 用于读取字符流的抽象类。子类必须实现的方法只有 read(char[], int, int) 和
close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能。
2.FileReader
用来读取字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是适当
的。要自己指定这些 值,可以先在 FileInputStream 上构造一个 InputStreamReader。
FileReader 用于读取字符流。要读取原始字节流,请考虑使用 FileInputStream。
3.常用的构造方法
4.常用的方法
5.代码 一个一个字符进行读取
Reader r = new FileReader("3.txt");
int leng =-1;
while ((leng=r.read()) !=-1) {
System.out.println((char) leng);
}
}
- 一次读取多个字符
Reader r = new FileReader("3.txt");
char[] ch = new char[1024];
int leng =-1;
while ((leng= r.read(ch)) !=-1){
System.out.println(new String(ch,0,leng));
}
六、字符流文件内容copy过程
注意点:字符流 是不能操作图片 以及音频 视频 因为 图片 存储的时候 没有对应任何的编码表,而字
符流在进行操作
需要依据编码表来进行转换 这样就可以导致图片打不开
package day19;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class Test05 {
public static void main(String[] args) {
FileReader fr =null;
FileWriter fw = null;
try {
fr = new FileReader("3.txt");
fw = new FileWriter("4.txt");
char [] ch =new char[1024];
int leng =-1;
while ((leng =fr.read(ch))!=-1){
fw.write(ch,0,leng);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(fw!=null){
fw.close();
}
if(fr!=null){
fr.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
七、转换流-读
1.InputStreamReader 是字节流通向字符流的桥梁
2.InputStreamReader 读的时候 可以设置其编码格式
3.为了达到最高效率,可要考虑在 BufferedReader 高效流
4.常用的构造方法
package day19;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class Test06 {
public static void main(String[] args) throws IOException {
InputStream is = new FileInputStream("E:\\admin\\1.txt");
//读取是使用编码utf-8, 单个字节读取中文也能正确读取,不会乱码
InputStreamReader isr = new InputStreamReader(is,"UTF-8");
int leng =-1;
while ((leng=isr.read())!=-1){
System.out.println((char)leng);
}
isr.close();
is.close();
}
}
八、转换流
1.OutputStreamWriter 是字符流通向字节流的桥梁
2.可使用指定的 charset 将要写入流中的字符编码成字节。
它使用的字符集可以由名称指定或显式给定,否则将接受平台默认的字符集
3.为了获得最高效率,可考虑将 OutputStreamWriter 包装到 BufferedWriter 中,以避免频繁调
用转换器
4.常用的构造方法
//OutputStream 表示输出字节流的所有类的超类
// FileOutputStream 文件输出流是用于将数据写入 File
//new 一个FileOutputStream对象时,会创建一个空的文件(存在就不创建),同时指向这个文件
//转换流OutputStreamWriter InputStreamReader 即是字节流转为字符流的工具类 转换器
// 写入时可以不用 String.getBytes()方法 直接用String
//但要指定编码格式,一般为utf-8
package day19;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
public class Test07 {
public static void main(String[] args) throws IOException {
OutputStream os = new FileOutputStream("7.txt");
OutputStreamWriter osw = new OutputStreamWriter(os,"UTF-8");
osw.write("顺哥666");
osw.flush();
osw.close();
}
}
九-字符的高效流-写
1.BufferedWriter 写的高效流
将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入
2.常用的构造方法
3.独有的方法
package day19;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
public class Test08 {
public static void main(String[] args) throws IOException {
Writer w = new FileWriter("9.txt");
BufferedWriter bw = new BufferedWriter(w);
bw.write("国足又又又输了");
bw.newLine();
bw.write("每天坚持吃海参");
bw.flush();
bw.close();
}
}
十、字符的高效流-读
1.BufferedReader 字符高效读
从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
可以指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值就足够大了
2.常用的构造方法
3.独有的方法
package day19;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
public class Test09 {
public static void main(String[] args) throws IOException {
Reader r = new FileReader("9.txt");
BufferedReader br = new BufferedReader(r);
String str =null;
//str=""; str是有地址值的,指向了内存空间,实例化了,输出内容为空白;
//str=null;str 是无地址值的,未指向内存空间,未实例化,输出内容为null;
while ((str=br.readLine())!=null){
System.out.println(str);
}
br.close();
r.close();
}
}
package day19;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class Test10 {
public static void main(String[] args) {
BufferedReader br = null;
BufferedWriter bw = null;
File file = new File("9.txt");
try {
if(!file.exists()){
file.createNewFile();
}
Reader r = new FileReader(file);
br = new BufferedReader(r);
//bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("10.txt"),"utf-8"));//转换流
bw = new BufferedWriter(new FileWriter("9.txt",true));//字符文件流
//第二个参数为ture,则从文件末尾加,不写默认false,直接清空重输
//bw没有第二个参数时,br 和bw 不能为同一文件夹,否则会清空文件夹且读不到数据 为什么?
List<String> list = new ArrayList<>();
String str =null;
while ((str=br.readLine())!=null){
list.add(str);
}
for (int i = list.size()-1; i >=0 ; i--) {
System.out.println(list.get(i));
bw.write(list.get(i));
bw.newLine();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(bw!=null){
bw.close();
}
if(br!=null){
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
十一、标准的输入流
1.InputStream in ==> System.in 标准”输入流 默认是关联键盘
public static void setIn(InputStream in) 可以用于改变其规则 可以用于来关联文件
2.代码
package day19;
import java.io.*;
public class Test11 {
public static void main(String[] args) throws IOException {
//读取单个字符
/*InputStream is = System.in;
System.out.println("请输入一个字符");
char leng = (char)is.read();
System.out.println(leng);*/
/*InputStream is2 = System.in;//Syetem.in 关联键盘输入
System.out.println("请输入数字");
int leng1 = is2.read();//ascll 码表
System.out.println(leng1);*/
//读取一行
/*InputStream is = System.in;
BufferedReader br = new BufferedReader(new InputStreamReader(is));
System.out.println("请输入一行");
String line = br.readLine();
System.out.println(line);*/
//关闭关联的规则
System.setIn(new FileInputStream("1.txt"));
//FileInputStream("File") 文件输入流
InputStream is = System.in;
//int leng = is.read();
int leng =-1;
while ((leng= is.read())!=-1)
System.out.println(leng);
}
}
标准的输出流
1.标准的输出流 PrintStream ps = System.out ==> 标准”输出流。 默认是关联控制台
可以改变其关联的规则 setOut(PrintStream out)
2. 提供很多重载的方法来打印各种基本数据类型 print(String s) println() write(int b)
3.代码
package day19;
import java.io.*;
public class Test12 {
public static void main(String[] args) throws FileNotFoundException {
PrintStream ps = System.out;
ps.println("您好");
ps.print(true);
ps.write(97);
ps.flush();
ps.close();
//改变其关联的规则 向文件中写入数据
/*System.setOut(new PrintStream("11.txt"));
PrintStream ps = System.out;
ps.write(97);
ps.print("海岛大亨");
ps.println(true);
ps.flush();
ps.close();*/
}
}
打印流
1.PrintStream PrintWriter 这两个都属于输出打印流 提供了一些答应的方法
writer()print()println()
2.PrintStream 得到这个对象
(1) 通过System.out 来获取
(2) 通过构造实例化对象
3.常用的构造方法
4.代码
package day19;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
public class Test13 {
public static void main(String[] args) throws FileNotFoundException {
PrintStream ps = new PrintStream(new FileOutputStream("12.txt"),true);
ps.print("向文件中写入");
ps.write(97);
ps.println("您好哈哈哈");
}
}
5.PrintWriter输出打印流 提供了一些答应的方法 writer()print()println()
6.通过构造实例化对象
7.常用的构造的方法
8.代码
public class Test01 {
public static void main(String[] args) throws FileNotFoundException {
PrintWriter pw = new PrintWriter(new FileOutputStream("14.txt"),true);
pw.print(30.4);
pw.write(97);
pw.println("dddd"); //遇到println 的方法只刷新一次
// pw.close();
}
}
序列化的概念
1.序列化 在文件中写入对象的时候 或者网络传输对象的时候必须进行序列化
2.序列化 序列化的机制 使用一个序列化的字节 来表示文件中对象的信息(属性 以及 方法)
3.序列化: 是将对象写入到文件 == > 这个过程称为序列化的过程 把对象进行流化 加快写的速度
4.反序列化 将文件中对象读取出来 == >这个过程就可以称为反序列化 加快读取的速度
5.对象序列化读的流 ObjectInputStream 对象序列化写的流 ObjectOutputStream
6.ObjectOutputStream
10.代码
package day19;
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Test14 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("15.txt"));
List<String> list = new ArrayList<>();
list.add("刘正武");
oos.writeObject(12);
oos.writeObject(new char[]{'a','b'});
oos.writeObject("您好");
oos.writeObject(list);
//开始读取
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("15.txt"));
Integer num = (Integer) ois.readObject();
char[] ch = (char[]) ois.readObject();
String s = (String) ois.readObject();
List<String> lis1 = (List<String>) ois.readObject();
System.out.println(num);
System.out.println(Arrays.toString(ch));
System.out.println(s);
System.out.println(lis1);
oos.close();
ois.close();
}
}
对象流操作自定义的对象
1.自定义的对象使用 对象流来进行读写操作 类必须实现这个接口 Serializable
2.出现这个问题 说明对象没有实现序列化接口
3.代码
学生类
注意代码public class Student implements Serializable 连接实现Serializable接口
package day19;
import java.io.Serializable;
public class Student implements Serializable {
private String sname;
private int sage;
public Student() {
}
public Student(String sname, int sage) {
this.sname = sname;
this.sage = sage;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public int getSage() {
return sage;
}
public void setSage(int sage) {
this.sage = sage;
}
@Override
public String toString() {
return "Student{" +
"sname='" + sname + '\'' +
", sage=" + sage +
'}';
}
}
测试类
package day19;
import java.io.*;
public class Test15 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
writerObj();
readObj();
}
//读的方法
public static void readObj() throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("16.txt"));
Student stu = (Student) ois.readObject();
System.out.println(stu);
}
// 写对象的方法
public static void writerObj() throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("16.txt"));
//实例化一个对象
Student stu = new Student();
stu.setSname("李四");
stu.setSage(18);
oos.writeObject(stu);
oos.close();
}
}
package day19;
import java.io.*;
public class Test16 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
writeObj();
readObj();
}
public static void readObj() throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("17.txt"));
Object obj =null;
while ((obj=ois.readObject()) != null){
Student stu = (Student)obj;
System.out.println(stu);
}
ois.close();
}
public static void writeObj() throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("17.txt"));
Student stu =new Student("顺哥一马当先",18);
Student stu1 = new Student("顺哥永远18",18);
Student stu2 = new Student("顺哥不怕困难",18);
Student stu3 = null;
oos.writeObject(stu);
oos.writeObject(stu1);
oos.writeObject(stu2);
oos.writeObject(stu3);
oos.close();
}
}
package day19;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class Test17 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
writeObj();
readObj();
}
public static void readObj() throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("18.txt"));
List<Student> list = (List<Student>) ois.readObject();
for (Student student : list) {
System.out.println(student);
}
ois.close();
}
public static void writeObj() throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("18.txt"));
Student stu =new Student("顺哥一马当先",18);
Student stu1 = new Student("顺哥永远18",18);
Student stu2 = new Student("顺哥不怕困难",18);
Student stu3 = new Student("顺哥灵光常常乍现",18);
List<Student> list = new ArrayList<>();
list.add(stu);
list.add(stu1);
list.add(stu2);
oos.writeObject(list);
oos.close();
}
}
IO流 总结
File 文件对象 可是文件夹或文件 new File() 不会在磁盘创建文件
file.mkdirs() 在磁盘创建文件夹
file.createNewFile() 在磁盘创建文件
file.listFiles() 返回文件夹子目录file对象 可通过new FilenameFilter() 重写方法 增加if 判断语句进行过滤
file对象里的.符号是转义字符 使用split()分割时 file.getName().split("\\.");
io 输出流 OutputStream 输入流 InputStream
记忆:出入 输出对应写入 入取 输入对应读取
输出是out 写入是write 输入时int 读取是read
记图片 intput 输入流 是磁盘数据给内存 output 输出流 内存数据传给磁盘
字节流
OutputStream 输出字节流的超类 抽象类 其实现类 FileOutputStream 会自动创建文件
对应的InputStram FileInputStream FileOutputStream fos = new FileOutputStream("1.txt");
FileOutputStream fos.writer() 以字节,字节数组写入 str.getBytes() write(字节数组,开始索引,个数) 换行 “\r\n”.getBytes()
对应的 fis.read() 以字节,字节数组读取 byte [] b = new byte[1024]; int leng=-1; while((leng=fis.read(b))!=-1) { String s = new String(b,0,leng);}
read() 和read(b) 区别
使用写入操作后 flush()一下;写入和读取操作结束后再按代码从下往上依次关闭
字节缓冲高效流 所有的高效流都是 加一个Buffered前缀词
底层是 在内存开辟一个专门的空间,缓冲数组区,内存和磁盘交互时,先让缓冲区和磁盘交互,缓冲区和磁盘交互的数据更多更快,写入时flush()一下存入缓冲区,在使用内存和缓冲区交互,减少内存和磁盘的多次交互。
BufferedInputStream 与BufferedOutputStream 没有读写的功能 只是对InputStream 与
OutputStream的封装 提供了一个缓冲区的数组 加快读写操作的速度,所以方法都是InputStream 与
OutputStream的方法
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File("E:\\a\\下载.jpg")));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("E:\\abc.jpg")));
字符流 = 字节流+ 编码表
java默认用UTF-8解码中文
utf-8 一个中文三个字节
GBK 一个中文 两个字节
Writer 输出字节流的超类 抽象类 其实现类 FileWriter 会自动创建文件
对应的Reader FileReader FileWriter fw = new FileWriter("1.txt"); Writer fw = new FileWriter("1.txt");
FileWriter fw.writer() 以字符,字符数组写入 字符串也用了字符数组 write(str) write(字符数组,开始索引,个数)
对应的 fis.read() 以字符,字符数组读取 char [] ch = new char[1024]; int leng=-1; while((leng=fis.read(ch))!=-1) { String s = new String(ch,0,leng);}
字符缓冲高效流 加Buffered前缀词 同字节高效流
BufferedWriter 和 BufferedReader
Writer w = new FileWriter("9.txt");
BufferedWriter bw = new BufferedWriter(w);
//BufferedWriter bw = new BufferedWriter(new FileWriter("9.txt"));
Reader r = new FileReader("9.txt");
BufferedReader br = new BufferedReader(r);
new BufferedWriter(w,ture);表示从后面添加写入,不清空原内容
其方法和字符流方法有所改变,有其独有的方法
br.readLine()返回字符串 读取一行内容
bw.newLine();换行写入
可用list 存储str
bw没有第二个参数时,br 和bw 不能为同一文件夹,否则会清空文件夹且读不到数据
String str =null;
while ((str=br.readLine())!=null){
System.out.println(str);
}
转换流
转换流也算字符流
InputStreamReader 和OutputStreamWriter
InputStream is = new FileInputStream("E:\\admin\\1.txt");
InputStreamReader isr = new InputStreamReader(is,"UTF-8");
//InputStreamReader isr = new InputStreamReader(new FileInputStream("E:\\admin\\1.txt"),"UTF-8");
OutputStreamWriter 同理
其底层还是 FileInputStream 即文件字节输入流 ,方法一样,不过其指定编码格式,不会中文乱码,可直接读写 中文字符串
字符高效流 也可以封装转换流 其方法用高效流的独有方法
BufferedWriter bw = null;
BufferedReader br = null;
bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("10.txt"),"utf-8"));
br = new BufferedReader(new InputStreamWriter(new FileInputStream("10.txt"),"utf-8"));
标准输入输出流 关联键盘和关联控制台
InputStrem 和 PrintStream
读取和写入
read()
方法writer()print()println()
InputStream is = System.in;
System.out.println("请输入一个字符");
char leng = (char)is.read();
System.out.println(leng);
//关闭联系
System.setIn(new FileInputStream("1.txt"));
InputStream is = System.in;
int leng =-1;
while ((leng= is.read())!=-1)
System.out.println(leng);
PrintStream ps = System.out;
ps.println("您好");
ps.print(true);
ps.write(97);
ps.flush();
ps.close();
//改变其关联的规则 向文件中写入数据
/*System.setOut(new PrintStream("11.txt"));
PrintStream ps = System.out;
ps.write(97);
ps.print("海岛大亨");
ps.println(true);
ps.flush();
ps.close();*/
打印流
PrintStream和PrintWriter 都是一样的 是写入
方法writer()print()println()
PrintStream ps = new PrintStream(new FileOutputStream("12.txt"),true);
PrintWriter pw = new PrintWriter(new FileOutputStream("14.txt"),true);
ps.print("向文件中写入");
ps.write(97);
ps.println("您好哈哈哈");
序列化 即对象输入输出流
ObjectInputStream 和 ObjectOutputStream
new ObjectInputStream(new FileInputStream(“17.txt”));
new ObjectOutputStream(new FileOutputStream(“17.txt”));
只能字节流
方法 readObject(); 返回Object类型 然后再自己强转回来
writeObject(Object); 常写stu,List< Student>
可用集合存储对象
学生类需要连接实现Serializable接口 重写toString()方法
一个一个写入读取学生对象,需要自定义写入一个null 对象作为结束标记
集合就不需要,推荐用集合
public static void readObj() throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("17.txt"));
Object obj =null;
while ((obj=ois.readObject()) != null){
Student stu = (Student)obj;
System.out.println(stu);
}
ois.close();
}
public static void writeObj() throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("17.txt"));
Student stu =new Student("顺哥一马当先",18);
Student stu1 = new Student("顺哥永远18",18);
Student stu2 = new Student("顺哥不怕困难",18);
Student stu3 = null;
oos.writeObject(stu);
oos.writeObject(stu1);
oos.writeObject(stu2);
oos.writeObject(stu3);
oos.close();
}
public static void readObj() throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("18.txt"));
List<Student> list = (List<Student>) ois.readObject();
for (Student student : list) {
System.out.println(student);
}
ois.close();
}
public static void writeObj() throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("18.txt"));
Student stu =new Student("顺哥一马当先",18);
Student stu1 = new Student("顺哥永远18",18);
Student stu2 = new Student("顺哥不怕困难",18);
Student stu3 = new Student("顺哥灵光常常乍现",18);
List<Student> list = new ArrayList<>();
list.add(stu);
list.add(stu1);
list.add(stu2);
oos.writeObject(list);
oos.close();
}