Java 基础进阶篇(十五):IO 流总结(全网最全面)

阅读: 评论:0

Java 基础进阶篇(十五):IO 流总结(全网最全面)

Java 基础进阶篇(十五):IO 流总结(全网最全面)

文章目录

  • 前置内容:字符集
  • 一、IO 流概述
  • 二、字节流
    • 2.1 文件字节输入流 FileInputStream
      • 2.1.1 案例:每次读取一个字节
      • 2.1.2 案例:每次读取一个字节数组
      • 2.1.3 案例:读取文件的全部字节
    • 2.2 文件字节输出流 FileOutputStream
    • 2.3 文件拷贝
    • 2.4 资源释放的方式
      • 2.4.1 try-catch-finally
      • 2.4.2 try-with-resource
  • 三、字符流
    • 3.1 文件字符输入流 FileReader
    • 3.2 文件字符输出流 FileWriter
  • 四、缓冲流
    • 4.1 字节缓冲流
      • 4.1.1 字节缓冲输入流 BufferedInputStream
      • 4.1.2 字节缓冲输出流 BufferedOutputStream
    • 4.2 字符缓冲流
      • 4.2.1 字符缓冲输入流 BufferedReader
      • 4.2.2 字符缓冲输出流 BufferedWritter
  • 五、转换流
    • 5.1 字符输入转换流 InputStreamReader
    • 5.2 字符输出转换流 OutputStreamWrite
  • 六、序列化流
    • 6.1 对象序列化与反序列化
    • 6.2 对象字节输出流 ObjectOutputStream
    • 6.3 对象字节输入流 ObjectInputStream
  • 七、打印流
    • 7.1 PrintStream
    • 7.2 PrintWriter
    • 7.3 PrintStream 和 PrintWriter 的区别
  • 补充:Commons-IO 框架


前置内容:字符集

字符集(Character Set)是多个字符的集合,字符集种类较多,每个字符集包含的字符个数不同。

常见的字符集有:ASCII、GBK、Unicode(UTF-8)字符集等。

  • ASCII 字符集:包括了数字、英文、符号。
    ASCII 字符集中一个字符存储 1 个字节,一个字节是 8 位,总共可以表示 128 个字符信息,对于表示英文、数字来说是够用的。

  • GBK 字符集:是中国的码表,包含了几万个汉字等字符
    GBK 字符中一个中文字符一般以 2 个字节的形式存储,同时兼容 ASCII 编码表

  • Unicode 字符集 :又叫统一码、万国码,其容纳了世界上大多数国家的常见文字和字符,是计算机科学领域里的一项业界标准。
    UTF-8 是 Unicode 字符集的一种常见编码方式,用于将数字转换成二进制。
    UTF-8 编码后一个中文一般以 3 个字节的形式存储,同时兼容 ASCII 编码表

中文存储和展示流程解析:

注意:

① 英文和数字不会乱码;
② 英文和数字等在任何国家的字符集中都占 1 个字节;
③ 字符解码时使用的字符集和编码时使用的字符集必须一致,否则会出现中文乱码;


字符集的编码、解码操作:

String 编码:

String 解码:

举例:

