jdk1.8 java.io.FileInputStream class source reading

Posted by Darrel on Mon, 17 Feb 2020 03:22:39 +0100

introduce

jdk explained:
public class FileInputStream
extends InputStream
A FileInputStream gets input bytes from files in the file system.What files are available depends on the host environment.
FileInputStream is used to read raw byte streams such as image data.To read a string, consider using FileReader.

attribute

    /* File Descriptor - handle to the open file */
    private final FileDescriptor fd;

    /**
     * The path of the referenced file
     * (null if the stream is created with a file descriptor)
     */
    private final String path;

    private FileChannel channel = null;

    private final Object closeLock = new Object();
    private volatile boolean closed = false;

It is worth noting that private final FileDescriptor fd;
FileDescriptor class jdk 1.8 Interpretation:
Instances of the file descriptor class are used as opaque handles to underlying machine-specific structures that represent open files, open sockets, or other byte sources or hosts.The main practical use of a file descriptor is to create a FileInputStream or FileOutputStream to contain it.

FileDescriptor Details http://wangkuiwu.github.io/2012/05/09/FileDescriptor/

Construction method

 public FileInputStream(String name) throws FileNotFoundException {
        this(name != null ? new File(name) : null);
    }
 public FileInputStream(File file) throws FileNotFoundException {
        String name = (file != null ? file.getPath() : null);
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkRead(name);
        }
        if (name == null) {
            throw new NullPointerException();
        }
        if (file.isInvalid()) {
            throw new FileNotFoundException("Invalid file path");
        }
        fd = new FileDescriptor();
        fd.attach(this);
        path = name;
        open(name);
    } 
 public FileInputStream(FileDescriptor fdObj) {
        SecurityManager security = System.getSecurityManager();
        if (fdObj == null) {
            throw new NullPointerException();
        }
        if (security != null) {
            security.checkRead(fdObj);
        }
        fd = fdObj;
        path = null;

        /*
         * FileDescriptor is being shared by streams.
         * Register this stream with FileDescriptor tracker.
         */
        fd.attach(this);
    }

First look at the explanation of jdk1.8

The implementation of these three constructions returns to private final FileDescriptor fd; attributes.
public FileInputStream(File file) throws FileNotFoundException: The implementation of this construction method first determines whether the incoming parameter is legal, then for the property
fd = new FileDescriptor();fd.attach(this); note that fd.attach(this); source view attach method

    synchronized void attach(Closeable c) {
        if (parent == null) {
            // first caller gets to do this
            parent = c;
        } else if (otherParents == null) {
            otherParents = new ArrayList<>();
            otherParents.add(parent);
            otherParents.add(c);
        } else {
            otherParents.add(c);
        }
    }

Note that the parameter passed in is Closeable and we are passing in FileInputStream because FileInputStream inherits InputStream and InputStream implements the Closeable interface.
The last open(name); is a local method of the FileInputStream class
private native void open0(String name) throws FileNotFoundException: Opens the specified file for reading.

Similarly, the following construction method, public FileInputStream(FileDescriptor fdObj), is the same.

@Test

    @Test
    public void toPath() throws FileNotFoundException {
        File file = new File("F:\\FileStudy\\test2.txt");//Existing files
        File file1 = new File("F:\\FileStudy\\test2.t1xt");//No file exists
        File file2 = new File("F:\\FileStudy");//Existing directory
        File file3 = new File("F:\\FileStud");//No file exists

        FileInputStream fileInputStream =new FileInputStream(file);//1
        FileInputStream fileInputStream1 =new FileInputStream(file1);//2
        FileInputStream fileInputStream2 =new FileInputStream(file2);//3
        FileInputStream fileInputStream3 =new FileInputStream(file3);//4
        
    }
    //Output Results:
    //Except for the first one to succeed
    2Will return:java.io.FileNotFoundException: F:\FileStudy\test2.t1xt (The system could not find the specified file.)
    3Will return:java.io.FileNotFoundException: F:\FileStudy (Access denied.)
    4Will return:java.io.FileNotFoundException: F:\FileStud (The system could not find the specified file.)

Tests show that if the file is a directory, the creation is unsuccessful and an exception is thrown.

Method

(1) read() method class:

public int read() throws IOException {
        return read0();
    }
private native int read0() throws IOException;
private native int readBytes(byte b[], int off, int len) throws IOException;
public int read(byte b[]) throws IOException {
        return readBytes(b, 0, b.length);
    }
