Java InputStream詳解

InputStream 是個抽象類。

public abstract class InputStream implements Closeable 

    public int read(byte b[], int off, int len) throws IOException {
        if (b == null) {
            throw new NullPointerException();
        } else if (off < 0 || len < 0 || len > b.length - off) {
            throw new IndexOutOfBoundsException();
        } else if (len == 0) {
            return 0;
        }

        int c = read();
        if (c == -1) {
            return -1;
        }
        b[off] = (byte)c;

        int i = 1;
        try {
            for (; i < len ; i++) {
                c = read();
                if (c == -1) {
                    break;
                }
                b[off + i] = (byte)c;
            }
        } catch (IOException ee) {
        }
        return i;
    }

核心實現了這個read 方法。

他有以下實現的子類:

FileInputSteam: 讀取文件

BufferedInputStream:帶有緩存功能

ByteArrayInputStream 一個字節讀取流

FilterInputStream 一個包裹了inputSteam 的流

PushbackInputStream 可以返回上一個讀取位置的流:

PipedInputStream 管道流

我們看到上面很多類,其實對於讀文件來說,核心是FileInputStream.其他的BufferedInputStream 只是提供了一個緩存的功能,他沒有具體實現輸出流的東西。就像是一個裝飾品。比如我們可以這樣用:new BufferedInputStream(new FileInputStream)

這樣來學io 的話,你只需要知道讀文件用FileInputStream,如果想要有緩存功能,就用BufferInputStreme 包裹一下。

什麼是裝飾模式?

你可以根據 自己的需求,去添加功能,這些功能都是可以自由組合的。這樣可以避免大量的重複類。

假設Beverage是一個抽象類,它被所有在一個咖啡店裏賣的飲料繼承。Beverage有個抽象方法cost,所有的子類都要實現這個抽象方法,計算它們的價格。現在有四個最基本的咖啡:HouseBlend,DarkRoast,Decaf,Espresso他們都繼承自Beverage,現在的需求是說在四個最基本的咖啡裏,每個都可以隨便地添加調味品,像steamed milk,soy,還有mocha最後是加上whipped milk。如果是說按繼承來實現這種幾個調味品跟原來咖啡的組合的話,會有很多種組合。但是我們每個類負責不用的功能,必須mileBeverage負責裝牛奶,那麼我們就可以自己寫程序的時候,按照需要去組合自己想要的產品。

看不懂io 的時候,臥槽,這麼多類,我該用哪個?
看懂了io 的裝飾模式,臥槽,寫的真好。

一些示例:

ObjectStream 相關

/**
 * =======================================================================================
 * 作    者:caoxinyu
 * 創建日期:2020/3/15.
 * 類的作用:
 * 修訂歷史:
 * =======================================================================================
 */
public class Persion implements Serializable {


    private static final long serialVersionUID = -4200702238120282380L;
    public String mFname;
    public int age;
    //transient 的字段不會被序列化保存
    public transient String secName;
    public String tridName;

    public Persion(String Fname, int age,String secName) {
        this.mFname = Fname;
        this.age = age;
        this.secName = secName;
    }


}

