InputStream && OutputStream

InputStream && OutputStream


介绍

IO流操作中非常重要的一组接口(其实是抽象类)是InputStream和OutputStream。

InputStream字节输入流其最核心的一个方法是read()方法
OutputStream字节输出流其最核心的一个方法是write()方法

所有字节输入输都要实现read方法,所有字节输出流都要实现write()方法。
字节流可以操作任意类型的文件(二进制或文本文件)

首先了解几个概念:

01机器码:只有机器才能识别0101串
字节:拿英文来说明就是英文字符所对应的ASCII码(a==>97)
字符:就是我们人类能识别的字符文字
备注:每种语言有自己对应的字节码比如英文一个字符只占一个字节(ASCII编
码),但是中文可能就会占两个字节(gbk/gb2312)或三个字节(utf-8)取决于使用何种编码格式。

InputStream抽象类研究

InputStream核心Code

    /**
     * This abstract class is the superclass of all classes representing
     * an input stream of bytes.
     *
     * Applications that need to define a subclass of InputStream
     * must always provide a method that returns the next byte of input.
     */
    public abstract class InputStream implements Closeable {

        /**
         * Reads the next byte of data from the input stream. The value byte is
         * returned as an int in the range 0 to
         * 255. If no byte is available because the end of the stream
         * has been reached, the value -1 is returned. This method
         * blocks until input data is available, the end of the stream is detected,
         * or an exception is thrown.
         *
         * A subclass must provide an implementation of this method.
         */
        public abstract int read() throws IOException;//核心方法

        /**
         * Reads some number of bytes from the input stream and stores them into
         * the buffer array b. The number of bytes actually read is
         * returned as an integer.  This method blocks until input data is
         * available, end of file is detected, or an exception is thrown.
         *
         * If the length of b is zero, then no bytes are read and
         * 0 is returned; otherwise, there is an attempt to read at
         * least one byte. If no byte is available because the stream is at the
         * end of the file, the value -1 is returned; otherwise, at
         * least one byte is read and stored into b.
         *
         * The first byte read is stored into element b[0], the
         * next one into b[1], and so on. The number of bytes read is,
         * at most, equal to the length of b. Let k be the
         * number of bytes actually read; these bytes will be stored in elements
         * b[0] through b[k-1],
         * leaving elements b[k] through
         * b[b.length-1] unaffected.
         */
        public int read(byte b[]) throws IOException {
            return read(b, 0, b.length);
        }

        //理解下面代码块
        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;
        }

        /**
         * Closes this input stream and releases any system resources associated
         * with the stream.
         */
        public void close() throws IOException {}

    //备注:最重要的是理解read()方法和read(byte[] bytes)方法

}


典型模板代码

@Test
public void testReadFile() throws Exception {

    String SEPARATOR = File.separator;
    File file = new File("E:" + SEPARATOR + "io" + SEPARATOR + "test.txt");
    // 获得输入流
    FileInputStream inputStream = new FileInputStream(file);

    // 定义缓存字节数组
    byte[] buffer = new byte[1024];
    int length = 0;// 表示实际读取字节数组缓冲的字节数目
    while ((length = inputStream.read(buffer)) != -1) {
        System.out.print(new String(buffer, 0, length, "utf-8"));
        // 输出文件到控制台时最好不要使用ln换行打印,否则如果数组长度定义不恰当是可能出现问题的.
    }
    // 流资源关闭
    inputStream.close();

}

OutputStream抽象类研究

OutputStream核心Code

/**
 * This abstract class is the superclass of all classes representing
 * an output stream of bytes. An output stream accepts output bytes
 * and sends them to some sink.
 *
 * Applications that need to define a subclass of
 * OutputStream must always provide at least a method
 * that writes one byte of output.
 */
public abstract class OutputStream implements Closeable, Flushable {
        /**
         * Writes the specified byte to this output stream. The general
         * contract for write is that one byte is written
         * to the output stream. The byte to be written is the eight
         * low-order bits of the argument b. The 24
         * high-order bits of b are ignored.
         *
         * Subclasses of OutputStream must provide an
         * implementation for this method.
         *
         */
        public abstract void write(int b) throws IOException;

