IO流概念与实现类

目录

一、IO流的概述:

二、IO流的java.io.FileOutputStream类(输出字节流)

三、io流的java.io.FileInputStream类(输入字节流)

四、io流的java.io.Writer类(输出字符流)

五、io流的java.io.FileReader类(输入字符流)

六、转换流

七、打印流

八、缓存流


一、IO流的概述:

 可以将数据的传输看成一种流动,按照流动的方向可以分为输入Input和输出Output

Java的IO操作,一般指的是Java.IO包下的一些常用类的使用,通过这些常用类对数据进行读取(Input)和输出(Output)

按照流动方向可以分为:输入流和输出流。

按照流动的数据类型可以分为:字节流和字符流

字节流:

             输出——OutputStream   (顶级父类)

             输入——InputStream   (顶级父类)

字符流:

             输出——Writer       (顶级父类)

             输入——Reader       (顶级父类)

二、IO流的java.io.FileOutputStream类
(输出字节流)

* 每创建一个FileOutputStream的对象,就相当于开了一个流管道,就可以通过此对象向指定文件输出内容。

方法的实现——write(输入流)

 public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("d://b.txt");//创建一个对象
        fos.write(65);   //传入一个字节 65
        byte [] bytes = {65,66,67,68};   //创建一个数组
        fos.write(bytes);         //传入数组bytes
        byte [] bytes1 = "哈哈哈哈".getBytes(StandardCharsets.UTF_8); //传入字符数组
        fos.write(bytes1);
        fos.close();    //用完要关闭流!!很重要!!
        System.out.println("创建完成");

    }

执行结果

值得注意的是:每创建一个对象都会清空原本的文件然后重写,eg:

加上这段代码后:

 FileOutputStream fos2 = new FileOutputStream("d://b.txt");
        byte [] bytes2 = "继续写的".getBytes(StandardCharsets.UTF_8);
        fos2.write(bytes2);
        fos2.write(66);
        fos2.close();

运行结果:

除非:在new对象时在路径后面加上,true

FileOutputStream fos2 = new FileOutputStream("d://b.txt",true);
        byte [] bytes2 = "继续写的".getBytes(StandardCharsets.UTF_8);
        fos2.write(bytes2);
        fos2.write(66);
        fos2.close();

运行结果:

 写出数组中的一部分:

 FileOutputStream fos = new FileOutputStream("D://c.txt");
        byte [] bytes = {65,66,67,68,10};
        fos.write(bytes,1,2);   //传入数组bytes,从下标1开始,输入两个
        fos.close();

运行结果:

三、io流的java.io.FileInputStream类(输入字节流)

InputStream是将文件内容读到程序中

例如:我们现在创建一个文件,路径为:d://c.txt  。内容如下!

 现在我们实现一下将内容读到程序中的方法,来将此文件中的内容,读到程序中

此为以字节形式输出

 FileInputStream fos = new FileInputStream("d://c.txt");//new一个输入流对象
        /**
         * 读取,以字节形式输出
         */
        byte b = (byte) fos.read();    //因为是字节型,所以要强转
        System.out.println((char)b);    //再将字节强转成字符进行输出
        fos.close();

注意:read读取,返回是int值,是从第几个字节读到第几个字节

运行结果:

 此段代码为:每次读一个字节,循环输出!

   fos.close();*/
        /**
         * 循环读取
         */
       while (true){
        byte b = (byte) fos.read();    //因为是字节型,所以要强转
            if(b!=-1) {           //因为读取不到的话会返回-1
                System.out.print((char) b);    //再将字节强转成字符进行输出
            }else{
                break;
            }
        }
        fos.close();

结果:

但其实,我们通常用的输入都是用数组: 

 /**
         * 读取,以数组形式输出
         */
        byte[] bytes = new byte[10];
        int len = fos.read(bytes);
        System.out.println(new String(bytes,0,len));
        len = fos.read(bytes);
        System.out.println(new String(bytes,0,len));
        len = fos.read(bytes);
        System.out.println(new String(bytes,0,len));
        fos.close();

运行结果:

这里有个知识点:我们如果不用len来限定输出的长度,那么输出的结果会是这样:

 这是因为,我们创建的数组长度为10,第三次读取的时候,长度不够,所以只替换数组中的前6个!后面四个和上一次读取输出的数组的后四个一样!!

四、io流的java.io.Writer类(输出字符流)

注意:字符流在输出时要刷新管道,而 字节流不需要。刷新管道即用对象调用flush方法。也可以不用专门调用,因为close方法会自动刷新管道。再次强调是因为,如果没有close,也没有flush。字节流是可以输出的,但是字符流不可以。

