30.3. 文件拷贝操作

需求:把copy_before.txt文件中的数据拷贝到copy_after.txt文件中

private static void copy() throws Exception {//1):创建源或者目标对象File src = new File("file/copy_before.txt");File dest = new File("file/copy_after.txt");//2):创建IO流对象FileReader in = new FileReader(src);FileWriter out = new FileWriter(dest);//3):具体的IO操作int len = -1;//记录以及读取了多个字符char[] buff = new char[1024];//每次可以读取1024个字符len = in.read(buff);//先读取一次while(len > 0) {//边读边写out.write(buff, 0, len);len = in.read(buff);//再继续读取}//4):关闭资源(勿忘)out.close();in.close();
}

如何,正确处理异常:

private static void copy2() {//1):创建源或者目标对象File src = new File("file/copy_before.txt");File dest = new File("file/copy_after.txt");
​//把需要关闭的资源,声明在try之外FileReader in = null;FileWriter out = null;try {//可能出现异常的代码//2):创建IO流对象in = new FileReader(src);out = new FileWriter(dest);//3):具体的IO操作int len = -1;//记录以及读取了多个字符char[] buff = new char[1024];//每次可以读取1024个字符len = in.read(buff);//先读取一次while (len > 0) {out.write(buff, 0, len);len = in.read(buff);//再继续读取}} catch (Exception e) {e.printStackTrace();} finally {//4):关闭资源(勿忘)try {if (out != null) {out.close();}} catch (Exception e) {e.printStackTrace();}try {if (in != null) {in.close();}} catch (Exception e) {e.printStackTrace();}}
}

此时关闭资源的代码,又臭又长,在后续的学习中为了方便就直接使用throws抛出IO异常了,在实际开发中需要处理。

30.4. 缓冲流

节点流的功能都比较单一,性能较低。处理流,也称之为包装流,相对于节点流更高级,这里存在一个设计模式——装饰设计模式,此时撇开不谈。

包装流如何区分?写代码的时候,发现创建流对象时,需要传递另一个流对象,类似:

new  流类A(  new 流类B(..) ) ;  

那么流A就属于包装流,当然B可能属于节点流也可能属于包装流。

有了包装流之后,我们只关系包装流的操作即可,比如只需要关闭包装流即可,无需在关闭节点流。

非常重要的包装流——缓冲流,根据四大基流都有各自的包装流:

BufferedInputStream / BufferedOutputStream / BufferedReader / BufferedWriter

缓冲流内置了一个默认大小为8192个字节或字符的缓存区,缓冲区的作用用来减少磁盘的IO操作,拿字节缓冲流举例,比如一次性读取8192个字节到内存中,或者存满8192个字节再输出到磁盘中。

操作数据量比较大的流,都建议使用上对应的缓存流。

需求:把郭德纲-报菜名.mp3文件中的数据拷贝到郭德纲-报菜名2.mp3文件中

private static void copy3() throws Exception {//1):创建源或者目标对象File src = new File("file/郭德纲-报菜名.mp3");File dest = new File("file/郭德纲-报菜名2.mp3");//2):创建IO流对象BufferedInputStream bis =
new BufferedInputStream(new FileInputStream(src), 8192);BufferedOutputStream bos =
new BufferedOutputStream(new FileOutputStream(dest), 8192);//3):具体的IO操作int len = -1;//记录以及读取了多个字符byte[] buff = new byte[1024];//每次可以读取1024个字符len = bis.read(buff);//先读取一次while (len > 0) {//边读边写bos.write(buff, 0, len);len = bis.read(buff);//再继续读取}//4):关闭资源(勿忘)bos.close();bis.close();
}

30.5. 对象序列化

序列化:指把Java堆内存中的对象数据,通过某种方式把对象数据存储到磁盘文件中或者传递给给网络上传输。序列化在分布式系统在应用非常广泛。

反序列化:把磁盘文件中的对象的数据或者把网络节点上的对象数据恢复成Java对象的过程。

需要做序列化的类必须实现序列化接口:java.io.Serializable(这是标志接口[没有抽象方法])

可以通过IO中的对象流来做序列化和反序列化操作。

  • ObjectOutputStream:通过writeObject方法做序列化操作的

  • ObjectInputStream:通过readObject方法做反序列化操作的

