JAVA中的I/O流到底怎么理解

先来介绍一下I/O流的一些基本概念 

根据流的方向,可以分为 :

输入流:程序读数据

输出流:程序写数据

根据流的单位,可以分为:

字节流:一个字节一个字节的流,八位  对应抽象类:InputStream OutputStream 

字符流:一个字符一个字符的流,十六位  对应抽象类:Reader Writer

根据流的用途,可以分为:

处理流:套在其他流之上的流,处理数据的流。 

节点流:流直接连接源,源包括文件、内存中的数组或字符串、管道。

一、字节流:带stream的都为字节流

二、字符流 :带reader或writer的都为字符流

三、 缓冲流:处理流的一种,套在节点流上面,在内存中的一块空间,缓冲节点流数据,减少I/O读写次数,延长硬盘寿命,带Buffered的都为缓冲流

下面程序是个缓冲流的例子,粗的管道相当于缓冲流,套在细的字节流外面处理数据 

四、转换流,处理流的一种。可以将字节数据转换成字符数据。

下面看转换流的例子:

  • new FileOutputStream时,参数传了一个true,表示写的时候是向这个文件后追加内容,而不是覆盖。
  • 转换流可以指定编码集合。
  • 在写入字节流时用转换流包装一下,write()方法就可以传入字符串了,提高写入效率。

再看一个例子,这里的System.in返回的是InputStream抽象类型的流,这个方向相当于读取键盘的输出,然后外层套了一个InputStreamReader转换流,将其由字节流转为字符流,紧接着,外面又套了一个BufferedReader缓冲流,将读取结果放到

一个缓冲区里,然后一行一行的读(readLine()方法是缓冲流的专属方法),这样又快又不损害硬盘

 

五、数据流,也是处理流的一种。可以将一些java基本数据类型的流或者utf8编码进行I/O操作,而不用去考虑字节字符转换等问题。

 

看一个例子:

  • 首先,ByteArrayOutputStream字节数组输出流在内存中创建一个字节数组,所有发送到输出流的数据保存在该字节数组中,若构造时不带参数,则这个字节数组长度是32,即可以存放32个字节。
  • 然后然后将处理流DataOutputStream包在这个字节数组流外面,这样写操作时就不用关心数值类型了
  • writeDouble() ,writeBoolean()是写数据的方法,每次调用,相当于依数组下标从小到大将数值放进数组中的单元内,因double型占用超过1个字节,因此需要先转换成long型,然后再放入字节数组,因long占8个字节,因此需要占用数组8个单元。boolean占一个字节。
  • ByteArrayInputStream的available()方法:返回字节数组中存有元素的有效长度,因之前放了一个double,又放了一个boolean,总共占了九个字节。因此available()返回9
  • DataInputStream的readDouble()和 readBoolean()方法需要注意调用顺序,这个数组相当于一个队列,先进先出,因此先读到的是double类型的。

六、Print流 ,处理流的一种。因为其涉及到的都是打印,输出等操作,因此没有输入流的相关处理类。

 

看一个例子:

  • 写一个文件,使用PrintStream()打印字节流包在FileOutputStream外面,这样可以重新指定print操作
  •  System.out  这个字段先解释一下,这是 “标准”输出流。 此流已经打开并准备好接受输出数据。 通常,此流对应于显示输出或由主机环境或用户指定的另一个输出目标。
  • System.setOut(ps) ;//这里是将system.out.由原来的显示输出改为这个已经套在FileOutputStream之外的PrintStream打印流,换言之,就是这个输出流将流向最终的log.dat文件,因此后面再调用System.out.print()方法时,实际上是执行的PrintStream的print方法,将结果打印在其指定的流中。

 

 

这是运行结果

 

再来一个例子

  • 这里是想将键盘输入的内容输出到一个文件中。
  • 输入的内容首先读取后用缓冲流管道包一下
  • 然后开启一个FileWriter字符流,准备好写入流管道
  • 在写入流管道外再包一个打印写入流管道,管道时刻准备中
  • 开始从缓冲区读,每读一行,只要不是exit这个字符串,就用打印流写入文件中

 

七.Object流,Object数据在内存中整个序列化进行I/O操作,因此类需要声明实现了serializable接口

 

下面看一个例子:

 

下面再来两个例子: 

public static void main(String args[]) throws Exception{
        File contentFile = null;
        FileInputStream fis = null;
        InputStreamReader isr = null;
        try {
            contentFile = new File("src/cn/duoduo/ddd.txt");
            if(contentFile.exists()) {
                fis = new FileInputStream(contentFile);
                StringBuffer sb = new StringBuffer(8192);
                isr = new InputStreamReader(fis, "utf-8");

                char buff[] = new char[4096];
                int length;

                while ((length = isr.read(buff, 0, 4096)) != -1) {
                    if (length > 0) {
                        sb.append(buff, 0, length);
                    }
                }

                System.out.println(sb.toString());
            }
        } catch(FileNotFoundException e){
            e.printStackTrace();
        }finally {
            isr.close() ;
            fis.close() ;
        }
    }

下面是一个复制文件的例子:

public static void main(String args[]) throws java.io.FileNotFoundException,IOException {
        try(
        FileInputStream input = new FileInputStream("src/cn/duoduo/ddd.txt");
        FileOutputStream output = new FileOutputStream("src/cn/duoduo/bbb.txt");
        BufferedInputStream bfInput = new BufferedInputStream(input);
        BufferedOutputStream bfOutput = new BufferedOutputStream(output);
        ) {
            int r, bytesNumber = 0;
            while ((r = bfInput.read()) != -1) {
                bfOutput.write(r);
                bytesNumber++;
            }
            System.out.println("Destination.java有"+bytesNumber+"个字节");
        }

 }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值