End

IO流 简介 总结 API 案例-1

本文地址


目录

IO流 简介 总结 API 案例-1

IO 流

简介

IO流用来处理设备之间的数据传输,Java对数据的操作是通过流的方式。

输入流和输出流相对于内存设备而言。

  • 将外设中的数据读取到内存中:输入
  • 将内存中的数据写入到外设中:输出

流按操作的数据不同可分为两种:字节流与字符流。

字符流的由来:字节流读取文字字节数据后,不直接操作而是先查指定的编码表(默认的码表),获取对应的文字,再对这个文字进行操作。

简单说:字符流 = 字节流 + 编码表。

IO流基类:

  • 字节流的抽象基类:InputStream,OutputStream
  • 字符流的抽象基类:Reader,Writer

关闭流的正确方式

public void closeStream() {
    InputStream inputStream = null;
    try {
        inputStream = new FileInputStream("");
        //...
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if (inputStream != null) {
                inputStream.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

关闭流的封装方法

public static void closeStream(Closeable... closeable) {
    for (Closeable c : closeable) {
        if (c != null) {
            try {
                c.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

InputStream 转 String 的方式

public static String inputStreamtoString(InputStream inputStream) throws IOException {
    byte[] bytes = new byte[inputStream.available()]; //一次性读取全部内容
    inputStream.read(bytes);
    return new String(bytes, CHARSET);
}

public static String inputStreamtoStringByBuffer(InputStream inputStream) throws IOException {
    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, CHARSET));
    StringBuilder sb = new StringBuilder(); //一次读取一行内容
    String line;
    while ((line = reader.readLine()) != null) {
        sb.append(line).append("\n");
    }
    return sb.toString();
}

public static String inputStreamtoStringByByteArray(InputStream inputStream) throws IOException {
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024]; //一次读取固定长度内容,相对来说最高效的方式
    int length;
    while ((length = inputStream.read(buffer)) != -1) {
        outputStream.write(buffer, 0, length);
    }
    return outputStream.toString(CHARSET);
}

转换流

  • 数据从【硬盘】中读入【内存】时,顺序是:文件流(字节流,FileInputStream)->转换流(即InputStreamReader)->缓冲流(字符流,BufferedReader),所以InputStreamReader是字节流到字符流的桥梁
  • 数据从【内存】中写入【硬盘】时,顺序是:缓冲流(字符流,BufferedWriter)->转化流(即OutputStreamWriter)->文件流(字节流,FileOutputStream),所以OutputStreamWriter是字符流到字节流的桥梁

InputStreamReader

InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。

每次调用 InputStreamReader 中的一个 read() 方法都会导致从底层输入流读取一个或多个字节。要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。

为了达到最高效率,可要考虑在 BufferedReader 内包装 InputStreamReader。例如:

BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

继承关系

  • class InputStreamReader extends Reader
  • 所有已实现的接口:Closeable, Readable
  • 直接已知子类:FileReader

构造方法

  • InputStreamReader(InputStream in) 创建一个使用默认字符集的 InputStreamReader。
  • InputStreamReader(InputStream in, Charset cs) 创建使用给定字符集的 InputStreamReader。
  • InputStreamReader(InputStream in, CharsetDecoder dec) 创建使用给定字符集解码器的 InputStreamReader。
  • InputStreamReader(InputStream in, String charsetName) 创建使用指定字符集的 InputStreamReader。

常用方法

  • void close() 关闭该流并释放与之关联的所有资源。关闭以前关闭的流无效。
  • String getEncoding() 返回此流使用的字符编码的名称。如果流已经关闭,则返回 null
  • int read() 读取单个字符。返回读取的字符数,如果已到达流的末尾,则返回 -1
  • int read(char[] cbuf) 将读取到的字符存到数组中。返回读取的字符数,如果已到达流的末尾,则返回 -1
  • int read(char[] cbuf, int offset, int length) 将字符读入数组中的某一部分。返回读取的字符数,如果已到达流的末尾,则返回 -1
  • boolean ready() 判断此流是否已经准备好用于读取。如果其输入缓冲区不为空,或者可从底层字节流读取字节,则 InputStreamReader 已做好被读取准备。
  • 从类 java.io.Reader 继承的方法:mark, markSupported, read, read, reset, skip

OutputStreamWriter

OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。

每次调用 write() 方法都会导致在给定字符(或字符集)上调用编码转换器。在写入底层输出流之前,得到的这些字节将在缓冲区中累积。可以指定此缓冲区的大小,不过,默认的缓冲区对多数用途来说已足够大。注意,传递给 write() 方法的字符没有缓冲。

为了获得最高效率,可考虑将 OutputStreamWriter 包装到 BufferedWriter 中,以避免频繁调用转换器。例如:

BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));

构造方法

  • OutputStreamWriter(OutputStream out) 创建使用默认字符编码的 OutputStreamWriter。
  • OutputStreamWriter(OutputStream out, Charset cs) 创建使用给定字符集的 OutputStreamWriter。
  • OutputStreamWriter(OutputStream out, CharsetEncoder enc) 创建使用给定字符集编码器的 OutputStreamWriter。
  • OutputStreamWriter(OutputStream out, String charsetName) 创建使用指定字符集的 OutputStreamWriter。

常用方法

  • void close() 关闭此流,但要先刷新它。关闭以前关闭的流无效。
  • void flush() 刷新该流的缓冲。
  • String getEncoding() 返回此流使用的字符编码的名称。如果流已经关闭,则可能返回 null
  • void write(char[] cbuf, int off, int len) 写入字符数组的某一部分。
  • void write(int c) 写入单个字符。
  • void write(String str, int off, int len) 写入字符串的某一部分。
  • 从类 java.io.Writer 继承的方法:append, append, append, write, write

测试代码

public static void test() {
    try {
        //写文件,不带缓冲区
        OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(FILE_PATH), CHARSET);
        writer.write("\n包青天abc-" + FORMAT.format(new Date()));
        writer.flush();
        writer.close();

        //写文件,带缓冲区
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(FILE_PATH, true), CHARSET));//可以续写
        bufferedWriter.write("\n白乾涛abc-" + FORMAT.format(new Date()));
        bufferedWriter.close();

        //读文件,不带缓冲区
        InputStreamReader reader = new InputStreamReader(new FileInputStream(FILE_PATH), CHARSET);
        char[] chars = new char[1024];
        int length = reader.read(chars);
        System.out.println(new String(chars, 0, length));
        reader.close();

        //读文件,带缓冲区
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(FILE_PATH), CHARSET));
        String line;
        while ((line = bufferedReader.readLine()) != null) {
            System.out.println(line);
        }
        bufferedReader.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

