JAVA输入输出流总结

JAVA中的流按照数据流的流向分为输入输出流;按照数据处理的类型不同又分为字节流和字符流。下面就分别来进行说明。

字符流

一:输入流:

java 中使用的字符输入流的基本类为Reader抽象类,通常实现字符输入流功能的都是他的一些子类;
这里写图片描述

1.1—FileReader
InputStreamReader是字节流通向字符流的桥梁,他使用指定的charset读取字节,并且将它解析成字符。通常我们使用他的子类FileReader来进行字符的读取操作;
上代码!
(1)

FileReader fReader = null;
        int c = 0;
        try {
            fReader = new FileReader(
                    "C:\\Users\\Administrator\\Desktop\\abc.txt");
            while ((c = fReader.read()) != -1) 
            {
                System.out.println((char) c);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            try {
                if (fReader != null) {
                    fReader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

分析:
1:因为FileReader对象被try catch包裹,无法做到全局使用,所以在try catch外创建FileReader对象:FileReader fReader = new FileReader(
“C:\Users\Administrator\Desktop\abc.txt”);
注意:内部的参数是要读取的文件的绝对路径。(一定要写文件的后缀名)
2:FileReader的方法read():读取的是文件的单个字符,他将字符转换成了int类型返回出来,所以在输出的时候要使用强制类型转换。当字符读取完后他的返回值是-1。所以在while循环中使用这个方法的返回值来作为循环是否继续的条件。
3:在while循环内部有一个坑: System.out.println((char) c);内部的输出一定不能写fReader.read();因为在上边的代码中已经有变量对这个方法的返回值进行接收了,如果在输出语句中再使用一次这个方法,会出现跳读的现象。
4:这两段代码使用try catch包裹起,是因为有可能会出现两个异常,有可能找不到文件,或者是读取不出来文件中的字符。如果不出现异常那么将不会进入catch语句
5:finally语句块的特殊之处就在于,前边的代码块就算有return等程序结束语句也会执行,通常放在finally语句块的往往是一些资源关闭,或者是日志。这个地方的判断是如果FileReader对象不为空的话就执行关闭资源的操作。

(2)如果认为单个字符读取不快捷,read()有一个重载的方法可以使用数组进行读取。

public static void main(String[] args) throws IOException {
        FileReader fReader = new FileReader(
                "C:\\Users\\Administrator\\Desktop\\abc.txt");
        char[] arr = new char[3];
        int len=0;
        while ((len = fReader.read(arr)) != -1) 
        {
            System.out.println(new String(arr));//应改成new String(arr,0,len)
        }
        fReader.close();
    }

分析:
1:创建一个数组,fReader.read(arr);意思就是将每一次读取的字符放进数组中,这样就可以实现一次读取多个字符。同样的如果返回值为-1也代表读取已经完成。
2:while循环的思想和上边代码一样,输出语句中也不能再重复写方法fReader.read(arr);
3:len = fReader.read(arr);这个方法的返回值是每一次读取字符的个数。返回为-1为读取完毕。
4:说一下为什么输出语句中需要使用String类的另一个构造方法。
这里写图片描述
解释:假设有六个字母需要进行读取,数组的大小是5,如果输出语句中是new String(arr),他最后输出来的是abcde和fghde,为什么多了两个字符呢,这个方法是将读取到的字符放进数组中,所以在第二次读取的时候,只有三个,最后两个没有办法覆盖。所以就会出现上述效果。所以使用构造方法new String(arr,0,len),意思为输出从0到len的数组的值。

1.2 —BufferedReader
前边使用FileReader类中的read方法的时候都是从底层输入流一个一个的读取字符,然后再启用从字节到字符的有效转换,我们可以使用加强类从字符输入流中读取文本缓冲各个字符,从而实现字符,数组和行的高效读取。
通常我们会用BufferedReader包装所有使用read方法会造成开销很大(效率低)的Reader类

上代码!

public static void main(String[] args) throws IOException {
        FileReader fReader = new FileReader(
                "C:\\Users\\Administrator\\Desktop\\abc.txt");
        BufferedReader br = new BufferedReader(fReader);
        String str;
        while ((str = br.readLine()) != null) {
            System.out.println(str);
        }
        br.close();
    }

分析:
1:创建一个BufferedReader对象,并将创建出FileReader对象包装进BufferedReader对象内部。
2:使用方法readLine()这个方法是用于读取整行的字符。并且返回一个字符串。当返回值为null的时候代表读取完毕。(此时这个读取指针就被拨到了最后一行,如果想要再读取一遍,或者是进行循环,就必须先关闭资源,再重新打开资源)
3:关闭资源的时候只需要关闭BufferedReader的资源即可。

二:输出流:
和字符输入流类似:java 中使用的字符输出流的基本类为Writer抽象类,通常实现字符输出流功能的都是他的一些子类;(输出流和输入流用法都类似,这里就不进行过多的解释了)
这里写图片描述

2.1—FileWriter

public static void main(String[] args) throws IOException {
        FileWriter fw = new FileWriter(
                "C:\\Users\\Administrator\\Desktop\\abc.txt");
        final String SEPARATOR = System.getProperty("line.separator");
        fw.write("aaa");
        fw.write("bbb");
        fw.write("ccc");
        fw.write(SEPARATOR);
        fw.write("ddd");
        fw.flush();
        fw.close();
    }

分析:
1:创建输出流对象,如果不存在输出流对象,那么会在参数所指定的路径中创建一个文件;
注意:在多次输出数据的时候就会出现第二次的覆盖第一次输出内容的现象。

FileWriter fw = new  FileWriter("C:\\Users\\Administrator\\Desktop\\abc.txt",true);

加一个参数true,就会将下一次输出的内容接在上一次输出的内容下边,而不是覆盖

2:final String SEPARATOR = System.getProperty(“line.separator”);是用来获取当前系统的换行符;(在加强版的BufferedWriter中会有方法进行替代);
3:方法write()将内容输入进指定文件中;
4:flush()方法,相当于是保存。
5:close()方法,必不可少的关闭资源方法。

2.2—-BufferedWriter
BufferedWriter的基本思想和BufferedReader的基本思想一致。重点介绍他的方法。

public static void main(String[] args) throws IOException { 
        FileWriter fw =null;
        fw = new  FileWriter("C:\\Users\\Administrator\\Desktop\\abc.txt");
        BufferedWriter bw = new BufferedWriter(fw);
        bw.write("qqqq");
        bw.newLine();//加强版的输出流的换行操作。。。
        bw.write("qdddd");
        bw.flush();
        }

分析:
1:和输入流一样,创建一个BufferedWriter对象,包装FileWriter对象。
2:使用wirte()方法进行输出数据;
3:在BufferedWriter中换行操作是newLine()方法;
4:注意在BufferedWriter中不需要使用close方法关闭资源,直接使用flush方法就可以刷新和关闭资源。

字节流

字符流是依赖于字节流实现的,通常在使用的时候读取汉字等字符是使用字符流来进行输入输出,而不使用字节流:字节流是按照字节输入输出的,容易出现乱码。当进行输入输出图片,音频等可以采用字节流。

在方法和思想上是和字符流一样的,所以也只进行简单地介绍:

一:输入流:
这里写图片描述

1.(1)FileInputStream

public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("C:\\Users\\Administrator\\Desktop\\abc.txt");
        byte[] b = new byte[5];
        int res = 0;
        while ((res = fis.read(b)) != -1) {
            System.out.println(new String(b, 0, res));
        }
        fis.close();
    }

1.(2)BufferedInputStream

注意:BufferedInputStream中没有readLine()方法,可以使用数组的方法进行读取。

byte[] b = new byte[10];
int len = bis.read(b);

二:输出流
这里写图片描述
字节输出流的方法使用和字符输出流的使用大致类似基本思想都是一致的。使用时应该结合API进行使用。

最后的总结

一:字符流
1:字符输入流
* 1)FileReader
* 2)BufferedReader
2:字符输出流
* 1)FileWriter
* 2)BufferedWriter
二:字节流
1:字节输入流
*1)FileInputStream
*2)BufferedInputStream
2:字节输出流
* 1)FileOutputStream
*2)BufferedOutputStream

猜你喜欢

转载自blog.csdn.net/sun_DongLiang/article/details/81260451