缓冲流:是Buffered开头的
缓冲流的优点? 内部自带数组,提高读写效率
字节缓冲流 字符缓冲流
输入流 BufferedInputStream BufferedReader
输出流 BufferedOutputStream BufferedWriter
BufferedInputStream:继承InputStream 读数据方式使用父类 int read() 从输入流读取数据的下一个字节。 int read(byte[] b) 从输入流中读取一些字节数,并将它们存储到缓冲器阵列 b 。 BufferedInputStream(InputStream in) 创建一个 BufferedInputStream并保存其参数,输入流 in供以后使用。
FileInputStream fis = new FileInputStream("路径/abc/bos.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
int ch;
while ((ch = bis.read()) != -1) {
System.out.println((char)ch);
}
bis.close();
BufferedOutputStream:继承OutputStream 写数据方法使用父类的: void write(int b) 将指定的字节写入此输出流。 void write(byte[] b) 将 b.length字节从指定的字节数组写入此输出流。 void write(byte[] b, int off, int len) 从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。 BufferedOutputStream的构造方法: BufferedOutputStream(OutputStream out) 创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
FileOutputStream fos = new FileOutputStream("路径/abc/bos.txt");
// BufferedOutputStream只是提数组供缓冲区(1024*8),真正操作文件的是fos.
BufferedOutputStream bos = new BufferedOutputStream(fos);
bos.write(97);
bos.close();
下列是四种复制文件的方式:字节流,字节数组,缓冲字节流,缓冲字节数组
使用四种方式复制 "day10_课堂代码/abc/xyz.flv" 到 "c:/MyFileTest/xyz?.flv"
讲解
四种方式复制:
基本流读取一个字节
基本流读取一个字节数组
缓冲流读取一个字节
缓冲流读取一个字节数组
小结
1.字节流哪四种复制文件的方式?
*/
public class Demo02 {
public static void main(String[] args) throws IOException {
long start = System.currentTimeMillis();
// copyWithByte(); // 81367
// copyWithByteArray(); // 68
// copyWithBufferedByte(); // 373
copyWithBufferedByteArray(); // 78
long end = System.currentTimeMillis();
System.out.println("消耗时间: " + (end - start));
}
// 基本流读取一个字节
public static void copyWithByte() throws IOException {
FileInputStream fis = new FileInputStream("day10_课堂代码/abc/xyz.flv");
FileOutputStream fos = new FileOutputStream("C:/MyFileTest/xyz1.flv");
int ch;
while ((ch = fis.read()) != -1) {
fos.write(ch);
}
fos.close();
fis.close();
}
// 基本流读取一个字节数组
public static void copyWithByteArray() throws IOException {
FileInputStream fis = new FileInputStream("day10_课堂代码/abc/xyz.flv");
FileOutputStream fos = new FileOutputStream("C:/MyFileTest/xyz2.flv");
byte[] buf = new byte[1024 * 8];
int len;
while ((len = fis.read(buf)) != -1) {
fos.write(buf, 0, len);
}
fos.close();
fis.close();
}
// 缓冲流读取一个字节
public static void copyWithBufferedByte() throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("day10_课堂代码/abc/xyz.flv"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("C:/MyFileTest/xyz3.flv"));
int ch;
while ((ch = bis.read()) != -1) {
bos.write(ch);
}
bos.close();
bis.close();
}
// 缓冲流读取一个字节数组
public static void copyWithBufferedByteArray() throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("day10_课堂代码/abc/xyz.flv"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("C:/MyFileTest/xyz4.flv"));
byte[] buf = new byte[1024 * 8];
int len;
while ((len = bis.read(buf)) != -1) {
bos.write(buf, 0, len);
}
bos.close();
bis.close();
}
}
字符缓冲流如下例
BufferedWriter bw = new BufferedWriter(new FileWriter("路径/abc/bis.txt")); bw.write('我'); char[] chs = {'喜', '欢', '你'}; bw.write(chs); // bw.write("\r\n"); bw.newLine(); bw.write("要乱来!"); bw.close();
字符输入缓冲流BufferedReader继承Reader:
读取数据的方式使用父类Reader的:
int read() 读一个字符
int read(char[] cbuf) 将字符读入数组。
BufferedReader(Reader in) 创建使用默认大小的输入缓冲区的缓冲字符输入流。
特有方法:
String readLine() 读一行文字。
例子:
BufferedReader br = new BufferedReader(new FileReader("day10_课堂代码/abc/bis.txt"));
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
符流读字符乱码问题:其实是因为写入和读取使用了不同的码表导致的
,有的是UTF-8,有的是GBK,Idea默认用的是UTF-8,文本文档用的是GBK
InputStreamReader是从字节流到字符流的桥梁:它读取字节,并使用指定的charset将其解码为字符。
构造方法:
InputStreamReader(InputStream in) 创建一个使用默认字符集的InputStreamReader。
InputStreamReader(InputStream in, String charsetName) 创建一个使用命名字符集的InputStreamReader。
charsetName: gbk/utf8 (大小写均可)
InputStreamReader isr = new InputStreamReader(new FileInputStream("路径/abc/china_gbk.txt"), "GBK");
int ch;
while ((ch = isr.read()) != -1) {
System.out.println((char)ch);
}
isr.close();
OutputStreamWriter是从字符流到字节流的桥梁:使用指定的charset将写入的字符编码为字节。 构造方法: OutputStreamWriter(OutputStream out) 创建一个使用默认字符编码的OutputStreamWriter。 OutputStreamWriter(OutputStream out, String charsetName) 创建一个使用命名字符集的OutputStreamWriter。
1.InputStreamReader类的好处,OutputStreamWriter类的好处? FileReader和FileWriter使用默认编码,无法更改 InputStreamReader和OutputStreamWriter即可以使用默认编码,也可以使用指定编码 2.操作字符时如何选择流? 如果不需要指定编码,使用 FileReader和FileWriter 如果需要指定编码,使用 InputStreamReader和OutputStreamWriter
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("day10_课堂代码/abc/osw2.txt"), "gbk");
osw.write("你好");
osw.close();
GBK编码的文本文件,转换为UTF-8编码的文本文件例子
步骤
1,使用GBK编码读取GBK编码的文件
2.使用UTF-8编码将内容写入到UTF-8编码的文件
InputStreamReader isr = new InputStreamReader(new FileInputStream("day10_课堂代码/abc/china_gbk.txt"), "gbk");
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("day10_课堂代码/abc/china_utf8666.txt"), "utf-8");
char[] chs = new char[1024];
int len;
// 使用GBK读取
while ((len = isr.read(chs)) != -1) {
// 使用UTF-8写出
osw.write(chs, 0, len);
}
osw.close();
isr.close();
序列化和反序列化
什么是序列化? 将对象写入文件 什么是反序列化? 将文件内容读入成程序的对象 相关的类? ObjectOutputStream将Java对象写入文件中 ObjectInputStream将文件中内容读入成程序的对象
序列化的类要实现 Serializable 接口
学生类实现了Serializable接口
序列化
Student s1 = new Student("凤姐", 18);
// 将对象写入文件
// ObjectOutputStream(OutputStream out)
// 特有方法:void writeObject(Object obj) 将指定的对象写入ObjectOutputStream。
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("day10_课堂代码/abc/students.txt"));
oos.writeObject(s1); // 将s1对象写入文件
oos.close();
反序列化 路径相同上下
// ObjectInputStream(InputStream in)
// 特有方法:Object readObject() 从ObjectInputStream读取一个对象。
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("day10_课堂代码/abc/students.txt"));
// Object obj = ois.readObject();
Student obj = (Student) ois.readObject();
System.out.println(obj);
ois.close();
序列化一个集合,代码如下
当序列化集合时,集合中的内容也必须实现Serializable
*/
public class Demo11 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
save();
load();
}
public static void load() throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("day10_课堂代码/abc/list.txt"));
ArrayList<Student> obj = (ArrayList<Student>) ois.readObject();
for (Student student : obj) {
System.out.println(student);
}
ois.close();
}
public static void save() throws IOException {
ArrayList<Student> stus = new ArrayList<>();
stus.add(new Student("凤姐", 18));
stus.add(new Student("如花", 19));
stus.add(new Student("石榴姐", 20));
stus.add(new Student("包租婆", 30));
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("day10_课堂代码/abc/list.txt"));
oos.writeObject(stus);
oos.close();
}
}
打印流
打印流分类:
PrintStream;
PrintWriter;
打印流的特点:
1.只有输出方向,没有输入方向
2.原样输出(写什么就是什么)
PrintStream类的使用:
构造方法:
PrintStream(String fileName)
PrintStream(File file)
PrintStream(OutputStream out)
普通方法:
print(各种类型)
println(各种类型)
小结:
1.打印流的特点?
1.只有输出方向,没有输入方向
2.原样输出(写什么就是什么)
2.PrintStream类常用哪2个方法?
print(各种类型)
println(各种类型)
*/
public class Demo12 {
public static void main(String[] args) throws FileNotFoundException {
// test01();
// out是静态的成员变量
System.out.println("hello world");
System.setOut(new PrintStream("day10_课堂代码/abc/sos.txt"));
System.out.println("大家好!");
System.out.println("才是真的好");
System.out.println("就是要乱来");
}
public static void test01() throws FileNotFoundException {
// PrintStream(String fileName)
PrintStream ps = new PrintStream("day10_课堂代码/abc/ps.txt");
ps.print(97);
ps.print(3.14);
ps.print('好');
ps.print("飞机");
ps.println(666);
ps.println(3.14);
ps.println('打');
ps.println("灰机");
ps.close();
}