InputStream && OutputStream Introduction
An important set of interfaces (actually abstract classes) in IO flow operations is InputStream and OutputStream.
InputStream字节输入流其最核心的一个方法是read()方法OutputStream字节输出流其最核心的一个方法是write()方法所有字节输入输都要实现read方法,所有字节输出流都要实现write()方法。字节流可以操作任意类型的文件(二进制或文本文件)
Start by understanding several concepts:
01机器码:只有机器才能识别0101串字节:拿英文来说明就是英文字符所对应的ASCII码(a==>97)字符:就是我们人类能识别的字符文字备注:每种语言有自己对应的字节码比如英文一个字符只占一个字节(ASCII编码),但是中文可能就会占两个字节(gbk/gb2312)或三个字节(utf-8)取决于使用何种编码格式。
InputStream Abstract class Research
InputStream Core Code
/** * This abstract class is the superclass of any classes representing * an input stream of bytes. * * Applications that need to define a subclass of InputStream * must always provide a method that returns the NEX t byte of input. */Public abstract class InputStream implements Closeable {/** * Reads the next byte of data from the I Nput Stream. The value byte is * returned as a int in the range 0 to * 255. If no byte is available because the end of the stream * have been reached, the value-1 is returned. This method * blocks until input data was available, the end of the stream is detected, * or an exception I s thrown. * * A subclass must provide an implementation of this method. */public abstract int Read () throws ioexception;//Core method/** * Reads Some number of bytes from the Put 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 was * available, end of file is detected, or a exception is thrown. * If The length of the B is zero, then no bytes be read and * 0 is returned; Otherwise, there is a attempt to read at * least one byte. If no byte is available because the stream was at the * end of the file, and the value-1 is returned; Otherwise, at * least one byte was read and stored into B. * * The first byte read is stored to 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 is the * number of bytes actually read; These bytes'll 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); }//Understand the following code block public int Read (byte b[], int off, int len) throws IOException {if (b = = nul L) {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 {}//Note: The most important thing is to understand the read () method and the read (byte[] bytes) method}
Typical template code
@Testpublic 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 Abstract class Research
OutputStream Core Code
/** * This abstract class is the superclass of any classes representing * An output stream of bytes. An output stream accepts the 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 T His output stream. The general * Contract for write are that one byte are written * to the output stream. The byte to being written is the eight * low-order bits of the argument B. The 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, it should has 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 stre Am. * The general contract for write (b, off, Len) was that * some of the bytes in the array B was written to the * Output stream in order; Element B[off] is the first * byte written and b[off+len-1] are 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 is * written out. Subclasses is 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 OU T. The general contract of Flush is * This calling it is a indication that, if any bytes previously * WRI Tten has been buffered by the implementation of the output * stream, such bytes should immediately is written to their * intended destination. * * If The intended destination of this stream is a abstraction provided by * The underlying operating s Ystem, for example a file, then flushing The * stream guarantees only this bytes previously written to the stream is * passed to the operating sy Stem for writing; It does not guarantee that * they is 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 an Y system resources * associated with the This stream. The general contract of Close * are that it closes the output stream. A closed stream cannot perform * Output operations and cannot be reopened. */public void Close () throws IOException {}}//A computer scientist says the idea of caching is the most important thought of computer development in the 20th century.
Typical template code
@Testpublic 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方法就直接写入到文件中。}
Document Test Book
说明:文件考本这里涉及到源和目标其实这样就可以推广到网络上文件传输也是一样的,都是有输入流和输出流,IO流操作弄清楚源和目标以及输入输出流和方向时那么问题就简单了模型就清楚了。
Code
@Testpublic 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(); // 备注:解释缓冲字节数组,通常缓冲字节数组都是对于输入流而言的,可以那么理解, // 当输入流读一个文件的时候,原先是读一个字节就往输出流写一个字节,这样相对比较浪费时间, // 所以就可以读一定量的字节存放到一个数组中,当数组满了之后然后将这个数组中所有字节输入到输出流中,然后清空数组继续读取字节。以此循环}
InputStream && OutputStream