public class Test {public static void main(String[] args) throws Exception {// 1、编码:把文字转换成字节(使用指定的编码)String name = "abc我爱你中国";byte[] bytes = Bytes(); // 以当前代码默认字符集进行编码 (UTF-8)//byte[] bytes = Bytes("GBK"); // 指定编码System.out.println(bytes.length); // 18 abc占三个字节,5个汉字各占三个字节,一共 18System.out.String(bytes)); // [97, 98, 99, -26, -120, -111, -25, -120, -79, -28, -67, -96, -28, -72, -83, -27, -101, -67]// 2、解码:把字节转换成对应的中文形式(编码前 和 编码后的字符集必须一致,否则乱码 )String rs = new String(bytes); // 默认的UTF-8// String rs = new String(bytes, "GBK"); // 指定GBK解码System.out.println(rs); // abc我爱你中国}
}

一、IO 流概述

I 表示 intput,负责读,把硬盘文件中的数据读入到内存的过程,称之输入。
O 表示 output,负责写,把内存中的数据写出到硬盘文件的过程,称之输出。

IO流的分类:按照流的方向分为输入流与输出流,若按照流中数据的最小单位可分为字节流与字符流。


IO 流的四大类:

字节输入流: 以内存为基准,来自磁盘文件/网络中的数据 以字节的形式读入到内存中去
字节输出流: 以内存为基准,把内存中的数据 以字节写出到磁盘文件或者网络中去
字符输入流: 以内存为基准,来自磁盘文件/网络中的数据 以字符的形式读入到内存中去
字符输出流: 以内存为基准,把内存中的数据 以字符写出到磁盘文件或者网络介质中去

IO 流的体系如下:


二、字节流

2.1 文件字节输入流 FileInputStream

以内存为基准,来自磁盘文件/网络中的数据 以字节的形式读入到内存 中去。

构造方法:

常用方法:


2.1.1 案例:每次读取一个字节

示例:

public class FileInputStreamDemo01 {public static void main(String[] args) throws Exception {// 1、创建一个文件字节输入流管道与源文件接通。// InputStream is = new FileInputStream(new File("day09-oop/"));// ab3// 简化写法InputStream is = new FileInputStream("day09-oop/");// 2、读取一个字节返回 (每次读取一滴水)//int b1 = is.read();System.out.println((ad()); // aint b2 = is.read();System.out.println((char)b2); // bint b3 = is.read();System.out.println((char)b3); // 3int b4 = is.read(); // 读取完毕返回-1System.out.println(b4); // -1}
}

上文案例的循环改进版本:

public class FileInputStreamDemo01 {public static void main(String[] args) throws Exception {// 1、创建一个文件字节输入流管道与源文件接通。InputStream is = new FileInputStream("day09-oop/");// ab3// 2、使用循环改进int b;while (( b = is.read() ) != -1){System.out.print((char) b);}}
}

问题分析:由于中文字符占3个字节,每次读取一个字符会出现乱码问题。


2.1.2 案例:每次读取一个字节数组

示例2: 每次读取一个字节数组(可以理解为一桶水)

public class FileInputStreamDemo03 {public static void main(String[] args) throws Exception {// 1、创建一个文件字节输入流管道与源文件接通InputStream is = new FileInputStream("day09-oop/"); // abcdefgh// 2、定义一个字节数组,用于读取字节数组byte[] buffer = new byte[3]; // 3Bint len1 = is.read(buffer);System.out.println("读取了几个字节:" + len1); // 3String rs1 = new String(buffer);System.out.println(rs1); // abcint len2 = is.read(buffer);System.out.println("读取了几个字节:" + len2); // 3String rs2 = new String(buffer);System.out.println(rs2); // defint len3 = is.read(buffer);System.out.println("读取了几个字节:" + len3); // 2// 读取多少倒出多少String rs3 = new String(buffer,0 ,len3);// ghString rs4 = new String(buffer); // ghfSystem.out.println(rs3);int len4 = is.read(buffer);System.out.println(len4); // 读取完毕返回-1}
}

问题分析1:为什么上文案例当读到 “第三桶水” 的时候,桶里面的水不是 gh,而是 ghf

int len3 = is.read(buffer);
System.out.println("读取了几个字节:" + len3); // 2
// 读取多少倒出多少
String rs3 = new String(buffer,0 ,len2);// gh
String rs4 = new String(buffer); // ghf

原因在于:当读完 “第二桶水” 的时候,字节数组 buffer 中装有的水是 def,当继续从读取的时候,由于只有前两滴水可被读到桶中,因此最终桶里的水只有 ghf


上文案例的循环改进版本:

public class FileInputStreamDemo04 {public static void main(String[] args) throws Exception {// 1、创建一个文件字节输入流管道与源文件接通InputStream is = new FileInputStream("day09-oop/"); // abcdefgh// 2、循环改进byte[] buffer = new byte[3];int len; // 记录每次读取的字节数。while ((len = is.read(buffer)) != -1) {// 读取多少倒出多少System.out.print(new String(buffer, 0 , len));}}
}

问题分析2:读取中文字符输出无法避免乱码问题。

例:读取内容为 ab巴s啦啦c 时,每次读取三个字节,会出现乱码问题。


2.1.3 案例:读取文件的全部字节

方式一: 定义一个字节数组与文件的大小一样大,然后使用读取字节数组的方法,一次性读取完成。

方式二: 字节输入流 InputStream 提供了如下 API 可以直接把文件的全部数据读取到一个字节数组中。

public class FileInputStreamDemo05 {public static void main(String[] args) throws Exception {// 1、创建一个文件字节输入流管道与源文件接通File f = new File("day09-oop/");InputStream is = new FileInputStream("day09-oop/");// 2、定义一个字节数组与文件的大小刚刚一样大。// byte[] buffer = new byte[(int) f.length()];// int len = is.read(buffer);// System.out.println("读取了多少个字节:" + len);// System.out.println("文件大小:" + f.length());// System.out.println(new String(buffer));// 读取全部字节数组byte[] buffer = is.readAllBytes();System.out.println(new String(buffer));}
}

问题分析:不会有中文乱码,但如果文件过大,字节数组可能引起内存溢出


2.2 文件字节输出流 FileOutputStream

以内存为基准,把内存中的数据 以字节写出到磁盘文件或者网络中去

构造方法:

常用方法:

流的刷新与关闭:

示例:

public class OutputStreamDemo01 {public static void main(String[] args) throws Exception {// 1、创建一个文件字节输出流管道与目标文件接通// OutputStream os = new FileOutputStream("day09-oop/" , true); // 追加数据管道OutputStream os = new FileOutputStream("day09-oop/"); // 先清空之前的数据,写新数据进入// 2、写数据出去// a.public void write(int a):写一个字节出去os.write('a'); // 自动转换成整型os.write(98);os.write("rn".getBytes()); // 添加换行,win和其他系统都支持换行// os.write('徐'); // [ooo]// b.public void write(byte[] buffer):写一个字节数组出去。byte[] buffer = {'a' , 97, 98, 99};os.write(buffer);os.write("rn".getBytes()); // 添加换行byte[] buffer2 = "我是中国人".getBytes();// byte[] buffer2 = "我是中国人".getBytes("GBK");os.write(buffer2);os.write("rn".getBytes());// c. public void write(byte[] buffer , int pos , int len):写一个字节数组的一部分出去。byte[] buffer3 = {'a',97, 98, 99};os.write(buffer3, 0 , 3);// 左闭右开,写前三个字符os.write("rn".getBytes());// os.flush(); // 写数据必须,刷新数据 可以继续使用流os.close(); // 释放资源,包含了刷新的!关闭后流不可以使用流对象}
}

2.3 文件拷贝

思路:

① 根据数据源创建字节输入流对象。
② 根据目的地创建字节输出流对象。
③ 定义一个字节数组进行数据的转移。
④ 释放资源。

实现:

public class CopyDemo {public static void main(String[] args) {try {// 1、创建一个字节输入流管道与原视频接通InputStream is = new FileInputStream("day09-oop/");// 2、创建一个字节输出流管道与目标文件接通OutputStream os = new FileOutputStream("day09-oop/");// 3、定义一个字节数组转移数据byte[] buffer = new byte[1024];int len; // 记录每次读取的字节数。while ((len = is.read(buffer)) != -1){os.write(buffer, 0 , len);}// 4、关闭流。os.close();is.close();} catch (Exception e){e.printStackTrace();}}
}

任何文件的底层都是字节,只要前后文件格式、编码一致没有任何问题,字节流可以完成一切文件数据的拷贝。

总结:字节流适合做文件数据的拷贝,但不适合做中文数据的输出


2.4 资源释放的方式

2.4.1 try-catch-finally

finally: 放在 try-catch 后面的,无论是正常执行还是异常执行代码,最后一定要执行,除非 JVM 退出。

作用:一般用于进行最后的资源释放操作(专业做法)


2.4.2 try-with-resource

上文的资源虽然可行,但是释放资源的代码过于繁琐,如下文:

finally{...} 中判断是否为空,是因为有可能在得到流对象之前出现了异常的情况;
finally{...} 中再次 try catch 是因为系统认为可能在上文 try 未结束时已经关闭了流。

JDK 7 和 JDK 9 中都简化了资源释放操作:


JDK7 以及 JDK9 的改进方案中只能放置资源对象,否则报错。(注:资源都是实现了Closeable/AutoCloseable 接口的类对象)

如:

public abstract class InputStream implements Closeable {...}
public abstract class OutputStream implements Closeable, Flushable{...} 

示例1: JDK7 做法

public class TryCatchResourceDemo2 {public static void main(String[] args) {try (// 这里面只能放置资源对象,用完会自动关闭:自动调用资源对象的close方法关闭资源// 即使出现异常也会做关闭操作// 1、创建一个字节输入流管道与原视频接通InputStream is = new FileInputStream("day09-oop/");// 2、创建一个字节输出流管道与目标文件接通OutputStream os = new FileOutputStream("day09-oop/");// int age = 23; //报错,这里只能放资源MyConnection connection = new MyConnection(); // 模拟资源对象,最终会自动调用资源的close方法) {              // 3、定义一个字节数组转移数据byte[] buffer = new byte[1024];int len; // 记录每次读取的字节数。while ((len = is.read(buffer)) != -1){os.write(buffer, 0 , len);}System.out.println("复制完成了!");} catch (Exception e){e.printStackTrace();}}
}class MyConnection implements AutoCloseable{@Overridepublic void close() throws IOException {System.out.println("连接资源被成功释放了!");}
}

示例2: JDK9 做法

public class TryCatchResourceDemo3 {public static void main(String[] args) throws Exception {// 这里面只能放置资源对象,用完会自动关闭:自动调用资源对象的close方法关闭资源(即使出现异常也会做关闭操作)// 1、创建一个字节输入流管道与原视频接通InputStream is = new FileInputStream("day09-oop/");// 2、创建一个字节输出流管道与目标文件接通OutputStream os = new FileOutputStream("day09-oop/");MyConn conn = new MyConn(); // 最终会自动调用资源的close方法try ( is; os; conn ) {// 3、定义一个字节数组转移数据byte[] buffer = new byte[1024];int len; // 记录每次读取的字节数。while ((len = is.read(buffer)) != -1){os.write(buffer, 0 , len);}System.out.println("复制完成了!");} catch (Exception e){e.printStackTrace();}}
}
class MyConn implements AutoCloseable{@Overridepublic void close() throws IOException {System.out.println("连接资源被成功释放了~~~");}
}

三、字符流

字节流适合做文件拷贝,但是读取中文会出现乱码或者内存溢出。

字符流则可以完全解决这个问题,其把中文和英文数字都当成一个字符来处理。

3.1 文件字符输入流 FileReader

以内存为基准,来自磁盘文件/网络中的数据 以字符的形式读入到内存中去

构造器:

常用方法:

示例1: 每次读取一个字符

public class FileReaderDemo01 {public static void main(String[] args) throws Exception {// 1. 创建一个字符输入流与源文件接通Reader fr = new FileReader("day09-oop/");// 2. 读取一个字符,若没有可读字符返回-1/*int code = fr.read();System.out.println((char)code); // 单个中文一个字符int code1 = fr.read();System.out.println((char)code1);*/// 循环读取int code;while((code = fr.read()) != -1){System.out.print((char)code);}}
}

注:如果代码文件编码一致,读取中文字符不会出现乱码;读取性能较慢

示例2: 每次读取一个字符数组

public class FileReaderDemo02 {public static void main(String[] args) throws Exception {// 1. 创建一个字符输入流与源文件接通Reader fr = new FileReader("day09-oop/");// 2. 用循环,每次读取一个字符数组的数据char[] buffer = new char[1024]; // 1K 字符int len;while((len = fr.read(buffer)) != -1){String rs = new String(buffer, 0, len); // 解码并输出System.out.print(rs);}}
}

注:读取的性能得到了提升;读取中文字符输出不会乱码


3.2 文件字符输出流 FileWriter

以内存为基准,把内存中的数据 以字符写出到磁盘文件或者网络介质中去

构造器:

常用方法:

流的关闭与刷新:

示例:

public class FileWriterDemo03 {public static void main(String[] args) throws Exception {// 1、创建一个字符输出流管道与目标文件接通Writer fw = new FileWriter("day09-oop/"); // 覆盖管道,每次启动都会清空文件之前的数据// Writer fw = new FileWriter("day09-oop/", true); // 追加数据// a.public void write(int c):写一个字符出去fw.write('c');fw.write(98);fw.write('爱');// b.public void write(String c)写一个字符串出去fw.write("我是中国人");fw.write("rn");// c.public void write(char[] buffer):写一个字符数组出去char[] chars = "我是中国人".toCharArray();fw.write(chars);// d.public void write(String c ,int pos ,int len):写字符串的一部分出去fw.write("我是中国人", 0, 3);// e.public void write(char[] buffer ,int pos ,int len):写字符数组的一部分出去fw.write("我是中国人".toCharArray(), 0, 3);// fw.flush(); // 刷新后流可以继续使用fw.close(); // 关闭包含刷线,关闭后流不能使用}
}

四、缓冲流

缓冲流也称为高效流、或者高级流。之前学习的字节流、字符流可以称为原始流。

作用:缓冲流自带 8KB 缓冲区、可以提高原始字节流、字符流读写数据的性能

4.1 字节缓冲流

字节缓冲流性能优化原理:
字节缓冲输入流自带了 8KB 缓冲池,以后我们直接从缓冲池读取数据,所以性能较好。
字节缓冲输出流自带了 8KB 缓冲池,数据就直接写入到缓冲池中去,写数据性能提高了。

4.1.1 字节缓冲输入流 BufferedInputStream

字节缓冲输入流:BufferedInputStream,提高字节输入流读取数据的性能。

4.1.2 字节缓冲输出流 BufferedOutputStream

字节缓冲输出流:BufferedOutputStream,提高字节输出流读取数据的性能。

构造方法:

示例:

public class ByteBufferDemo {public static void main(String[] args) {try (// 这里面只能放置资源对象,用完会自动关闭:自动调用资源对象的close方法关闭资源(即使出现异常也会做关闭操作)// 1、创建一个字节输入流管道与原视频接通InputStream is = new FileInputStream("day10-oop/");// a.把原始的字节输入流包装成高级的缓冲字节输入流InputStream bis = new BufferedInputStream(is); // 多态// 2、创建一个字节输出流管道与目标文件接通OutputStream os = new FileOutputStream("day10-oop/");// b.把字节输出流管道包装成高级的缓冲字节输出流管道OutputStream bos = new BufferedOutputStream(os);) {// 3、定义一个字节数组转移数据byte[] buffer = new byte[1024];int len; // 记录每次读取的字节数。while ((len = ad(buffer)) != -1){bos.write(buffer, 0 , len);}System.out.println("复制完成了!");} catch (Exception e){e.printStackTrace();}}
}

4.2 字符缓冲流

4.2.1 字符缓冲输入流 BufferedReader

字符缓冲输入流:BufferedReader,可提高字符输入流读取数据的性能,除此之外多了按照行读取数据的功能

构造器:

独有方法:

示例1:

public class BufferedReaderDemo1 {public static void main(String[] args) {try(// 1、创建一个文件字符输入流与源文件接通。Reader fr = new FileReader("day10-oop\src\");// a、把低级的字符输入流包装成高级的缓冲字符输入流。BufferedReader br = new BufferedReader(fr); // 多态下调用子类方法,只能强转或不用多态) {// 2、用循环,每次读取一个字符数组的数据。  1024 + 1024 + 8char[] buffer = new char[1024]; // 1K字符int len;while ((len = br.read(buffer)) != -1) {String rs = new String(buffer, 0, len);System.out.print(rs);}} catch (Exception e) {e.printStackTrace();}}
}

示例2:

public class BufferedReaderDemo2 {public static void main(String[] args) {try(// 1、创建一个文件字符输入流与源文件接通。Reader fr = new FileReader("day10-oop\src\");// a、把低级的字符输入流包装成高级的缓冲字符输入流。BufferedReader br = new BufferedReader(fr); // 多态下调用子类方法,只能强转或不用多态) {// 2、用循环,每次读取一行数据。 String line;while ((line = br.readLine()) != null){System.out.println(line);}} catch (Exception e) {e.printStackTrace();}}
}

4.2.2 字符缓冲输出流 BufferedWritter

字符缓冲输出流:BufferedWritter,可提高字符输出流写取数据的性能,除此之外多了换行功能

构造器:

独有方法:

注:特性是由原始管道决定。(如:若想追加数据,在原始管道中使用追加管道数据的构造方法)

示例:

public class BufferedWriterDemo3 {public static void main(String[] args) throws Exception {// 1、创建一个字符输出流管道与目标文件接通// Writer fw = new FileWriter("day10-oop\src\"); // 覆盖管道,每次启动都会清空文件之前的数据Writer fw = new FileWriter("day10-oop\src\", true); // 追加数据BufferedWriter bw = new BufferedWriter(fw); // 特性是由原始管道决定,因此若想追加数据,也是设置上一行代码// a.public void write(int c):写一个字符出去bw.write(98);bw.write('a');bw.write('徐');bw.newLine(); // bw.write("rn"); // 换行// b.public void write(String c)写一个字符串出去bw.write("abc我是中国人");bw.newLine(); // bw.write("rn"); // 换行// c.public void write(char[] buffer):写一个字符数组出去char[] chars = "abc我是中国人".toCharArray();bw.write(chars);bw.newLine(); // bw.write("rn"); // 换行// d.public void write(String c ,int pos ,int len):写字符串的一部分出去bw.write("abc我是中国人", 0, 5);bw.newLine(); // bw.write("rn"); // 换行// e.public void write(char[] buffer ,int pos ,int len):写字符数组的一部分出去bw.write(chars, 3, 5);bw.newLine(); // bw.write("rn"); // 换行// fw.flush();// 刷新后流可以继续使用bw.close(); // 关闭包含刷新,关闭后流不能使用}
}

五、转换流

上文在使用字符流读取中文的时候,只有在文件和代码的编码一致才不会乱码,但编码不一致会出现乱码,而转换流可解决上述问题。

5.1 字符输入转换流 InputStreamReader

字符输入转换流:InputStreamReader,可以把原始的字节流按照指定编码转换成字符输入流

构造器:

示例:

public class InputStreamReaderDemo01 {public static void main(String[] args) throws Exception {// 1、提取GBK文件的原始字节流。InputStream is = new FileInputStream("day10-oop\src\");// 2、把原始字节流转换成字符输入流// Reader isr = new InputStreamReader(is); // 默认以UTF-8的方式转换成字符流。 还是会乱码的  跟直接使用FileReader是一样的Reader isr = new InputStreamReader(is , "GBK"); // 以指定的GBK编码转换成字符输入流  完美的解决了乱码问题// 3、把低级的字符输入流包装成高级的缓冲字符输入流。BufferedReader br = new BufferedReader(isr);String line;while ((line = br.readLine()) != null){System.out.println(line); // 正常打印}}
}

5.2 字符输出转换流 OutputStreamWrite

字符输出转换流:OutputStreamWriter,可以把字节输出流按照指定编码转换成字符输出流

构造器:

示例:

public class OutputStreamWriterDemo02 {public static void main(String[] args) throws Exception {// 1、定义一个字节输出流OutputStream os = new FileOutputStream("day10-oop\src\");// 2、把原始的字节输出流 转换成 字符输出流// Writer osw = new OutputStreamWriter(os); // 以默认的UTF-8写字符出去 跟直接写FileWriter一样Writer osw = new OutputStreamWriter(os , "GBK"); // 指定GBK的方式写字符出去// 3、把低级的字符输出流包装成高级的缓冲字符输出流。BufferedWriter bw = new BufferedWriter(osw);bw.write("我爱中国1~~");bw.write("我爱中国2~~");bw.write("我爱中国3~~");bw.close();}
}

六、序列化流

6.1 对象序列化与反序列化

对象序列化: 以内存为基准,把内存中的对象存储到磁盘文件中去。使用到的流是对象字节输出流:ObjectOutputStream。

对象反序列化: 以内存为基准,把存储到磁盘文件中去的对象数据恢复成内存中的对象。使用到的流是对象字节输入流:ObjectInputStream


6.2 对象字节输出流 ObjectOutputStream

构造器:

序列化方法:

注意:

① 序列化对象必须实现序列化接口。
② transient 修饰的成员变量不参与序列化。

示例:

public class Student implements Serializable {// 申明序列化的版本号码// 序列化的版本号与反序列化的版本号必须一致才不会出错!private static final long serialVersionUID = 1;private String name;private String loginName;// transient 修饰的成员变量不参与序列化了private transient String passWord;private int age ;...
}
public class ObjectOutputStreamDemo1 {public static void main(String[] args) throws Exception {// 1、创建学生对象Student s = new Student("张三", "zhangsan", "1314520", 21);// 2、对象序列化:使用对象字节输出流包装字节输出流管道ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("day10-oop/"));// 3、直接调用序列化方法oos.writeObject(s);// 4、释放资源oos.close();System.out.println("序列化完成了~~");}
}

6.3 对象字节输入流 ObjectInputStream

构造器:

序列化方法:

示例:

public class ObjectInputStreamDemo2 {public static void main(String[] args) throws Exception {// 1、创建对象字节输入流管道包装低级的字节输入流管道ObjectInputStream is = new ObjectInputStream(new FileInputStream("day10-oop/"));// 2、调用对象字节输入流的反序列化方法Student stu = (Student) is.readObject();System.out.println(stu );}
}

七、打印流

打印流可以实现方便、高效的打印数据到文件中去。打印流一般是指:PrintStream、PrintWriter两个类。

可以实现打印什么数据就是什么数据,如:打印整数 97 写出去就是 97,打印 boolean 的 true,写出去就是 true。

7.1 PrintStream

构造器:

常用方法:


7.2 PrintWriter

构造器:

常用方法:

示例1:

public class PrintDemo1 {public static void main(String[] args) throws Exception {// 1、创建一个打印流对象// PrintStream ps = new PrintStream(new FileOutputStream("day10-oop/"));PrintStream ps = new PrintStream(new FileOutputStream("day10-oop/" , true)); // 追加数据,在低级管道后面加True// PrintStream ps = new PrintStream("day10-oop/" );// PrintWriter pw = new PrintWriter("day10-oop/"); // 打印功能上与PrintStream的使用没有区别ps.println(97);ps.println('a');ps.println(23.3);ps.println(true);ps.println("我是打印流输出的,我是啥就打印啥");ps.close();}
}

示例2: 改变输出语句的位置

public class PrintDemo2 {public static void main(String[] args) throws Exception {System.out.println("锦瑟无端五十弦");System.out.println("一弦一柱思华年"); // out 是 PrintStream 对象// 改变输出语句的位置(重定向)PrintStream ps = new PrintStream("day10-oop/");System.setOut(ps); // 把系统打印流改成我们自己的打印流System.out.println("庄生晓梦迷蝴蝶");System.out.println("望帝春心托杜鹃");}
}

7.3 PrintStream 和 PrintWriter 的区别