//ObjectOutputStream 寫入
                Persion persion = new Persion("a",20,"ffff");
                try {
                    File file = new File(FilePath);
                    if (!file.exists()) {
                        file.createNewFile();
                    }
                    mObjectOutputStream = new ObjectOutputStream(new FileOutputStream(FilePath));
                    mObjectOutputStream.writeObject(persion);
                    mObjectOutputStream.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }finally {
                    try {
                        if (mObjectOutputStream != null) {
                            mObjectOutputStream.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

InputStream

try {
                    //ObjectInputStream 讀取

                    ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(FilePath));
                    Persion p = (Persion) objectInputStream.readObject();
//                    Persion2 p2 = (Persion2) objectInputStream.readObject();
                    Toast.makeText(getActivity(), p.mFname, Toast.LENGTH_SHORT).show();
                } catch (IOException | ClassNotFoundException e) {
                    e.printStackTrace();
                }
    /**
     * 使用inputStream 讀取文件內容
     */
    public void testInputStream(){
        InputStream inputStream = null;
        String str = null;

        try {
            String filePath = "/sdcard/vlog.txt";
            inputStream= new FileInputStream(filePath);
            byte[] result = null;
            byte[] readTemp = new byte[4096];
            int read ;
            // 讀取流
            while ((read =inputStream.read(readTemp))!= -1) {
                //第一次讀取
                if (result == null) {
                    result = new byte[read];
                    System.arraycopy(readTemp,0,result,0,read);
                }else {
                    byte[] temp = new byte[result.length + read];
                    System.arraycopy(result,0,temp,0,result.length);
                    System.arraycopy(readTemp,0,temp,result.length,read);
                    result = temp;
                }
            }
            str = new String(result);
            Log.d(TAG,str);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

FileReader

    /**
     * 使用reader 接口類型的api 讀取文件
     */
    public void testReader(){
        FileReader fileReader = null;
        try {
            fileReader = new FileReader("/sdcard/vlog.txt");
            BufferedReader bufferedReader = new BufferedReader(fileReader);
            StringBuilder stringBuilder = new StringBuilder();
            String str;
            while ((str = bufferedReader.readLine()) != null){
                stringBuilder.append(str);
                stringBuilder.append("\r\n");
            }
            String s = stringBuilder.toString();
            Log.d(TAG, s);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if (fileReader != null) {
                    fileReader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

OutPutStream

    /**
     * FileOutputStream
     */
    public void testOutPutStream(){
        BufferedOutputStream bufferedOutputStream = null;
        try {
            String name = "/sdcard/vlog.txt";
            File file = new File(name);
            file.createNewFile();
            bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(name,true));
            String test = "我哦見附件sad交集啊發生了可點擊撒反對建安費的手機上道路擴建";
            bufferedOutputStream.write(test.getBytes());
            bufferedOutputStream.flush();

            //printStream 可以寫換行等一系列操作 和 printWriter 差不多
            PrintStream printStream = new PrintStream(bufferedOutputStream, false);
            printStream.println();
            printStream.println(2222);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (bufferedOutputStream != null) {
                try {
                    bufferedOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

OutputStreamWriter

    /**
     * OutputStreamWriter
     */
    public void testWriter(){
        BufferedWriter bufferedWriter = null;
        try {
            String name = "/sdcard/vlog.txt";
            File file = new File(name);
            file.createNewFile();
            bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("/sdcard/vlog.txt",true)));
            bufferedWriter.write("j是家風看東方就是打開今飛凱達科技福建省");
            bufferedWriter.newLine();
            bufferedWriter.append("afdsfsafsad");
            bufferedWriter.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                bufferedWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

PrintWriter

    /**
     * PrintWriter  和 printStream差不多
     */
    public void testWriter2(){
        PrintWriter bufferedWriter = null;
        try {
            String name = "/sdcard/vlog.txt";
            File file = new File(name);
            file.createNewFile();
            bufferedWriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream("/sdcard/vlog.txt",true))));
            bufferedWriter.write("j是家風看東方就是打開今飛凱達科技福建省");
            bufferedWriter.println();
            bufferedWriter.format("23%s","真的");
            bufferedWriter.append("afdsfsafsad");
            bufferedWriter.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (bufferedWriter != null) {
                bufferedWriter.close();
            }
        }
    }

RandomAccessFile

    /**
     * RandomAccessFile
     */
    public void testAccess(){
        RandomAccessFile randomAccessFile = null;
        try {
            randomAccessFile = new RandomAccessFile("/sdcard/vlog.txt","rw");

            //如果你想要在文件末尾增加  那麼需要把當前的位置挪到最後
            randomAccessFile.seek(randomAccessFile.length());
            randomAccessFile.writeUTF("aaa");
            //randomAccessFile 返回的長度是實時的  如果你寫了 那麼就返回你這麼多
            randomAccessFile.length();

            randomAccessFile.writeInt(2000);
            randomAccessFile.writeInt(2900);


            //如果文件的長度就是4343 那麼你要讀取4344個長度 直接就會eofException
            byte[] bytes = new byte[4344];
            randomAccessFile.readFully(bytes);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException | NullPointerException e2) {
            e2.printStackTrace();
        }finally {
            try {
                if (randomAccessFile != null) {
                    randomAccessFile.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        LogToFile.init(getContext());
        LogToFile.log("aaa","bbb");
    }

參考:
https://www.jianshu.com/p/613ee60e08b4

https://www.cnblogs.com/heartstage/p/3391070.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章