Detailed Method InputStream abstract class

First class structure

The InputStream abstract class is a superclass of all bytes of the input stream based on

First, this is an abstract class that implements the interface Closeable, also Closeable interfaces and expanded AutoCloseable interface, so that all InputStream and its subclasses can be used to try statement Java 7 with the introduction of new resources. Before reading bytes, we may want to know how much data is available, which is available to complete the method, specific reading done by the read () and overloaded methods, skip method used to skip certain bytes also defines several methods related marks (mark), the data reading method using the close off the flow, the release of resources. The following details the various methods:
Class:

public abstract class InputStream implements Closeable {

1.方法available

public int available() throws IOException

This method can read and write operations before the first data stream that the number of bytes read. Note that, if this method is used when reading data from a local file, generally do not have problems, but if it is used for network operations, often encounter some trouble. For example, when Socket Communications, the other obviously sent a 1000 bytes, but his program calls available () method received only 900, or 100, or even zero, feeling a little puzzled, how could not find the cause. In fact, this is because the network communications are often intermittent, often a string of bytes sent in several batches. Local program call available () method sometimes get 0, this may be the other side has not responded, it could be the other party has responded, but the data has not delivered locally. Other party to send 1,000 bytes to you, maybe divided into three batches arrive, you have to call it 3 times available () method to get the total number of all data.

能否使用取决于实现了InputStream这个抽象类的具体子类中有没有实现available这个方法。如果实现了那么就可以取得大小,如果没有实现那么就获取不到。例如FileInputStream就实现了available方法,那么就可以用new byte[in.available()];这种方式。但是,网络编程的时候Socket中取到的InputStream,就没有实现这个方法,那么就不可以使用这种方式创建数组。

Java exception mechanism very important point, not throws subclass of parent class method throws no exceptions (except the constructors), so the first noted in the parent class method, and then allow the subclass method throws IOException

2. The method reads: read

The method follows to read the related method is the core of this class. There are three forms of overload, the following were introduced.

2.1 read()

   public abstract int read() throws IOException;

The next byte read the input stream. This is an abstract method, does not provide an implementation, subclass must implement this method. The method reads the next byte, returns an int integer between 0-255. If the end of the stream is reached, -1.

E.g:

    public static void main(String[] args) {
        try (InputStream in = new FileInputStream("E:\\q.txt")) {
            int i;
            while ((i = in.read()) != -1) {
                System.out.println(i);
                System.out.println("out: " + (char) i);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Output:

When the byte-oriented operations may be required such as a relatively low-byte operation. We can also read by a number of bytes, use the following overloaded forms.

2.2 read(byte[] b)

    public int read(byte b[]) throws IOException {
        return read(b, 0, b.length);
    }

Attempting to read a plurality of bytes, stored in byte array B, returns the number of bytes actually read.

If passed an empty array (note that the array length can be zero, i.e. empty array such as byte [] b = new byte [0];. Or byte [] b = {};) then nothing is read, returns 0 .

If flow reaches the tail, without the byte read, return -1;

E.g:

    public static void main(String[] args) {
        try (InputStream in = new FileInputStream("E:\\q.txt")) {
            byte[] buffer = new byte[1024];
            StringBuilder sb = new StringBuilder();
            while (in.read(buffer) != -1) {
                sb.append(new String(buffer, StandardCharsets.UTF_8));
            }
            System.out.println(sb);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

2.3 read (byte[] b, int off, int len)

This method is followed by a similar function, in addition to the read data stored in the array b is off from the beginning. len is the number of bytes to attempt to read, returns the number of bytes actually read.

If len = 0, nothing is read, return 0; if the tail encounters the stream, -1 otherwise read into the at least one byte.

This method does not introduce too much the same way as above, look at the source code to know is this a retrieval method. Finally, look at the source code of this method:

    public int read(byte b[], int off, int len) throws IOException {
        if (b == null) {   // 检测参数是否为null
            throw new NullPointerException();
        } else if (off < 0 || len < 0 || len > b.length - off) {
            throw new IndexOutOfBoundsException(); // 数组越界检测
        } else if (len == 0) {
            return 0;   //如果b为空数组,返回0
        }
 
        int c = read(); // 调用read()方法获取下一个字节
        if (c == -1) {
            return -1;
        }               // 遇到流尾部,返回-1
        b[off] = (byte)c;  //读入的第一个字节存入b[off]
 
        int i = 1;    // 统计实际读入的字节数
        try {
            for (; i < len ; i++) { // 循环调用read,直到流尾部
                c = read();
                if (c == -1) {
                    break;
                }
                b[off + i] = (byte)c; // 一次存入字节数组
            }
        } catch (IOException ee) {
        }
        return i;  // 返回实际读入的字节数
    }

3. skip method

public long skip(long n) throws IOException

This method attempts to skip n bytes of the current stream, returns the number of bytes actually skipped. If n is negative, it returns 0 subclass of course not possible to provide the treatment. n only our expectations, but the specific skipped a few, are not subject to our control, such as during the end of the stream.

Output:

4. A method associated with the label

4.1 mark 

public void mark(int readlimit)

This method is used at the current position of the stream to be labeled, this parameter specifies readLimit labeled "valid" if the start mark from the back, has been acquired or skipped readLimit bytes, then the failure flag, is not allowed to back to this position (the reset method). That is, you can not go too far to turn back Yeah, the prodigal son is not necessarily the shore, skip (get) so many bytes, mark it no longer wait for you. This method is called multiple times, in front of the mark will be overwritten.

看一下上面的图,如果我们在M出做标记,readLimit为绿色部分,当流的指针在A处的时候,这个标记依然有效,可是一旦指针跑到B处,标记就失效了。

4.2 reset 

public void reset() throws IOException

这个方法用于重定位到最近的标记。如果在这之前mark方法从来没被调用,或者标记已经无效,在抛出IOException。如果没有抛出这个异常,将当前位置重新定位到最近的标记位置。

InputStream is = null;
		//byte[] buffer = new byte[6];
		//char c;
		
		try {
			is = new BufferedInputStream(new FileInputStream("test.txt"));
			is.mark(4);
			is.skip(2);
			is.reset();
			//is.read(buffer, 1, 3);
			System.out.println((char)is.read());
			
			/*for (byte b : buffer) {
				System.out.println((char)b);
			}*/
			
	
		} finally {
			if (is != null) {
				is.close();
			}
		}
 
	}

我们使用了支持mark的BufferedInputStream,首先一开始做标记,跳过两个自己,然后再回到最初的位置。

4.3 markSupported

public boolean markSupported()

检测当前流对象是否支持标记。是返回true。否则返回false。比如InputStream不支持标记,而BufferedInputStream支持。

5. close方法 

public void close() throws IOException

关闭当前流,释放与该流相关的资源,防止资源泄露。在带资源的try语句中将被自动调用。关闭流之后还试图读取字节,会出现IOException异常。

Guess you like

Origin blog.csdn.net/qq_36850813/article/details/94390037