java BIO詳解

概念

流是一組有順序的,有起點(diǎn)和終點(diǎn)的字節(jié)集合,是對(duì)數(shù)據(jù)傳輸?shù)目偡Q或抽象。即數(shù)據(jù)在兩設(shè)備間的傳輸稱為流,流的本質(zhì)是數(shù)據(jù)傳輸,根據(jù)數(shù)據(jù)傳輸特性將流抽象為各種類,方便更直觀的進(jìn)行數(shù)據(jù)操作

IO類概述表

IO類概述表.png

常見(jiàn)流

  • RandomAccessFile 跳躍讀文件,原理是調(diào)用一個(gè)native方法移動(dòng)指向當(dāng)前操作字節(jié)數(shù)組指針的位置,所以一般對(duì)于流的操作我們就要按照順序讀寫,就可以獲得完整的文件
package com.rockjh.jdk.io;

import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * @author rockjh 【rockjh@aliyun.com】
 * @Description: 隨機(jī)讀寫文件操作demo
 * @Date 2017/12/14 15:52
 **/
public class RandomAccessFileDemo {

    /**
     *從這個(gè)類我們可以知道,在底層一直有一個(gè)pos指向當(dāng)前正在讀或者寫的位置,所以一般對(duì)于流的操作我們就要按照順序執(zhí)行
     * @param args
     * @throws IOException
     */
    public static void main(String[] args){
        byte[] value= new byte[4];
        try {
            //獲取resource路徑
            String path=RandomAccessFileDemo.class.getResource("/").getPath();
            RandomAccessFile randomAccessFile = new RandomAccessFile(path+"RandomAccessFileDemo.txt","r");
            //移動(dòng)閱讀的指針,注意漢字在不同編碼里面占的字節(jié)數(shù)不一樣,一般是2-4字節(jié)
            randomAccessFile.skipBytes(3);
            randomAccessFile.read(value);
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println(new String(value));
    }

}

  • 管道流主要是為多個(gè)線程提供通信,一個(gè)輸入管道,一個(gè)輸出管道,一邊輸入一邊輸出
package com.rockjh.jdk.io;


import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

/**
 * @author rockjh 【rockjh@aliyun.com】
 * @Description:
 * @Date 2017/12/14 16:42
 **/
public class PipeStreamDemo {
    public static void main(String[] args) throws IOException {
        PipedOutputStream pipedOutputStream=new PipedOutputStream();
        PipedInputStream pipedInputStream=new PipedInputStream(pipedOutputStream);
        Thread thread1=new Thread(() -> {
            try {
                pipedOutputStream.write("hello world".getBytes("utf-8"));
            } catch (IOException e) {
                e.printStackTrace();
            }
        },"thread1");
        Thread thread2=new Thread(()->{

            try {
                byte[] value=new byte[100];
                //一直等待讀取狀態(tài)為wait,直到有值
                pipedInputStream.read(value);
                System.out.println(new String(value));
            } catch (IOException e) {
                e.printStackTrace();
            }
        },"thread2");
        thread1.start();
        thread2.start();
    }
}
  • FileInputStream文件流
package com.rockjh.jdk.io;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;

/**
 * @author rockjh 【rockjh@aliyun.com】
 * @Description: 文件類demo
 * @Date 2017/12/14 21:16
 **/
public class FileDemo {

