Java BIO学习总结

1、流的概念和作用
流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。

注意:流只能顺序访问,不能像数组那样随机存取

2、流的分类
根据处理数据类型的不同分为:字符流和字节流
根据数据流向不同分为:输入流和输出流

3、字符流和字节流
字符流的由来: 因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表
字节流和字符流的区别:
读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。
结论:只要是处理纯文本数据,就优先考虑使用字符流。 除此之外都使用字节流。

4、输入流和输出流

输入流可以理解为向内存输入,输出流可以理解为从内存输出
InputStream或者Reader是从数据源读取数据(到内存中),OutputStream或者Writer是将数据(从内存中)写入到目标媒介

典型的数据源或目标媒介有:文件、管道、网络连接、内存缓存、控制台…

注意:Java IO流通常是基于字节或者基于字符的。字节流通常以“stream”命名,比如InputStream和OutputStream。除了DataInputStream 和DataOutputStream 还能够读写int, long, float和double类型的值以外,其他流在一个操作时间内只能读取或者写入一个原始字节

5、组合流

一次读取一个字节是很慢的,借助缓冲可以从磁盘中一次读取一大块数据,然后从读到的数据块中获取字节。为了实现缓冲,可以把InputStream包装到BufferedInputStream中。例如
InputStream input = new BufferedInputStream(new FileInputStream(“xxx”));

6、字符流与字节流之间的转换

例如 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String strLine = bufferedReader.readLine();

借助InputStreamReader可以将字节流转换为字符流

7、常用的几个类说明

// 区分是字符流还是字节流
        // 以InputStream或OutputStream结尾是字节流,以Reader或Writer结尾是字符流
        // 区分是输入还是输出
        // 以Input或Read开头是输入,以Output或Writer结尾时输出

        // byte stream
        //input stream
        String testStr = "heh";
        StringBufferInputStream strBufferInputStream = new StringBufferInputStream(testStr); //从String中读取数据到Stream中
        strBufferInputStream.read(b); // 从Stream中逐个字节读取

        File testFile = new File("filePath");
        FileInputStream fileInputStream = new FileInputStream(testFile); //从文件中读取数据到Stream中
        byte[] storeByte = new byte[10];
        fileInputStream.read(storeByte);    // 从Stream中逐个字节读取  // 文件结尾返回 -1

        byte[] testByte = new byte[10];
        ByteArrayInputStream byteArrInputStream = new ByteArrayInputStream(testByte); // 从ByteArray中读取数据到Stream中
        byteArrInputStream.read(testByte); // 从Stream中逐个字节读取

        // output stream
        File testFile2 = new File("filePath");  // 写入到哪个文件中去
        FileOutputStream fileOutputStream = new FileOutputStream(testFile2);
        byte[] srcByte = new byte[10];
        fileOutputStream.write(srcByte); // 将byteArray写入到指定文件中

        ByteArrayOutputStream byteArrOutputStream = new ByteArrayOutputStream();
        byte[] srcByte2 = new byte[10];
        byteArrOutputStream.write(srcByte2); // 将byteArray写入到Stream中

        // character stream
        String encoding = "utf-8";
        File testFile3 = new File("filePath");
        FileInputStream fileInputStream = new FileInputStream(testFile3);
        InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream,encoding);
        char[] characters = new char[1024];
        inputStreamReader.read(characters);  // 逐个字符读取,从字节流中读取并根据编码转换成字符,存入字符数组中

        BufferedReader bufferReader = new BufferedReader(inputStreamReader);
        bufferReader.readLine(); // 按行读取字符  // 文件结尾返回null

5、读取实例