1、为什么要用字符流?

因为字节流在输出字符时,不知道字符占几个字节,假如一个字占两个字节,但是,你只输出了一个字节,那么就是半个字,计算机会将其显示出来,但由于不认识,所以显示出来就是一个问号或其他乱码。为了解决这个问题,我们就用字符流。

2、字符流

字符流以字为单位输出,如果是半个字就不会输出。所以不至于输出问号或乱码。但字符流的方法与字节流大同小异!我们来实现一下!

FileWriter w = new FileWriter("d://a.txt");
    w.write("进大厂,买摩托");
    FileWriter w2 = (FileWriter) w.append("哈哈");      //追加返回的是此对象,
        System.out.println(w2 == w); //结果为true即这俩为一个对象
        // 需要强转,因为是多态
        /**
         * 可以连续追加
         */
        w.append("第一次追加").append("第二次追加").append("第三次追加");
    w.close(); //关闭流

下面为文件结果

值得注意的是:append方法为依次输入时的追加内容。而在new对象时,路径后面如果加true,是指在上一次的文件中直接继续添加,而不用清空原文件! 

五、io流的java.io.FileReader类(输入字符流)

和字节输入流类似,我们来实现一下常用方法!(用刚刚用字符输出流写的文件)

先用简单的read方法来读字符

FileReader r = new FileReader("d://a.txt");
        //读一个字符
        int c = r.read();   //read返回值是int型
        System.out.println((char)c);     //输出要强转
        //用循环来读一串字符
        while(true){
            int c1 = r.read();
            if(c1 == -1){
                break;
            }
            System.out.print((char) c1);
        }
            r.close();

运行结果:

用数组来输入字符流:

注意!!!!!:此处创建数组,长度为100,但是我们本来的字符长度没有100,所以后面的长度全部用空格来填满!这样很占内存!!

 char [] c = new char[100];
        r.read(c);
        System.out.println(c);
        r.close();

 运行结果:

 解决方案~~用length来限定长度!

char [] c = new char[100];
        int len = r.read(c);    //read返回的int就是长度,将长度赋给len
        String text = new String(c,0,len); //输出字符串,从0开始,输出len个字符
        System.out.println(text);
        System.out.println(text.length());
        r.close();

运行结果!

六、转换流

转换流是一种将字节流装饰为字符流的流

1、将字节输出流转换为字符输出流:

OutputStreamWriter 类

2、将字节输入流转换为字符输入流

InputStreamReader

演示实现一下!

我们先用输出流来写一个txt文件

FileOutputStream fis = new FileOutputStream("d://a.txt");  //创建一个输出字节流对象
        //转换流
        OutputStreamWriter fiss = new OutputStreamWriter(fis);  //用转换流将字节流转换为字符流
        fiss.write("床前明月光"); 
        fiss.close();

结果,在d盘中:

 再用输入流,将刚刚写的txt输入到程序中:

 FileInputStream fis = new FileInputStream("d://a.txt");  //创建一个输入字节流对象
       /* *
         * 转换流*/
        InputStreamReader fiss = new InputStreamReader(fis);  //用转换流将字节流转换为字符流
        while (true){
            int c = fiss.read();
            if(c==-1){
                break;
            }
            System.out.println((char)c);
        }
        fiss.close();

结果:

七、打印流

将字符打印出去,System.out其实就是在用字符的打印(输出)流。

很简单,我们用代码演示

PrintStream ps = new PrintStream("d://c.txt");
        ps.println("锄禾日当午");
        ps.close();
 PrintWriter ps1 = new PrintWriter("d://c.txt");
        ps1.append("汗滴禾下土");
        ps1.close();

这里面的PrintStream 和 PrintWriter 的实现和方法都没啥区别。

运行结果,这里展示一下第二个的,第一个和这个一样

打印流也可以直接将字节流转化为字符流

 FileOutputStream fos = new FileOutputStream("d://e.txt"); //字节流
        PrintWriter foss = new PrintWriter(fos);  //用PrintWriter来转换成字符流
        foss.println("进大厂1");
        foss.println("进大厂2");
        foss.println("进大厂3");
        foss.close();

 结果:

八、缓存流

之前的流都是一次读一个字节或者一个字符。
而缓存流是:
将字符输入流转换成带有缓存的,可以一次输出一行字符的缓存字符读取流。
FileReader fos1 = new FileReader("d://e.txt");  //先用FileReader读取文件
        BufferedReader fos2 = new BufferedReader(fos1);  //创建缓存流对象
        String text = fos2.readLine();   //用对象调用读取一行的方法
        System.out.println(text);

结果:

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值