    public static void main(String[] args){
        try {
            File file=new File(FileDemo.class.getResource("/").getPath()+"fileDemo.txt");
            if(!file.exists()){
                file.createNewFile();
            }
            OutputStreamWriter output=new FileWriter(file);
            char[] value=new char[]{'世','界','你','好'};
            output.write(value);
            output.flush();
            System.out.println(file.isDirectory());
            System.out.println(file.list());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

  • ByteArrayOutputStream允許我們以字節(jié)的形式獲取值toByteArray()方法

  • ObjectOutputStream主要是對(duì)象序列化存儲(chǔ)的一個(gè)東西,他需要一個(gè)將值輸出在構(gòu)造參數(shù)中的流中,相當(dāng)于是一個(gè)包裝流吧

package com.rockjh.jdk.io;

import com.rockjh.jdk.bean.People;

import java.io.*;

/**
 * @author rockjh 【rockjh@aliyun.com】
 * @Description: 對(duì)象流,序列化對(duì)象
 * @Date 2017/12/14 21:30
 **/
public class ObjectStreamDemo {

    public static void main(String[] args){
        //對(duì)象序列化和反序列化
        try {
            People people=new People("rockjh",23,"18280193473");
            ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream(ObjectStreamDemo.class.getResource("").getPath()+"object.data"));
            output.writeObject(people);
            output.flush();
            ObjectInputStream input = new ObjectInputStream(new FileInputStream(ObjectStreamDemo.class.getResource("").getPath()+"object.data"));
            people = (People) input.readObject();
            System.out.println(people);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }


        try {
            //對(duì)象轉(zhuǎn)byte,byte轉(zhuǎn)對(duì)象
            People people=new People("rockjh",23,"18280193473");
            System.out.println((People)byteToObj(objToByte(people)));
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * 字節(jié)轉(zhuǎn)對(duì)象
     * @param bytes
     * @param <T>
     * @return
     * @throws IOException
     * @throws ClassNotFoundException
     */
    private static <T> T byteToObj(byte[] bytes) throws IOException, ClassNotFoundException {
        ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(bytes);
        ObjectInputStream inputStream=new ObjectInputStream(byteArrayInputStream);
        T t= (T) inputStream.readObject();
        return t;
    }

    /**
     * 字節(jié)轉(zhuǎn)對(duì)象
     * @param obj
     * @param <T>
     * @return
     * @throws IOException
     * @throws ClassNotFoundException
     */
    private static <T> byte[] objToByte(T obj) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
        ObjectOutputStream outputStream=new ObjectOutputStream(byteArrayOutputStream);
        outputStream.writeObject(obj);
        return byteArrayOutputStream.toByteArray();
    }
}
  • BufferedOutputStream為輸出流提供緩存,能提供很多IO性能,不用每次都去磁盤或者網(wǎng)絡(luò)一次讀取一個(gè)或者幾個(gè)字節(jié)

  • DataInputStream包裝輸入流,可以使得輸入流直接輸入幾種基本數(shù)據(jù)類型,而不是只能輸入字節(jié)數(shù)據(jù)

  • System.in, System.out, System.error(注:Java標(biāo)準(zhǔn)輸入、輸出、錯(cuò)誤輸出)

  • PushBackInputStream可以回退一個(gè)已讀的流

  • java7新增在try塊中自動(dòng)關(guān)閉流,包括jdbc等

不管輸入流還是輸出流都要有一個(gè)數(shù)據(jù)源,最常見(jiàn)的一個(gè)列子就是實(shí)例化一個(gè)輸入流,向其中寫東西,然后輸出流,輸出到文件或者打印,輸入流是read,輸出流是write

路徑

  • Object.class.getResource("/").getPath();獲取classpath路徑

  • Object.class.getResource("").getPath();獲取當(dāng)前類路徑,即包括包

實(shí)例源代碼 前往下載

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、流的概念和作用。 流是一種有順序的,有起點(diǎn)和終點(diǎn)的字節(jié)集合,是對(duì)數(shù)據(jù)傳輸?shù)目偝苫虺橄?。即?shù)據(jù)在兩設(shè)備之間的傳輸...
    布魯斯不吐絲閱讀 10,320評(píng)論 2 95
  • 在經(jīng)過(guò)一次沒(méi)有準(zhǔn)備的面試后,發(fā)現(xiàn)自己雖然寫了兩年的android代碼,基礎(chǔ)知識(shí)卻忘的差不多了。這是程序員的大忌,沒(méi)...
    猿來(lái)如癡閱讀 3,122評(píng)論 3 10
  • tags:io categories:總結(jié) date: 2017-03-28 22:49:50 不僅僅在JAVA領(lǐng)...
    行徑行閱讀 2,304評(píng)論 0 3
  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂(lè)視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,818評(píng)論 11 349
  • 趙道新批評(píng)武林門派之弊 前年,機(jī)緣巧合看過(guò)一篇趙道新的訪談錄,言之有理,稍加整理,傳至豆瓣,題為《趙道新批評(píng)中國(guó)武...
    素履閱讀 2,123評(píng)論 1 2

友情鏈接更多精彩內(nèi)容