Java 文件 IO流

一、 JAVA 流式输入 / 输出原理
Java 程序中,对于数据的输入 / 输出操作以 Stream )方式进行; J2SDK 提供了各种各样的 类,用以获取不同种类的数据:程序中通过标准的方法输入或输出数据。
二、输入输出流分类
Java.io 包中定义了多个流类型(类或抽象类)来实现输入 / 输出功能;可以从不同的角度对其进行分类:
按数据流的方向不同可以分为输入流和输出流
按照处理数据单位不同可以分为字节流和字符流
按照功能不同可以分为节点流和处理流
我们来理解两个概念:
字节流:最原始的一个流,读出来的数据就是 010101 这种最底层的数据表示形式,只不过它是按
照字节来读的,一个字节( Byte )是 8 位( bit )读的时候不是一个位一个位的来读,而是一个字节
一个字节来读。
字符流:字符流是一个字符一个字符地往外读取数据。一个字符是 2 个字节
J2SDK 所提供的所有流类型位于包 Java.io 内,都分别继承自以下四种抽象流类型。
输入流: InputStream (字节流), Reader (字符流)
输出流: OutPutStream (字节流), Writer (字符流)
什么叫输入流?什么叫输出流?
用一根管道一端插进文件里,一端插进程序里面,然后开始读数据,那么这是输入还是输出呢?
如果站在文件的角度上,这叫输出。
如果站在程序的角度上,这叫输入。
记住,以后说输入流和输出流都是站在程序的角度上来说
三、节点流和处理流
3.1. 节点流类型

节点流就是一根管道直接插到数据源上面,直接读数据源里面的数据,或者是直接往数据源里面写入数据。典型的节点流是文件流:文件的字节输入流(FileInputStream ),文件的字节输出流
FileOutputStream ),文件的字符输入流( FileReader ),文件的字符输出流( FileWriter )。
3.2. 处理流类型

处理流是包在别的流上面的流,相当于是包到别的管道上面的管道。
四、 InputStream( 输入流 )
继承自 InputStream 的流都是用于向程序中输入数据,且数据的单位为字节( 8bit );下图中深色为节点流,浅色为处理流。

4.1.InputStream的基本方法

//读取一个字节并以整数的形式返回(0~255)
//如果返回-1就说明已经到了输入流的末尾
int read() throws IOException
//读取一系列字节并存储到一个数组buffer
//返回实际读取的字节数,如果读取前已到输入流的末尾,则返回-1
int read(byte[] buffer) throws IOException
//读取length个字节
//并存储到一个字节数组buffer,从length位置开始
//返回实际读取的字节数,如果读取前以到输入流的末尾返回-1.
int read(byte[] buffer,int offset,int length) throws IOException
//关闭流释放内存资源
void close() throws IOException
//跳过n个字节不读,返回实际跳过的字节数
long skip(long n) throws IOException
 

