一、FileInputStream 從文件系統(tǒng)中讀取一個文件轉換成的字節(jié) 數(shù)據結構:
public class FileInputStream extends InputStream{ /* 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; private static final ThreadLocal<Boolean> runningFinalize = new ThreadLocal<>(); //... }重載的構造方法
//通過文件來創(chuàng)建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.incrementAndGetUseCount();//增加用戶使用的次數(shù) this.path = name; open(name);//打開文件 } //通過文件描述器來創(chuàng)建文件輸入流 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. * Ensure that it's GC'ed only when all the streams/channels are done * using it. */ fd.incrementAndGetUseCount(); } //通過文件的路徑名來創(chuàng)建輸入流 public FileInputStream(String name) throws FileNotFoundException { this(name != null ? new File(name) : null); }FileDescriptor是FileInputStream與文件的連接橋梁,它的創(chuàng)建代表著文件的打開或者socket的打開。 部分方法: close方法
public void close() throws IOException { synchronized (closeLock) {//同步鎖 if (closed) { return; } closed = true; } if (channel != null) { //減少File Descriptor的數(shù)量 fd.decrementAndGetUseCount(); channel.close(); } /* *減少File Descriptor的數(shù)量 */ int useCount = fd.decrementAndGetUseCount(); /* * 如果File Descriptor的被其他流使用,那就將不會關閉 */ if ((useCount <= 0) || !isRunningFinalize()) { close0(); } }getChannel() 增加FileDescriptor的數(shù)量
public FileChannel getChannel(){ synchronized (this) { if (channel == null) { channel = FileChannelImpl.open(fd, path, true, false, this); //增加FileDescriptor fd.incrementAndGetUseCount(); } return channel; }}二、SocketInputStream 繼承與FileInputStream,注意的是該類沒有被public修飾。看一下類的結構
class SocketInputStream extends FileInputStream{ private boolean eof;//結束標志 private AbstractPlainSocketImpl impl = null;//socket現(xiàn)實抽象類 private byte temp[];//緩沖數(shù)據 private Socket socket = null;}從這里可以看出,F(xiàn)ile IO和Socket IO非常的相似。 三、ObjectInputStream 一個反序列化之前寫入到ObjectOutputSteam中的原生類型數(shù)據和對象類型。ObjectInputStream確保了在圖中流所匹配在JVM中的java類。
新聞熱點
疑難解答