如果字段使用transient 修饰则不会被序列化。

class User implements Serializable {private String name;private transient String password;private int age;
​public User(String name, String password, int age) {this.name = name;this.password = password;this.age = age;}public String getName() {return name;}public String getPassword() {return password;}public int getAge() {return age;}public String toString() {return "User [name=" + name + ", password=" + password + ", age=" + age + "]";}
}

测试代码

public class ObjectStreamDemo {public static void main(String[] args) throws Exception {String file = "file/obj.txt";ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file));User u = new User("Will", "1111", 17);out.writeObject(u);out.close();//--------------------------------------ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));Object obj = in.readObject();in.close();System.out.println(obj);}
}

obj.txt文件

序列化的版本问题

当类实现Serializable接口后,在编译的时候就会根据字段生成一个缺省的serialVersionUID值,并在序列化操作时,写到序列化数据文件中。

但随着项目的升级系统的class文件也会升级(增加一个字段/删除一个字段),此时再重新编译,对象的serialVersionUID值又会改变。那么在反序列化时,JVM会把对象数据数据中的serialVersionUID与本地字节码中的serialVersionUID进行比较,如果值不相同(意味着类的版本不同),那么报异常InvalidClassException,即:类版本不对应,不能进行反序列化。如果版本号相同,则可以进行反序列化。

为了避免代码版本升级而造成反序列化因版本不兼容而失败的问题,在开发中我们可以故意在类中提供一个固定的serialVersionUID值。

class User implements Serializable {private static final long serialVersionUID = 1L;//TODO
}

30.6. 查漏补缺

30.6.1. 打印流

打印流是一种特殊是输出流,可以输出任意类型的数据,比一般的输出流更好用。可以作为处理流包装一个平台的节点流使用,平时我们使用的System.out.println其实就是使用的打印流。

  • PrintStream :字节打印流

  • PrintWriter :字符打印流

打印流中的方法:

  • 提供了print方法:打印不换行

  • 提供了println方法:先打印,再换行

private static void test5() throws Exception {//1):创建源或者目标对象File dest = new File("file/result3.txt");//2):创建IO流对象PrintStream ps = new PrintStream(new FileOutputStream(dest));//3):具体的IO操作ps.println("Will");ps.println(17);ps.println("众里寻他千百度,蓦然回首,那人却在,灯火阑珊处。");//4):关闭资源(勿忘),打印流可以不用关闭
}  

30.6.2. 标准IO

标准的输入:通过键盘录入数据给程序

标准的输出:在屏幕上显示程序数据

在System类中有两个常量int和out分别就表示了标准流:

InputStream in  = System.in;
PrintStream out = System.out;

需求:做一个ECHO(回声)的小案例

public static void main(String[] args) throws Exception {Scanner sc = new Scanner(System.in);  //接受用户输入数据后敲回车while (sc.hasNextLine()) {        //判断用户是否输入一行数据String line = sc.nextLine();    //获取用户输入的数据System.out.println("ECHO:" + line);//显示用户输入的数据}
}

30.7.IO流小结

在开发中使用比较多的还是字节和字符流的读写操作,务必要非常熟练,再体会一下六字箴言(读进来,写出去),到底有何深意。

综合练习题:做一个统计代码行数的程序,扫描一个目录能统计出该目录中包括所有子目录中所有Java文件的行数,不统计空行。

private static void doWork(File dir) {//TODO
}