read() 方法是一个字节一个字节地往外读,每读取一个字节,就处理一个字节。 read(byte[] buffffer) 方法读取数据时,先把读取到的数据填满这个byte[] 类型的数组 buffffer(buffffer 是内存里面的一块缓冲区 ) ,然后再处理数组里面的数据。这就跟我们取水一样,先用一个桶去接,等桶接满水后再处理桶里面的水。如果是每读取一个字节就处理一个字节,这样子读取也太累了。
4.2 案例
try {
            in = new FileInputStream(path);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        // 记录读取到的字符数
        long num = 0;
        // 创建一个字节
        byte[] bytes = new byte[1024];
        // 调用read 可能发生异常 所以需要捕获 !=-1
        try {
           *//* while ((b = in.read()) != -1) {
                System.out.println((char) b);
                num++;
            }*//*
            // 传入数组接收
            while ((b = in.read(bytes))!= -1) {
                System.out.println(bytes);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        // 打印多少个字符
        System.out.println(num);




        FileOutputStream out = null;

        try {
            out = new FileOutputStream(path,true);
            // 写入数组 // 如果在调用FileOutputStream的构造方法时没有加入true,
            out.write(bytes);
        }
        catch (Exception e) {
            e.printStackTrace();
        }

五、 OutputStream( 输出流 )

5.1.OutputStream 的基本方法
//向输出流中写入一个字节数据,该字节数据为参数b的低8位
void write(int b) throws IOException
//将一个字节类型的数组中的数据写入输出流
void write(byte[] b) throws IOException
//将一个字节类型的数组中的从指定位置(off)开始的len个字节写入到输出流
void write(byte[] b,int off,int len) throws IOException
//关闭流释放内存资源
void close() throws IOException
//将输出流中缓冲的数据全部写出到目的地
void flush() throws IOException

六、 Reader
Reader : 和 InputStream 一模一样,唯一的区别就在于读的数据单位不同
继承自 Reader 的流都是用于向程序中输入数据,且数据的单位为字符( 16bit

七、 Writer

八、处理流讲解
8.1. 第一种处理流 —— 缓冲流 (Buffffering)
缓冲流要 套接 在相应的节点流之上,对读写的数据提供了缓冲的功能,提高了读写的效率,同时增加了一些新的方法。J2SDK 提供了四种缓冲流,常用构造方法如下:
BufferedReader(Reader in)
BufferedReader(Reader in,int sz) //sz 为自定义缓冲区的大小
BufferedWriter(Writer out)
BufferedWriter(Writer out,int sz)
BufferedInputStream(InputStream in)
BufferedInputStream(InputStream in,int size)
BufferedOutputStream(InputStream in)
BufferedOutputStream(InputStream in,int size)

缓冲输入流支持其父类的 mark reset 方法。
BufffferedReader 提供了 readLine 方法用于读取一行字符串
BufffferedWriter 提供了 newLine 用于写入一个行分隔符
对于输出的缓冲流,写出的数据会现在内存中缓存,使用 flflush 方法将会使内存中的数据立刻写出
带有缓冲区的,缓冲区 (Buffffer) 就是内存里面的一小块区域,读写数据时都是先把数据放到这块缓冲区 域里面,减少io 对硬盘的访问次数,保护我们的硬盘。可以把缓冲区想象成一个小桶,把要读写的数据想象成水,每次读取数据或者是写入数据之前,都是先把数据装到这个桶里面,装满了以后再做处理。
这就是所谓的缓冲。先把数据放置到缓冲区上,等到缓冲区满了以后,再一次把缓冲区里面的数据写入到硬盘上或者读取出来,这样可以有效地减少对硬盘的访问次数,有利于保护我们的硬盘。
8.2. 第二种处理流 —— 转换流
InputStreamReader OutputStreamWriter 用于字节数据到字符数据之间的转换
InputStreamReader 需要和 InputStream “ 套接
OutputStreamWriter 需要和 OutputStream “ 套接
转换流在构造时可以指定其编码集合
转换流非常的有用,它可以把一个字节流转换成一个字符流,转换流有两种,一种叫
InputStreamReader ,另一种叫 OutputStreamWriter InputStream 是字节流, Reader 是字符流,
InputStreamReader 就是把 InputStream 转换成 Reader OutputStream 是字节流, Writer 是字符流,
OutputStreamWriter 就是把 OutputStream 转换成 Writer 。把 OutputStream 转换成 Writer 之后就可以
一个字符一个字符地通过管道写入数据了,而且还可以写入字符串。我们如果用一个 FileOutputStream流往文件里面写东西,得要一个字节一个字节地写进去,但是如果我们在FileOutputStream 流上面套上 一个字符转换流,那我们就可以一个字符串一个字符串地写进去。
8.5. 对象流 ——Object
直接将 Object 写入或读出
transient 关键字
transient :透明的,用它来修饰的成员变量在序列化的时候不予考虑,也就是当成不存在。
serializable 接口
externaliazble 接口
ObjectInputStream objectInputStream = new ObjectInputStream(in);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(out);
/*
* 凡是要将一个类的对象序列化成一个字节流就必须实现Serializable接口
* Serializable接口中没有定义方法,Serializable接口是一个标记性接口,用来给类作标记,
只是起到一个标记作用。
* 这个标记是给编译器看的,编译器看到这个标记之后就可以知道这个类可以被序列化 如果想把某个
类的对象序列化,就必须得实现Serializable接口
*/
class T implements Serializable {
// Serializable的意思是可以被序列化的
int i = 10;
int j = 9;
double d = 2.3;
int k = 15;
// transient int k = 15;
// 在声明变量时如果加上transient关键字,那么这个变量就会被当作是透明的,即不存在。
}

九、 IO 流总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值