  • 打印数据功能上是一模一样的,都是使用方便,性能高效(核心优势)。
  • PrintStream 继承自字节输出流 OutputStream,支持写字节数据的方法。
  • PrintWriter 继承自字符输出流 Writer,支持写字符数据出去。

补充:Commons-IO 框架

Commons-IO 是 apache 开源基金组织提供的一组有关 IO 操作的类库,可以提高 IO 功能开发的效率。
Commons-IO 工具包提供了很多有关 IO 操作的类。有两个主要的类 FileUtils, IOUtils。

FileUtils 主要有如下方法:

示例:

/**包的功能描述见下表:| 包                                  | 功能描述                                     || ----------------------------------- | :------------------------------------------- || org.apachemons.io               | 有关Streams、Readers、Writers、Files的工具类 || org.apachemons.io.input         | 输入流相关的实现类,包含Reader和InputStream  || org.apachemons.io.output        | 输出流相关的实现类,包含Writer和OutputStream || org.apachemons.io.serialization | 序列化相关的类步骤:1. 下载commons-io相关jar包;. 把commons-io-2.6.jar包复制到指定的Module的lib目录中3. 将commons-io-2.6.jar加入到classpath中小结:IOUtils和FileUtils可以方便的复制文件和文件夹!!*/
public class CommonsIODemo {public static void main(String[] args) throws Exception {// 1.完成文件复制&#py(new FileInputStream("D:\resources\hushui.jpeg"),new FileOutputStream("D:\resources\hushui2.jpeg"));// 2.完成文件复制到某个文件夹下&#pyFileToDirectory(new File("D:\resources\hushui.jpeg"), new File("D:/"));// 3.完成文件夹复制到某个文件夹下&#pyDirectoryToDirectory(new File("D:\resources") , new File("D:\new"));FileUtils.deleteDirectory(new File("D:\new"));// JDK1.7 也做了一些一行代码完成复制的操作:New IO的技术// py(Path.of("D:\resources\hushui.jpeg"), Path.of("D:\resources\hushui3.jpeg"));FileUtils.deleteDirectory(new File("D:\new")); // 只能删除空文件夹}
}

文章参考:Java入门基础视频教程,java零基础自学就选黑马程序员Java入门教程(含Java项目和Java真题)

本文发布于:2024-02-01 23:54:01,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170680985140123.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:最全面   基础   进阶篇   Java   IO
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23