Android I/O

一、概念

文件在程序中是以流的形式来操作的。

流:是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两个存储位置之间的传输称为流。流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。

二、分类

1、按照流向划分:输入流、输出流


20170402104740037.png

以内存为参照:
输入流:从文件流向内存
输出流:从内存流向文件

2、按照传输单位划分:字节流、字符流


20170402110541498.png

字节流:可以用于读写二进制文件及任何类型文件。

字符流:可以用于读写文本文件。

以“Reader”结尾都是字符流,操作的都是字符型的数据;以“Stream”结尾的都是字节流,操作的都是byte数据。

三、字节流VS字符流的区别

字符流的由来: 因为数据编码的不同,从而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。

区别:

1、读写单位不同:字节流以字节(1 byte,1byte=8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
2、处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。
3、缓存。字节流在操作的时候本身是不会用到缓冲区的,是文件本身的直接操作的;而字符流在操作的时候下后是会用到缓冲区的,是通过缓冲区来操作文件。

总结:优先选用字节流。因为硬盘上的所有文件都是以字节的形式进行传输或者保存的,包括图片等内容。字符只是在内存中才会形成的,所以在开发中,字节流使用广泛。

四、实际使用

  1. InputStream && OutputStream
    在java中InputStream是字节输入流,用来将文件中的数据读取到java程序中。
    outputStream 是字节输出流,用来将内存中的数据输出到文件中。
    InputStream 和 OutputStream为各种输入输出字节流的基类,所有字节流都继承这两个基类。


    图片.png
  2. Reader && Writer
    字符流只能处理字符,不能用来处理 .jpg;.mp3;.mp4;.avi;.doc;.ppt等二进制文件,这些只能通过字节流来处理。所以对于纯文本的文件,强烈推荐使用字符输入输出流。
    字符流的本质其实就是基于字节流在读取时去查了指定的码表。
    Reader 和 Writer 为各种输入输出字符流的基类,所有字符流都继承这两个基类。

图片.png

注意:如果字符输出流不调用close()方法关闭资源,数据只是保存到缓冲区,并不会保存到文件(这一点与FileOutputStream不同,即使它不调用close()方法依然会写入到文件中)。

这里就得介绍一下flush()这个方法。

flush()和close()方法的区别:

flush():将流中的缓冲区缓冲的数据刷新到目的地中,刷新后,流还可以继续使用。

close():关闭资源,但在关闭前会将缓冲区中的数据先刷新到目的地,否则丢失数据,然后再关闭流。流不可以使用。

  1. 文件操作流 --------- FileInputStream && FileOutputStream
       //1.指定要读 的文件目录及名称
        File file =new File("文件路径");
        //2.创建文件读入流对象
        FileInputStream fis =new FileInputStream(file);
        //3.定义结束标志,可用字节数组读取
        int i =0 ;
        while((i = fis.read())!=-1){ 
            //i 就是从文件中读取的字节,读完后返回-1
        }
        //4.关闭流
        fis.close();
        //5.处理异常
        //1.指定要写到的文件目录及名称
        File file =new File("文件路径");
        //2.创建文件读入流对象
    FileOutputStream fos =new FileOutputStream(file);
        //3.定义结束标志
        fos.write(要写出的字节或者字节数组);
        //4.刷新和关闭流
        fos.flush();
        fos.close();
        //5.处理异常
  1. 文件操作流 --------- FileReader && FileWriter

  2. 缓冲流 --------- BufferedInputStream && BufferedOutputStream
    缓冲流是对流的操作的功能的加强,提高了数据的读写效率。既然缓冲流是对流的功能和读写效率的加强和提高,所以在创建缓冲流的对象时应该要传入要加强的流对象。

  3. 缓冲流 --------- BufferedReader && BufferedWriter
    在字符读入缓冲流BufferedReader 中还提供了读一行的方法 readLine() 可以读取一行文本
    在字符写出缓冲流BufferedWriter 中还提供了写入一个行分隔符的方法writeLine(),用于写出时换行

  4. 转换流 --------- InputStreamReader && OutputStreamWriter
    InputStreamReader: 字符转换输出流
    OutputStreamWriter:字符转换输入流
    实际上,这两个类内部各自持有一个inputStream 和 outputStream对象,相当于是对inputStream 和 outputStream进行了包装,将输入字节流转换成字符流,便于读写操作。注 :要传入字节流作为参数
    需求:读取键盘输入的一行文本,再将输入的写到本地磁盘上

//1.获取键盘输入的字节流对象in
InputStream in =Stream.in; 
/*2.用转换流将字节流对象转换为字符流对象,方便调用字符缓冲流的readeLine()方法*/
InputStreamReader isr =new InputStreamReader(in);
/*5.创建字符转换输出流对象osw,方便把输入的字符流转换为字节输出到本地文件。*/
OutputStreamWriter osw =new OutputStreamWriter(new 
    FileOutputStream(new File("文件名"))); 
 
/*3.现在isr是字符流,可以作为参数传入字符缓冲流中*/
BufferedReader br =new BufferedReader(isr);
 
/*4.可以调用字符缓冲流br的readLine()方法度一行输入文本*/
String line =null;
while((line =br.readLine()){
    osw.write(line);//osw是字符流对象,可以直接操作字符串
 
}
 
 
注:InputStreamReader isr =new InputStreamReader(new "各种类型的字节输入流都行即是:后缀为InputStream就行");
OutputStreamWriter osw =new OutputStreamWriter(new 
    "后缀为OutputStream就行"); 
  1. 对象流 --------- ObjectInputStream && ObjectOutputStream
    不同于以上两种类型的流这里只能用字节对对象进行操作

ObjectOutputStream对象的序列化:
将java程序中的对象写到本地磁盘里用ObjectOutputStream
eg:将Person类的对象序列化到磁盘

    1.创建Person类
        注1:此类要实现Serializable接口,此接口为标志性接口
        注2:此类要有无参的构造函数
        注3:一旦序列化此类不能再修改
        class Person implements Serializable{
            public Person(){}
        } 
    2.创建对象流对象
        注:要增强功能可以将传入文件缓冲流
        ObjectOutputStream oos =new ObjectOutputStream(
        new FileOutputStream(new File("文件路径")));
    3.写入对象 ,一般会将对象用集合存储起来然后直接将集合写入文件
        List<Person> list =new ArrayList<>();
        list.add(new Person());
        ...(可以添加多个)
        oos.writeObject(list);
    4.关闭流,处理异常
        oos.flush();
        oos.close();

ObjectInputStream对象的反序列化:
从本地磁盘里用ObjectInputStream将对象文件读入java程序

    注1:用集合接收的时候要强转
    1.创建对象流对象
        ObjectInputStream ois =new ObjectInputStream(
        new FileInputStream(new File("文件路径")));
    2.读入对象
        List<Person> list =new ArrayList<>();
        List =(List<Person>)ois.readObject();
    3.关闭流,处理异常
        ois.close();
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 什么是 I/OI/O 是机器获取和交换信息的主要渠道,而流是完成 I/O 操作的主要方式。 在计算机中,流是一种信...
    柳岸花开阅读 366评论 0 0
  • 概念和作用 流:代表任何有能力产出数据的数据源对象或者是有能力接受数据的接收端对象流的本质:数据传输,根据数据传输...
    海人为记阅读 289评论 0 0
  • 一、流的概念和作用。 流是一种有顺序的,有起点和终点的字节集合,是对数据传输的总成或抽象。即数据在两设备之间的传输...
    布鲁斯不吐丝阅读 10,101评论 2 95
  • 1 I/O流的概念,分类2 I/O所有类的结构图及详解3 何为NIO,和传统I/O有何区别4 在开发中正确使用I/...
    艾剪疏阅读 502评论 0 2
  • 47. File类 java.io.File类文件和目录路径名的抽象表示形式java把电脑中的文件和文件夹(目录)...
    abboo阅读 305评论 0 0