JavaIO流个人总结,Much Demo

Java IO Flow


编码的一些注意点

  • GBK编码格式中,1个汉字占用2个字符,1个英文占用1个字节,1个字符占用2个字节
  • UTF编码格式中,1个汉字占用2个字符,1个英文占用1个字节,1个字符占用3个字节

Java是双字节编码,即字符串中1个字符占用2个字节

采用Unicode编码格式,即utf-16be,中文占用2个字节,英文也占用2个字节
所以要注意编码解码要使用同样的编码格式,否则会出现错误。Java默认采用Unicode。


Java File类

  • java.io.File类用于表示文件(目录)
  • File类只用于表示文件(目录)的信息(名称、大小等),不能用于文件内容的访问

File类有许多方法,举几个例子如下的

    File file = new File("xx:"+File.separator);
    file.mkdir();//file.mkdirs()
    file.delete();
    /*这里可以判断file类型, 有很多*/
    file.isFile();
这里不一一列举了,这里分隔符是一个问题,有同学经常写错,这里可以使用File.separator静态变量,并且支持Linux和Windows,这样就不用担心这个问题了。

这是一个遍历文件的Demo

文件遍历Demo

注意dir.list()和dir.lists()区别,这里用到递归调用,保证遍历

RandomAccessFile类

  • 提供对文件内容的访问,完成读写操作。
  • 支持随机访问文件

java文件模型

  1. 在硬盘上的文件时byte byte存储的,是数据的集合,打开文件有两种方式

  2. 打开方式 “rw” “r”

    RandomAccessFile raf = new RandomAccessFile(file,"rw");
    

    文件指针,打开文件时,指针在开头,pointer = 0;

  3. 写方法

    raf.write(int)----->只写一个字节(后8位),同时指针指向下一个位置,准备再次写入
    
  4. 读方法

    int b = raf.rea的()----->读一个字节
    
  5. 文件读完之后一定要关闭(小心意想不到的错误)

    raf.close();
    

Demo

点击这里查看RAF的例子

使用一次性读取文件内容时,这里会出现乱码,是因为只有汉字是按照gbk编码,其他内容,仍旧使用默认编码,所以需要注意。

IO流

字节流

  1. InputStream、OutputStream分别抽象了应用数据读取和写入的方法。
  2. EOF=end 读到-1就读到结尾
  3. 有许多读写基本方法,按字节读写,或者将读写数据放入byte[].
其他输入输出流均为字节流的子类。

FileIn/OutputStream流


实现向文件中读写的方法,点击查看例子

File流读写工具类

针对一个文件读取并写入,性能比较,具体代码在Test.java中

Test.java

文件大小字节批量读取Buffered缓冲流读取逐个字节读取
4MB64ms12788ms24076ms
37MB707ms101903ms时间太久
这个例子中的copyFile()方法,使用字节批量读取,速度房产快,远远优于其他读取方法。其次是缓冲读取,但只有在大容量文件读取时比较明显。上面的数据太明显了,所以推荐字节批量读取。

DataInputStream/DataOutPutStream


对”流功能的扩展”,可以更加方便的读取int,long,字符等类型数据

DataOutputStream

  • writeInt()
  • writeDouble()
  • writeUTF()

这些只是装饰了基础的方法,提供一个更简单好用的统一方法。是一种装饰模式的体现。

代码测试如下

DataInputStream例子

DataOutputStream例子

BufferedIn/OutputStream流


这两个流类为IO提供了带缓冲区的操作,一般打开文件进行读写操作时,都会带上缓冲,这种流模式提高了IO的性能,从应用程序中把输入放入文件中,相当于将一缸水倒入另一个水缸中:

  1. FileOutputStream—>write()方法相当于一滴一滴地把水”转移”过去
  2. DataOutputStream—>writeXxxx()方法会方便一些,相当于一碗一碗把水”转移”过去
  3. BufferedOutputStream—->write方法更方便,相当于先一碗一碗把水放入桶中,再从桶中倒入到另一个水缸中,这样性能更高。
性能问题在上面已经做过比较

字符流

1. 编码问题

2. 认识文本和文本文件

Java的文本(char)是16位无符号整数,是字符的unidode编码(双字节编码)文件时byte byte byte…的数据序列
文本文件是文本(char)序列按照某种编码方案序列化为byte的集合

3. 字符流(Reader Writer)—->操作的是文本,文本文件

字符的处理,一次处理一个
字符的底层仍然是基本的字节序列
字符流的基本实现
  • InputStreamReader 完成byte流解析为char流,按照编码解析。
  • OutputStreamWriter 提供char流到byte流,按照编码处理。
  • FileReader和FileWriter同上,FileReader无法实现设定编码类型

InputStreamReader和OutputStreamWriter

FileReader和FileWriter

字符流过滤器

  • BufferedReader —->readLine一次度一行
  • BufferedWriter/PrintWriter—-写一行

我们常常将BufferedReader和PrintWriter结合起来用

对象的序列化,反序列化


  • 对象序列化,就是将Object对象转换成byte序列,反之叫对象的反序列化
  • 序列化流(ObjectOutputStream),是过滤流 —–writeObject,反序列化流(ObjectInputStream) readObject()

对象必须实现序列化接口Serializable,才能进行序列化,否则将出现异常,这个接口没有任何方法,只是一个标准。

用法演示

这里注意写入和读取时,分别注释另一块代码,最好分开写成两个函数,方便测试。同下面代码。

transient关键字会使其修饰的元素不进行jvm默认的序列化,但可以自己完成这个元素的序列化

改写writeObject和readObject方法,可以从ArrayList中copy一个,可以看看ArrayList源码,里面有对ArrayList中有效元素的手动序列化,默认是transient的。注意是有效!!!

序列化中子类和父类构造函数的调用问题


序列化过程中子父类构造函数问题
  • 一、父类实现了serializable接口,子类继承就可序列化。
    1. 子类在反序列化时,父类实现了序列化接口,则不会递归调用其构造函数。
  • 二、父类未实现serializable接口,子类自行实现可序列化
    1. 子类在反序列化时,父类没有实现序列化接口,则会递归调用其构造函数。

例子点这里

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值