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

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