文件读写流 File-Stream

  • 文件字节读写流:FileInputStream、FileOutputStream
  • 文件字符读写流:FileReader、FileWriter

FileInputStream

FileInputStream 从文件系统中的某个文件中获得输入字节。哪些文件可用取决于主机环境。

FileInputStream 用于读取诸如图像数据之类的原始字节流。要读取字符流,请考虑使用 FileReader。

继承关系

  • class FileInputStream extends InputStream
  • 所有已实现的接口:Closeable

构造方法

  • FileInputStream(File file) 通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。
  • FileInputStream(FileDescriptor fdObj) 通过使用文件描述符 fdObj 创建一个 FileInputStream,该文件描述符表示到文件系统中某个实际文件的现有连接。
  • FileInputStream(String name) 通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。

如果指定文件不存在,或者它是一个目录,抑或因为其他某些原因而无法打开进行读取,则抛出 FileNotFoundException。

常用方法

  • int available() 返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取(或跳过)的估计剩余字节数。
  • void close() 关闭此文件输入流并释放与此流有关的所有系统资源。
  • FileChannel getChannel() 返回与此文件输入流有关的唯一 FileChannel 对象(文件通道对象)。
  • FileDescriptor getFD() 返回表示到文件系统中实际文件的连接的 FileDescriptor 对象(文件描述符对象),该文件系统正被此 FileInputStream 使用。
  • int read() 从此输入流中读取一个数据字节。如果没有输入可用,则此方法将阻塞。返回下一个数据字节;如果已到达文件末尾,则返回 -1。
  • int read(byte[] b) 从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。在某些输入可用之前,此方法将阻塞。返回读入缓冲区的字节总数,如果因为已经到达文件末尾而没有更多的数据,则返回 -1。
  • int read(byte[] b, int off, int len) 从此输入流中将最多 len 个字节的数据读入一个 byte 数组中。
  • long skip(long n) 从输入流中跳过并丢弃 n 个字节的数据。
  • 从类 java.io.InputStream 继承的方法:mark, markSupported, reset

FileOutputStream