java之IO流(2)相关推荐

  1. Java基础—IO流

    第一讲   IO概述 1. 流的概念 IO流即InputOutput的缩写,在Java中IO流用来处理设备之间的数据传输,Java对数据的操作是通过IO流的方式, 我们可以把IO流抽象的当作一根管道, ...

  2. java数据通道抽象为流_【java】IO流

    对于java的IO流的理解很长时间来都是很乱,包括学习其他的语言对这一块知识也都算是一个盲点.更多的时候一提到读取保存数据就是使用数据库.这一次学习了IO流,自己又解决了一个很大的盲点. IO流为我们 ...

  3. 第15章-输入/输出 --- 理解Java的IO流

    (一)理解Java的IO流 JAVA的IO流是实现输入/输出的基础,它可以方便地实现数据的输入/输出操作,在Java中把不同的输入/输出(键盘.文件.网络连接等)抽象表述为"流"( ...

  4. Java基础-IO流对象之数据流(DataOutputStream与DataInputStream)

    Java基础-IO流对象之数据流(DataOutputStream与DataInputStream) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.数据流特点 操作基本数据类型 ...

  5. Java中IO流的总结

    有关Java中IO流总结图 流分类 按方向分 输入流 输出流 按单位分 字节流 字符流 按功能分 节点流 处理流(过滤流) 其他 所有的流继承与这四类流:InputSteam.OutputStream ...

  6. Java 的 IO 流

    接着上一篇的 "Java 的 File 类" 的随笔,在File类的基础上,我们就走进Java的IO流吧. 流的概念和作用 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的 ...

  7. java中io流是类吗_Java中的IO流

    今天刚刚看完java的io流操作,把主要的脉络看了一遍,不能保证以后使用时都能得心应手,但是最起码用到时知道有这么一个功能可以实现,下面对学习进行一下简单的总结: IO流主要用于硬板.内存.键盘等处理 ...

  8. Java - 文件(IO流)

    Java - 文件 (IO) 流的分类:     > 文件流:FileInputStream | FileOutputStream | FileReader | FileWriter     & ...

  9. java 的io流需要学吗_Java的IO流之字节流,必须要学得内容,你会嘛?

    原标题:Java的IO流之字节流,必须要学得内容,你会嘛? 伙伴们~ 端午节过的如何呀~ 有没有很开心呀~ 假期已过咱们继续开动了 IO流 先来认识一下IO流: IO流用来处理设备之间的数据传输,Ja ...

  10. 总是记不住java的IO流用法?用N个问题教你掌握java IO流

    本文分享自华为云社区<总是记不住java的IO流用法?用N个问题教你掌握java IO流>,原文作者:breakDraw . Java IO 体系看起来类很多,感觉很复杂,但其实是 IO ...

最新文章

  1. ignite学习笔记
  2. .net pdf转图片_pdf2image类库实现批量pdf转图片
  3. 汇编语言基础知识摘要(《汇编语言》王爽)第 1 / 17 章
  4. Javascript原型理解图
  5. 详解语音识别的技术原理
  6. VirtualBox虚拟机执行效率很高
  7. 【飞行器】基于matlab GUI四旋翼飞行器飞行模拟【含Matlab源码 1183期】
  8. java日期字符串排序_java字符串日期排序比较问题
  9. 备课手记:把Ken Olsen换成姚明
  10. php三级分销思路 数据库设计_微信分销相关的数据表结构设计
  11. 宠物商店信息管理系统(C++)
  12. 怎么在宝妈论坛引流?宝妈论坛如何引流?如何引流宝妈群体
  13. 4 Pics 1 Word,穷举答题
  14. java 必须try catch的异常_【java基础之异常】死了都要try,不淋漓尽致地catch我不痛快!...
  15. 哈姆雷特(hamlet)现代英语版
  16. 【ARCGIS创建中国南海诸岛及九段线小图框】
  17. 基于多特征时空图卷积网络的水运通航密度预测
  18. python csv数据处理生成图_Python 读取CSV文件数据并生成可视化图形
  19. 如何从TensorFlow的mnist数据集导出手写体数字图片
  20. 学习数学一定要多做练习

热门文章

  1. centos下使用glog
  2. C++实现选择排序算法
  3. 离开 YY 三年,赵斌和他的声网是如何做实时音视频互动的?
  4. lintcode 骰子求和
  5. LeeCode LCP.13 寻宝【python】
  6. 医院招计算机科学与技术干什么,最新医院信息科招收计算机科学与技术专业的笔试试题...
  7. linux 非root用户mount,linux – 选项“user”适用于mount,而不适用于umount
  8. 【Beautiful Soup库】{0} ——Beautiful Soup库的简介
  9. html中购物车小球飞入的效果,vue项目中css3实现加入购物车小球抛物线飞入动画效果...
  10. 5Why根因分析法:通过好问题引出一个好答案