        /**
         * Writes b.length bytes from the specified byte array
         * to this output stream. The general contract for write(b)
         * is that it should have exactly the same effect as the call
         * write(b, 0, b.length).
         */
        public void write(byte b[]) throws IOException {
            write(b, 0, b.length);
        }

        /**
         * Writes len bytes from the specified byte array
         * starting at offset off to this output stream.
         * The general contract for write(b, off, len) is that
         * some of the bytes in the array b are written to the
         * output stream in order; element b[off] is the first
         * byte written and b[off+len-1] is the last byte written
         * by this operation.
         * <p>
         * The write method of OutputStream calls
         * the write method of one argument on each of the bytes to be
         * written out. Subclasses are encouraged to override this method and
         * provide a more efficient implementation.
         */
        public void write(byte b[], int off, int len) throws IOException {
            if (b == null) {
                throw new NullPointerException();
            } else if ((off < 0) || (off > b.length) || (len < 0) ||
                       ((off + len) > b.length) || ((off + len) < 0)) {
                throw new IndexOutOfBoundsException();
            } else if (len == 0) {
                return;
            }
            for (int i = 0 ; i < len ; i++) {
                write(b[off + i]);
            }
        }

        /**
         * Flushes this output stream and forces any buffered output bytes
         * to be written out. The general contract of flush is
         * that calling it is an indication that, if any bytes previously
         * written have been buffered by the implementation of the output
         * stream, such bytes should immediately be written to their
         * intended destination.
         *
         * If the intended destination of this stream is an abstraction provided by
         * the underlying operating system, for example a file, then flushing the
         * stream guarantees only that bytes previously written to the stream are
         * passed to the operating system for writing; it does not guarantee that
         * they are actually written to a physical device such as a disk drive.
         *
         * The flush method of OutputStream does nothing..
         */
        public void flush() throws IOException {
        }

        /**
         * Closes this output stream and releases any system resources
         * associated with this stream. The general contract of close
         * is that it closes the output stream. A closed stream cannot perform
         * output operations and cannot be reopened.
         */
        public void close() throws IOException {
        }

}
//有一位计算机科学家说缓存思想是20世纪计算机发展最重要的思想


典型模板代码

@Test
public void testFileOutputStream() throws Exception {

        String SEPARATOR = File.separator;
        File file = new File("E:" + SEPARATOR + "io" + SEPARATOR + "out.txt");
        // 定义输出流
        FileOutputStream out = new FileOutputStream(file);
        // 向输出流中写入数据
        out.write("helloworld 你好世界".getBytes("utf-8"));
        out.close();

        // 备注使用OutputStream由于没有缓存,所以不需要调用flush方法就直接写入到文件中。
}

文件考本

说明:文件考本这里涉及到源和目标其实这样就可以推广到网络上文件传输
也是一样的,都是有输入流和输出流,IO流操作弄清楚源和目标以及输入输
出流和方向时那么问题就简单了模型就清楚了。

Code

@Test
public void testCopyFile() throws Exception {

    String SEPARATOR = File.separator;
    // 源文件
    File source = new File("E:" + SEPARATOR + "io" + SEPARATOR + "1.png");
    // 获得输入流
    FileInputStream inputStream = new FileInputStream(source);

    // 输出(目标)文件
    File copyFile = new File("E:" + SEPARATOR + "io" + SEPARATOR + "copy.png");
    // 定义输出流
    FileOutputStream outputStream = new FileOutputStream(copyFile);

    // 定义缓冲字节数组
    byte[] buffer = new byte[1024];
    int length = 0;
    while ((length = inputStream.read(buffer)) != -1) {// 只要输入流还有字节那么输出流就一直写入数据
        outputStream.write(buffer, 0, length);
    }
    outputStream.close();
    inputStream.close();

    // 备注:解释缓冲字节数组,通常缓冲字节数组都是对于输入流而言的,可以那么理解,
    // 当输入流读一个文件的时候,原先是读一个字节就往输出流写一个字节,这样相对比较浪费时间,
    // 所以就可以读一定量的字节存放到一个数组中,当数组满了之后然后将这个数组中所有字节输入到输出流中,然后清空数组继续读取字节。以此循环

}
时间: 2024-11-13 14:34:43