文件输出流是用于将数据写入 File 或 FileDescriptor 的输出流。文件是否可用或能否可以被创建取决于基础平台。特别是某些平台一次只允许一个 FileOutputStream(或其他文件写入对象)打开文件进行写入。在这种情况下,如果所涉及的文件已经打开,则此类中的构造方法将失败。

FileOutputStream 用于写入诸如图像数据之类的原始字节的流。要写入字符流,请考虑使用 FileWriter。

继承关系

  • class FileOutputStream extends OutputStream
  • 所有已实现的接口:Closeable, Flushable

构造方法

  • FileOutputStream(File file) 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。创建一个新 FileDescriptor 对象来表示此文件连接。
  • FileOutputStream(File file, boolean append) 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。如果第二个参数为 true,则将字节写入文件末尾处,而不是写入文件开始处。创建一个新 FileDescriptor 对象来表示此文件连接。
  • FileOutputStream(FileDescriptor fdObj) 创建一个向指定文件描述符处写入数据的输出文件流,该文件描述符表示一个到文件系统中的某个实际文件的现有连接。
  • FileOutputStream(String name) 创建一个向具有指定名称的文件中写入数据的输出文件流。
  • FileOutputStream(String name, boolean append) 创建一个向具有指定 name 的文件中写入数据的输出文件流。如果第二个参数为 true,则将字节写入文件末尾处,而不是写入文件开始处。创建一个新 FileDescriptor 对象来表示此文件连接。

如果该文件存在,但它是一个目录,而不是一个常规文件;或者该文件不存在,但无法创建它;抑或因为其他某些原因而无法打开它,则抛出 FileNotFoundException。

常用方法

  • void close() 关闭此文件输出流并释放与此流有关的所有系统资源。
  • protected void finalize() 清理到文件的连接,并确保在不再引用此文件输出流时调用此流的 close 方法。
  • FileChannel getChannel() 返回与此文件输出流有关的唯一 FileChannel 对象。
  • FileDescriptor getFD() 返回与此流有关的文件描述符。
  • void write(byte[] b) 将 b.length 个字节从指定 byte 数组写入此文件输出流中。
  • void write(byte[] b, int off, int len) 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。
  • void write(int b) 将指定字节写入此文件输出流。
  • 从类 java.io.OutputStream 继承的方法:flush

FileReader(转换流)

用来读取字符文件的便捷类。此类的构造方法假定默认字符编码默认字节缓冲区大小都是适当的。要自己指定这些值,可以先在 FileInputStream 上构造一个 InputStreamReader。

FileReader 用于读取字符流。要读取原始字节流,请考虑使用 FileInputStream。

继承关系

  • class FileReader extends InputStreamReader
  • 所有已实现的接口:Closeable, Readable

构造方法

  • FileReader(File file) 在给定从中读取数据的 File 的情况下创建一个新 FileReader。
  • FileReader(FileDescriptor fd) 在给定从中读取数据的 FileDescriptor 的情况下创建一个新 FileReader。
  • FileReader(String fileName) 在给定从中读取数据的文件名的情况下创建一个新 FileReader。

常用方法

  • 从类 java.io.Reader 继承的方法:mark, markSupported, read, read, reset, skip
  • 从类 java.io.InputStreamReader 继承的方法:close, getEncoding, read, read, ready

FileWriter(转换流)

用来写入字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是可接受的。要自己指定这些值,可以先在 FileOutputStream 上构造一个 OutputStreamWriter。

文件是否可用或是否可以被创建取决于底层平台。特别是某些平台一次只允许一个 FileWriter(或其他文件写入对象)打开文件进行写入。在这种情况下,如果所涉及的文件已经打开,则此类中的构造方法将失败。

FileWriter 用于写入字符流。要写入原始字节流,请考虑使用 FileOutputStream。

继承关系

  • class FileWriter extends OutputStreamWriter
  • 所有已实现的接口:Closeable, Flushable, Appendable

构造方法

  • FileWriter(File file) 根据给定的 File 对象构造一个 FileWriter 对象。
  • FileWriter(File file, boolean append) 根据给定的 File 对象构造一个 FileWriter 对象。
  • FileWriter(FileDescriptor fd) 构造与某个文件描述符相关联的 FileWriter 对象。
  • FileWriter(String fileName) 根据给定的文件名构造一个 FileWriter 对象。
  • FileWriter(String fileName, boolean append) 根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象。