/**
     * BIO模式
     * 从输入流中读取指定长度的数据到字节数组中
     * 如何确定字节数组长度:file.length()返回字节数组长度
     * 如何保证文件内容全部读入:字节数组长度与文件内容长度相等
     * @param fileName
     * @return
     * @throws IOException
     */
    public static byte[] readByBytes(String fileName) throws IOException{
        File file = new File(fileName);
        InputStream fileInputStream = new FileInputStream(file);
        long length = file.length(); // return length in bytes
        System.out.println("file length:" + length);
        byte[] fileBytes = new byte[(int)length];
        int result = fileInputStream.read(fileBytes);
        fileInputStream.close(); // must close
        if(result != length){
            throw new IOException("can't read all," + result + "!=" + length);
        }
        System.out.println("read length: " + result);
        return fileBytes;
    }

    /**
     * BIO模式
     * 逐个字节读取
     * 如何确定字节数组长度:file.length()返回字节数
     * 如何保证文件内容全部被读取:比较文件长度与读取字节数组长度是否相等
     * @param fileName
     * @return
     * @throws IOException
     */
    public static byte[] readByOneByte(String fileName) throws IOException{
        File file = new File(fileName);
        FileInputStream fileInputStream = new FileInputStream(file);
        long length = file.length(); // return length in bytes
        System.out.println("file length:" + length);
        byte[] fileBytes = new byte[(int)length];
        int resultByte = fileInputStream.read();
        int i = 0; // array index
        while(resultByte != -1){
            byte tempByte = (byte)resultByte;
            fileBytes[i] = tempByte;
            i++;
            resultByte = fileInputStream.read();
        }
        fileInputStream.close(); // must close
        if(fileBytes.length != length){
            throw new IOException("can't read all," + fileBytes.length + "!=" + length);
        }
        System.out.println("read length: " + fileBytes.length);
        return fileBytes;
    }

    /**
     * BIO模式
     * FileReader逐个字符读取文件,FileReader extends InputStreamReader
     * 读取文件中内容到字符数组中
     * 如何确定字符数组长度:
     * FileReader不能自定义编码读取
     * 此方法也可以用于读取二进制文件,只不过读取出来有很多乱码
     * @param fileName
     * @return
     * @throws IOException
     */
    public static char[] readByOneCharWithDefaultEncoding(String fileName) throws IOException{
        File file = new File(fileName);
        FileReader fileReader = new FileReader(file); // 不能自定义编码,内部默认采用系统的编码
        System.out.println("当前采用编码: " + fileReader.getEncoding()); 
        char[] charcters = new char[1024];
        int result = fileReader.read();  // 逐个字符读取,不能按行读取
        int i = 0;
        while(result != -1 && i < 1024){
            char temp = (char)result;
            charcters[i] = temp;
            i++;
            result = fileReader.read();
        }
        fileReader.close();
        return charcters;
    }


    /**
     * BIO模式
     * 逐个字符读取文件
     * 读取文件中内容到字符数组中
     * 如何确定字符数组长度:
     * 此方法也可以用于读取二进制文件,只不过读取出来有很多乱码
     * @param fileName
     * @return
     * @throws IOException
     */
    public static char[] readByOneCharWithCustomEncoding(String fileName,String encoding) throws IOException{
        File file = new File(fileName);
        InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream(file),encoding);
        System.out.println("当前采用编码: " + inputStreamReader.getEncoding());
        char[] charcters = new char[1024];
        int result = inputStreamReader.read();  // 逐个字符读取,不能按行读取
        int i = 0;
        while(result != -1 && i < 1024){
            char temp = (char)result;
            charcters[i] = temp;
            i++;
            result = inputStreamReader.read();
        }
        inputStreamReader.close();
        return charcters;
    }

    /**
     * BIO模式
     * 使用InputStreamReader作为字节流与字符流之间的桥梁
     * 使用BufferedReader提升读取效率
     * @param fileName
     * @throws IOException
     */
    public static void readByLine(String fileName) throws IOException{
        String encoding = "utf-8"; // 既然是读取字符,肯定会涉及到编码问题
        File file = new File(fileName);
        if(file.isFile() && file.exists()){
            InputStream inputStream = new FileInputStream(file);
            // inputStreamReader是连接字节流和字符流的桥梁
            // 读取指定数量的字节,并按照传入的编码转换成字符
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream,encoding);
            // 使用BufferedReader的好处是可以一次读取多个字符(而不是一个字符)
            BufferedReader bufferReader = new BufferedReader(inputStreamReader);
            String readLine = bufferReader.readLine();
            while( readLine != null) {
                System.out.println(readLine);
                readLine = bufferReader.readLine();
            }
            bufferReader.close();
        }
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值