public int read(byte b[], int off, int len) throws IOException {
        return readBytes(b, off, len);
    }

These methods are overloaded with local methods
@Test

    @Test
    public void read() throws IOException {
        File file = new File("F:\\FileStudy\\test2.txt");//Existing files
        FileInputStream fileInputStream =new FileInputStream(file);
        System.out.println(fileInputStream.read());
        while (fileInputStream.read()>1){
            System.out.println(fileInputStream.read());
        }
        byte[] bytes =new byte[4];
        System.out.println("--------------------------------------");
        System.out.println(fileInputStream.read(bytes));
        System.out.println(fileInputStream.read(bytes,1,1));
    }
    
//Output Results:
183
183
181
203
183
181
-1
--------------------------------------
-1
-1

(2)

public native long skip(long n) throws IOException;

Is also a local method
public long skip(long n) throws IOException
Skip and discard n bytes of data from the input stream.
For various reasons, the skip method may skip a small number of bytes, possibly 0.If n is negative, the method will attempt to jump backwards.If the background file does not support skipping backwards at its current location, an IOException will be thrown.Returns the actual number of bytes skipped.If it jumps forward, it returns a positive value.If it jumps back, it returns a negative value.

This method may skip more bytes than are left in the backup file.This does not cause an exception, and the number of bytes skipped may include some bytes that exceed the EOF of the background file.Attempting to read from the stream after skipping results in -1 representing the end of the file.

Rewrite:
skip in InputStream
parameter
n - Number of bytes to skip.
Result
The actual number of bytes skipped.
abnormal
IOException - If n is negative, if the stream does not support queries, or if an I/O error occurs.

(3)

public native int available() throws IOException;

Local method
public int available() throws IOException
Returns an estimate of the number of bytes remaining that can be read (or skipped) from this input stream without being blocked by the next method that calls this input stream.Returns 0 when the file location exceeds EOF.The next call may be the same thread or another thread.A single read or skip of this multiple bytes will not be blocked, but fewer bytes can be read or skipped.
In some cases, non-blocking reads (or skips) may be blocked at slow times, such as reading large files on slow networks.
Rewrite:
available in InputStream
Result
An estimate of the number of bytes remaining that can be read (or skipped) from this input stream without blocking.
abnormal
IOException - If this file input stream has been closed by calling close or an I/O error occurs.
@Test

   @Test
    public void available() throws IOException {
        File file = new File("F:\\FileStudy\\test2.txt");//Existing files
        FileInputStream fileInputStream =new FileInputStream(file);
        while (fileInputStream.read()>1){
            System.out.println(fileInputStream.available());
        }
    }
//Output Results:
11
10
9
8
7
6
5
4
3
2
1
0

You can see that the read() method is a byte read;

(4) public void close() throws IOException;

    public void close() throws IOException {
        synchronized (closeLock) {
            if (closed) {
                return;
            }
            closed = true;
        }//I didn't understand this paragraph.
        if (channel != null) {
           channel.close();
        }

        fd.closeAll(new Closeable() {
            public void close() throws IOException {
               close0();
           }
        });
    }

public void close() throws IOException
Close this file input stream and release any system resources associated with the stream.
If the stream has an associated channel, the channel is also closed.
Specified by:
close in interface Closeable
Specified by:
close in interface AutoCloseable
Rewrite:
close in InputStream class
abnormal
IOException - If an I/O error occurs.

Looking at the source code analysis, we can see if the closed attribute is true and return it directly for true.
Then it determines if the channel attribute is empty and not channel.close() for air conditioning.
Finally, using the closeAll method in FileDescriptor, overrides the Closeable class method, and finally falls to the local close0() method in FileInputStream;

(5)

    public final FileDescriptor getFD() throws IOException {
        if (fd != null) {
            return fd;
        }
        throw new IOException();
    }
    public FileChannel getChannel() {
        synchronized (this) {
            if (channel == null) {
                channel = FileChannelImpl.open(fd, path, true, false, this);
            }
            return channel;
        }
    }

This method is a get method to get attributes and return an instance of the attributes.
Notably, the public FileChannel getChannel(),
The FileChannel class uses: https://blog.csdn.net/KingBoyWorld/article/details/72417461
FileChannel class Jdk1.8 document explanation: http://www.matools.com/api/java8

summary

Not Ended to Continue

16 original articles published. 0% praised. 7090 visits
Private letter follow

Topics: Attribute Java JDK github