常用方法

  • 从类 java.io.Writer 继承的方法:append, append, append, write, write
  • 从类 java.io.OutputStreamWriter 继承的方法:close, flush, getEncoding, write, write, write

测试代码

public static void test() {
    try {
        char[] chars = new char[1024];
        int length;
        //字符流读写文件
        FileOutputStream outputStream = new FileOutputStream(FILE_PATH);
        outputStream.write(("字符流读写文件-" + FORMAT.format(new Date())).getBytes());
        outputStream.close();

        FileInputStream inputStream = new FileInputStream(FILE_PATH);
        byte[] bytes = new byte[1024];
        length = inputStream.read(bytes);
        System.out.println(new String(bytes, 0, length));
        inputStream.close();

        //字节流读写文件
        FileWriter writer = new FileWriter(FILE_PATH);
        writer.write("字节流读写文件-" + FORMAT.format(new Date()));
        writer.close();

        FileReader reader = new FileReader(FILE_PATH);
        length = reader.read(chars);
        System.out.println(new String(chars, 0, length));
        reader.close();

        //转换流读写文件
        OutputStreamWriter streamWriter = new OutputStreamWriter(new FileOutputStream(FILE_PATH), CHARSET);
        streamWriter.write("转换流读写文件-" + FORMAT.format(new Date()));
        streamWriter.close();

        InputStreamReader streamReader = new InputStreamReader(new FileInputStream(FILE_PATH), CHARSET);
        length = streamReader.read(chars);
        System.out.println(new String(chars, 0, length));
        streamReader.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

字符串读写流 StringReader/Writer

为什么会存在这两个类?

当你有一组应用程序接口(API)只允许用 Writer 或 Reader 作为输入,但你的数据源又仅仅是一个现成的String类型数据,而无需从文件等流中读写,这时可以用StringWriter或StringReader。

StringReader

一个源为字符串的字符流

继承关系

  • class StringReader extends Reader

构造方法

  • StringReader(String s) 创建一个新字符串 reader。参数 s 为提供字符流的字符串。

常用方法

  • void close() 关闭该流并释放与之关联的所有系统资源。
  • int read() 读取单个字符。返回读取的字符,如果已到达流的末尾,则返回 -1
  • int read(char[] cbuf, int off, int len) 将字符读入数组的某一部分。返回读取的字符数,如果已到达流的末尾,则返回 -1
  • long skip(long ns) 跳过流中指定数量的字符。返回跳过的字符数。

其他方法

  • void mark(int readAheadLimit) 标记流中的当前位置。对 reset() 的后续调用会将该流重新定位到此点。
  • boolean markSupported() 判断此流是否支持 mark() 操作以及支持哪一项操作。当且仅当此流支持此 mark 操作时,返回 true。
  • boolean ready() 判断此流是否已经准备好用于读取。如果保证下一个 read() 不阻塞输入,则返回 true
  • void reset() 将该流重置为最新的标记,如果从未标记过,则将其重置到该字符串的开头。
  • 从类 java.io.Reader 继承的方法:read, read

StringWriter

一个字符流,可以用其回收在字符串缓冲区中的输出来构造字符串。

注意,StringWriter中,写入的数据只是存在于缓存中,并不会写入实质的存储介质之中。
关闭 StringWriter 无效。此类中的方法在关闭该流后仍可被调用,而不会产生任何 IOException。

继承关系

  • class StringWriter extends Writer

构造方法

  • StringWriter() 使用默认初始字符串缓冲区大小创建一个新字符串 writer。
  • StringWriter(int initialSize) 使用指定初始字符串缓冲区大小创建一个新字符串 writer。参数 initialSize - 在此缓冲区自动扩展前适合它的 char 值数。

常用方法

  • StringWriter append(char c) 将指定字符添加到此 writer。参数 c 为要添加的 16 位字符。行为与out.write(c)完全相同
  • StringWriter append(CharSequence csq) 将指定的字符序列添加到此 writer。行为与out.write(csq.toString())完全相同。如果 csq 为 null,则向此 writer 添加四个字符 "null"。
  • StringWriter append(CharSequence csq, int start, int end) 将指定字符序列的子序列添加到此 writer。行为与out.write(csq.subSequence(start, end).toString())完全相同。如果 csq 为 null,则向此 writer 添加四个字符 "null"。
  • void write(char[] cbuf, int off, int len) 写入字符数组的某一部分。
  • void write(int c) 写入单个字符。
  • void write(String str) 写入一个字符串。
  • void write(String str, int off, int len) 写入字符串的某一部分。
  • StringBuffer getBuffer() 返回该字符串缓冲区本身。
  • String toString() 以字符串的形式返回该缓冲区的当前值。和getBuffer().toString()的效果相同

其他方法

  • void close() 关闭 StringWriter 无效。
  • void flush() 刷新该流的缓冲。

测试代码

public static void test(String string) {
    try {
        StringReader sr = new StringReader(string);
        StringWriter sw = new StringWriter();
        int c = -1;
        while ((c = sr.read()) != -1) {
            sw.write(c);
        }
        sw.close(); //close方法是一个空实现
        System.out.println(sw.getBuffer().toString() + "," + sw.toString());
    } catch (Exception e) {
        e.printStackTrace();
    }
}

字节数组读写流 ByteArray-Stream

ByteArrayInputStreamByteArrayOutputStream,用于以IO流的方式来完成对字节数组内容的读写,来支持类似【内存虚拟文件】或者【内存映射文件】的功能。

相比之下,ByteArrayOutputStream 要比 ByteArrayInputStream 常见的多。

ByteArrayInputStream

ByteArrayInputStream 包含一个内部缓冲区,该缓冲区包含从流中读取的字节。内部计数器跟踪 read 方法要提供的下一个字节。
关闭 ByteArrayInputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException。

继承关系

  • class ByteArrayInputStream extends InputStream
  • 所有已实现的接口:Closeable

构造方法

  • ByteArrayInputStream(byte[] buf) 创建一个 ByteArrayInputStream,使用 buf 作为其缓冲区数组。该缓冲区数组不是复制得到的。 pos 的初始值是 0, count 的初始值是 buf 的长度。
  • ByteArrayInputStream(byte[] buf, int offset, int length) 创建 ByteArrayInputStream,使用 buf 作为其缓冲区数组。该缓冲区数组不是复制得到的。pos 的初始值是 offset, count 的初始值是 offset+length 和 buf.length 中的最小值。

常用方法

  • int read() 从此输入流中读取下一个数据字节。返回一个 0 到 255 范围内的 int 字节值。如果因为到达流末尾而没有可用的字节,则返回值 -1。此 read 方法不会阻塞。
  • int read(byte[] b, int off, int len) 将最多 len 个数据字节从此输入流读入 byte 数组。如果 pos 等于 count,则返回 -1 指示文件结束。否则,读取的字节数 k 等于 len 和 count-pos 中的较小者。此 read 方法不会阻塞。
  • int available() 返回可从此输入流读取(或跳过)的剩余字节数。返回值是 count - pos,它是要从输入缓冲区中读取的剩余字节数。

其他方法

  • void close() 关闭 ByteArrayInputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException。
  • void reset() 将缓冲区的位置重置为标记位置。除非已标记了另一个位置,或者在构造方法中指定了一个偏移量,否则该标记位置是 0。
  • long skip(long n) 从此输入流中跳过 n 个输入字节。如果已到达输入流末尾,则可能会跳过较少的字节。实际跳过的字节数 k 等于 n 和 count-pos 中的较小者。将值 k 与 pos 相加并返回 k。
  • void mark(int readAheadLimit) 设置流中的当前标记位置。构造时默认将 ByteArrayInputStream 对象标记在位置零处。如果尚未设置标记,则标记值是传递给构造方法的偏移量(如果未提供偏移量,则标记值为 0)。参数 readAheadLimit 表示在标记位置失效前可以读取字节的最大限制。
  • boolean markSupported() 测试此 InputStream 是否支持 mark/reset。ByteArrayInputStream 的此方法始终返回 true。
  • 从类 java.io.InputStream 继承的方法:read

ByteArrayOutputStream

此类实现了一个输出流,其中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray() 和 toString() 获取数据。

关闭 ByteArrayOutputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException。

继承关系

  • class ByteArrayOutputStream extends OutputStream
  • 所有已实现的接口:Closeable, Flushable

构造方法

  • ByteArrayOutputStream() 创建一个新的 byte 数组输出流。缓冲区的容量最初是 32 字节,如有必要可增加其大小。
  • ByteArrayOutputStream(int size) 创建一个新的 byte 数组输出流,它具有指定大小的缓冲区容量(以字节为单位)。

常用方法

  • void write(int b) 将指定的字节写入此 byte 数组输出流。
  • void write(byte[] b, int off, int len) 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此 byte 数组输出流。
  • void writeTo(OutputStream out) 将此 byte 数组输出流的全部内容写入到指定的输出流参数中,这与使用 out.write(buf, 0, count) 调用该输出流的 write 方法效果一样。
  • int size() 返回缓冲区的当前大小。
  • byte[] toByteArray() 创建一个新分配的 byte 数组。其大小是此输出流的当前大小,并且缓冲区的有效内容已复制到该数组中。
  • String toString() 使用平台默认的字符集,通过解码字节将缓冲区内容转换为字符串。
  • String toString(String charsetName) 使用指定的 charsetName,通过解码字节将缓冲区内容转换为字符串。

其他方法

  • void close() 关闭 ByteArrayOutputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException。
  • void reset() 将此 byte 数组输出流的 count 字段重置为零,从而丢弃输出流中目前已累积的所有输出。通过重新使用已分配的缓冲区空间,可以再次使用该输出流。
  • 从类 java.io.OutputStream 继承的方法:flush, write

测试代码

public static void byteArrayStream() {
    byte[] buf = "包青天_baiqiantao_2018".getBytes();
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    ByteArrayInputStream inputStream = new ByteArrayInputStream(buf);
    switch (count % 3) {
        case 0:
            int ch;
            while ((ch = inputStream.read()) != -1) {
                outputStream.write(ch);
            }
            Log.i("bqt", inputStream.available() + ",内容:" + outputStream.toString()); //0,包青天_baiqiantao_2018
            break;
        case 1:
            outputStream.write(buf, 0, buf.length);
            Log.i("bqt", outputStream.toString()); //包青天_baiqiantao_2018
            Log.i("bqt", outputStream.size() + ",字节数组:" + Arrays.toString(outputStream.toByteArray()));//25
            break;
        case 2:
            outputStream.write(buf, 0, buf.length);
            byte[] data = FORMAT.format(new Date()).getBytes();
            outputStream.write(data, 0, data.length);//拼接日期,而非覆盖
            try {
                OutputStream out = new FileOutputStream(FILE_PATH); //写入文件中
                outputStream.writeTo(out);
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            Log.i("bqt", outputStream.toString()); //包青天_baiqiantao_2018 2018.11.21 21:52:12 414
            break;
        default:
            break;
    }
    //outputStream.close();//关闭流无意义(在关闭此流后仍可被调用),因为它们没有调用底层资源,所有的操作都是在内存中完成的
    //inputStream.close();
}

二进制数据读写相关的几个接口

接口 DataInput

  • 已知子接口:ObjectInput
  • 已知实现类:DataInputStream, ObjectInputStream, RandomAccessFile

DataInput 接口用于从二进制流中读取字节,并根据所有 Java 基本类型数据进行重构。同时还提供根据 UTF-8 修改版格式的数据重构 String 的工具。

接口中的方法

  • boolean readBoolean() 读取一个输入字节,如果该字节不是零,则返回 true,如果是零,则返回 false。
  • byte readByte() 读取并返回一个输入字节(8 位值)。该字节被看作是 -128 到 127(包含)范围内的一个有符号值。
  • char readChar() 读取两个输入字节并返回一个 char 值。
  • double readDouble() 读取八个输入字节并返回一个 double 值。
  • float readFloat() 读取四个输入字节并返回一个 float 值。
  • void readFully(byte[] b) 从输入流中读取一些字节,并将它们存储在缓冲区数组 b 中。
  • void readFully(byte[] b, int off, int len) 从输入流中读取 len 个字节。
  • int readInt() 读取四个输入字节并返回一个 int 值。
  • String readLine() 从输入流中读取下一文本行。
  • long readLong() 读取八个输入字节并返回一个 long 值。
  • short readShort() 读取两个输入字节并返回一个 short 值(16 位值)。
  • int readUnsignedByte() 读取一个输入字节,将它左侧补零 (zero-extend) 转变为 int 类型,并返回结果,所以结果的范围是 0 到 255(无符号 8 位值)。
  • int readUnsignedShort() 读取两个输入字节,并返回 0 到 65535 范围内的一个 int 值(无符号 16 位值)。
  • String readUTF() 读入一个已使用 UTF-8 修改版格式编码的字符串。
  • int skipBytes(int n) 试图在输入流中跳过数据的 n 个字节,并丢弃跳过的字节。

接口 DataOutput

  • 已知子接口:ObjectOutput
  • 已知实现类:DataOutputStream, ObjectOutputStream, RandomAccessFile

DataOutput 接口用于将数据从任意 Java 基本类型转换为一系列字节,并将这些字节写入二进制流。同时还提供了一个将 String 转换成 UTF-8 修改版格式并写入所得到的系列字节的工具。

对于此接口中写入字节的所有方法,如果由于某种原因无法写入某个字节,则抛出 IOException。

接口中的方法

  • void write(byte[] b) 将数组 b 中的所有字节写入输出流。
  • void write(byte[] b, int off, int len) 将数组 b 中的 len 个字节按顺序写入输出流。
  • void write(int b) 将参数 b 的八个低位写入输出流。
  • void writeBoolean(boolean v) 将一个 boolean 值写入输出流。
  • void writeByte(int v) 将参数 v 的八个低位写入输出流。
  • void writeBytes(String s) 将一个字符串写入输出流。
  • void writeChar(int v) 将一个 char 值写入输出流,该值由两个字节组成。
  • void writeChars(String s) 将字符串 s 中的所有字符按顺序写入输出流,每个字符用两个字节表示。
  • void writeDouble(double v) 将一个 double 值写入输出流,该值由八个字节组成。
  • void writeFloat(float v) 将一个 float 值写入输出流,该值由四个字节组成。
  • void writeInt(int v) 将一个 int 值写入输出流,该值由四个字节组成。
  • void writeLong(long v) 将一个 long 值写入输出流,该值由八个字节组成。
  • void writeShort(int v) 将两个字节写入输出流,用它们表示参数值。
  • void writeUTF(String s) 将表示长度信息的两个字节写入输出流,后跟字符串 s 中每个字符的 UTF-8 修改版表示形式。

接口 ObjectInput

  • public interface ObjectInput extends DataInput
  • 所有超级接口:DataInput
  • 所有已知实现类:ObjectInputStream

ObjectInput 扩展 DataInput 接口以包含对象的读操作
DataInput 包括基本类型的输入方法,ObjectInput 扩展了该接口,以包含对象、数组和 String的输出方法。

接口中的方法

  • int read() 读取数据字节。如果不存在可用的输入,此方法将发生阻塞。返回读取的实际字节数,当到达流的末尾时返回 -1。
  • int read(byte[] b) 读入 byte 数组。在某些输入可用之前,此方法将发生阻塞。返回读取的实际字节数,当到达流的末尾时返回 -1。
  • int read(byte[] b, int off, int len) 读入 byte 数组。在某些输入可用之前,此方法将发生阻塞。返回读取的实际字节数,当到达流的末尾时返回 -1。
  • int available() 返回可以无阻塞地读取的字节数。
  • void close() 关闭输入流。必须调用此方法以释放与流相关的所有资源。
  • Object readObject() 读取并返回对象。实现此接口的类定义从哪里“读取”对象。
  • long skip(long n) 跳过输入的 n 个字节。

从接口 java.io.DataInput 继承的方法

readBoolean, readByte, readChar, readDouble, readFloat, readFully, readFully, readInt, readLine, readLong, readShort, readUnsignedByte, readUnsignedShort, readUTF, skipBytes

接口 ObjectOutput

  • public interface ObjectOutput extends DataOutput
  • 所有超级接口:DataOutput
  • 所有已知实现类:ObjectOutputStream

ObjectOutput 扩展 DataOutput 接口以包含对象的写入操作

DataOutput 包括基本类型的输出方法,ObjectOutput 扩展了该接口,以包含对象、数组和 String的输出方法。

接口中的方法

  • void write(int b) 写入字节。在实际写入字节前,此方法将阻塞。
  • void write(byte[] b) 写入 byte 数组。
  • void write(byte[] b, int off, int len) 写入字节的子数组。
  • void writeObject(Object obj) 将对象写入底层存储或流。实现此接口的类定义如何写入对象。
  • void close() 关闭该流。必须调用此方法以释放与此流相关的所有资源。
  • void flush() 刷新该流的缓冲。此操作将写入所有已缓冲的输出字节。

从接口 java.io.DataOutput 继承的方法

writeBoolean, writeByte, writeBytes, writeChar, writeChars, writeDouble, writeFloat, writeInt, writeLong, writeShort, writeUTF

2018-11-25

posted @ 2018-11-25 01:23  白乾涛  阅读(506)  评论(0编辑  收藏  举报