InputStream && OutputStream的相关文章

java的inputstream, outputstream, reader和writer的比较

java的文件读写有多种方式,在此通过代码做以下比较. 比较一:FileWriter和FileReader public class MyCode1 { public static void main(String[] args) throws IOException { File f = new File("my.txt"); FileWriter fw = new FileWriter(f); fw.write("HELLO"); fw.close(); Fil

黑马程序员——22,字节流InputStream,OutputStream,字节流缓冲区技术,BufferedInputStream,BufferedOutputStream

------<ahref="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流! ------- /* 字节流的相关讲解: InputStream(读操作),OutputStream(写操作) 在用法上和之前的字符流差不多 */ import java.io.*; class Ioliou13 { public static void

36.InputStream OutputStream

字符流:FileReader FileWriter BufferedReader BufferedWriter 字节流:InputStream 读OutputStream 写 public class FileStream_08 { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub //writeFile(); //readFile_1(); //readF

[五] JavaIO之InputStream OutputStream简介 方法列表说明

InputStream 和 OutputStream 对于字节流的输入和输出 是作为协议的存在 所以有必要了解下这两个类提供出来的基本约定 这两个类是抽象类,而且基本上没什么实现,都是依赖于子类具体的去实现 但是他是对于其子类 协议纲领一般的存在 了解清楚每一个方法含义,对于后续具体的子类将会有非常大的帮助 基本含义 InputStream 所有字节输入流的 超类 他是一个抽象类 OutputStream 所有字节输出流的 超类 他是一个抽象类 方法列表 InputStream  包含了读取方法

InputStream &amp; OutputStream 使用方法以及注意事项

1 /* 2 * To change this license header, choose License Headers in Project Properties. 3 * To change this template file, choose Tools | Templates 4 * and open the template in the editor. 5 */ 6 package InputStream; 7 8 import java.io.BufferedInputStre

Java I/O中的InputStream/OutputStream

原文地址:https://www.cnblogs.com/sunupo/p/10475906.html

Java复习——I/O与序列化

File类 java.io.File只用于表示文件(目录)的信息(名称.大小等),不能用于文件内容的访问,我们可以通过通过给其构造函数传一个路径来构建以文件,传入的路径名有一个小问题,就是Windows和UNIX 中的路径分隔符斜杠方向的问题:"/" 表示 UNIX 中的根目录,"\" 表示Windows 的根目录.File类有静态的参数可以很简单的解决这个问题:pathSeparator就是其中一个.File类中常用的方法有: exists():测试此抽象路径名表

14. 流、文件和IO

前言 InputStream/OutStream流用来处理设备之间的数据传输 Java.io 包几乎包含了所有操作输入.输出需要的类.所有这些流类代表了输入源和输出目标. Java.io 包中的流支持很多种格式,比如:基本类型.对象.本地化字符集等等. 一个流可以理解为一个数据的序列.输入流表示从一个源读取数据,输出流表示向一个目标写数据. 流按操作数据分为两种:字节流与字符流 按流向分为:输入流(InputStream)和输出流(OutputStream) Java 为 I/O 提供了强大的而

深入理解JAVA I/O系列二:字节流详解

流的概念 JAVA程序通过流来完成输入/输出.流是生产或消费信息的抽象,流通过JAVA的输入输出与物理设备链接,尽管与它们链接的物理设备不尽相同,所有流的行为具有相同的方式.这样就意味一个输入流能够抽象多种不同类型的输入:从磁盘文件.从键盘或从网络套接字:同样,一个输出流可以输出到控制台.磁盘文件或相连的网络. 在我们平时接触的输入/输出流中,有这样一个概念必须要弄明白,何谓输入.何谓输出?讨论这个问题的前提是要知道以什么为参考物,这个参考物就是程序或者内存.输入:就是从磁盘文件或者网络等外部的