java基礎學習_io流之FileInputStream

  一。FileInputStream屬性:
  
  /* File Descriptor - handle to the open file */
  
  private final FileDescriptor fd;
  
  /*用來標識輸入流的狀態*/
  
  private final String path; //文件的路徑信息
  
  private FileChannel channel = null;
  
  private final Object closeLock = new Object();//關閉時的同步鎖
  
  private volatile boolean closed = false;
  
  二。FileInputStream重載了3個構造方法。可以經過如下三種方式初始輸入流:
  
  public FileInputStream(String name) throws FileNotFoundException;
  
  :以路徑的方式初始一個輸入流。其內部調用的是如下的構造方法
  
  public FileInputStream(String name) throws FileNotFoundException {
  
  this(name != null ? new File(name) : null);//當name不爲空,就生成一個File對象 做爲FileInputStream(File file)構造函數的參數
  
  }
  
  public FileInputStream(File file) throws FileNotFoundException;
  
  :以File實例的方法初始一個輸入流
  
  源碼爲:
  
  FileInputStream(File file) 構造方法
  
  構造方法內部解析:
  
  SecurityManager security = System.getSecurityManager();
  
  其中 當運行未知的Java程序的時候,該程序可能有惡意代碼(刪除系統文件、重啓系統等),爲了防止運行惡意代碼對系統產生影響,須要對運行的代碼的權限進行控制,這時候就要啓用Java安全管理器(SecurityManager)。
  
  1.默認的安全管理器配置文件是 $JAVA_HOME/jre/lib/security/java.policy,即當未指定配置文件時,將會使用該配置。
  
  使用以前須要啓動SecurityManager,啓動有兩種方式:參數方式、編碼方式
  
  啓動程序的時候經過附加參數啓動安全管理器:
  
  -Djava.security.manager
  
  若要同時指定配置文件的位置那麼示例以下:
  
  -Djava.security.manager -Djava.security.policy="E:/java.policy"
  
  "="表示這個策略文件將和默認的策略文件一同發揮做用; "=="表示只使用指定的策略文件 。如 -Djava.security.policy==E:/temp/test1.policy或者 -Djava.security.policy=bin/com/test/test1.policy
  
  編碼方式(不建議):
  
  System.setSecurityManager(new SecurityManager());
  
  參數方式啓動:
  
  保存後在運行security就不爲null了 ,走進security.checkRead(name); 拋錯(使用了默認配置文件)
  
  這時候解決方式:(1)關閉安全管理器;(2)賦予該程序讀取文件權限
  
  打開管理器配置文件添加:
  
  grant {
  
  permission java.io.FilePermission "C:\\Study\\*", "read";
  
  permission java.io.FilePermission "C:\\Study\\2401.jpg_wh1200.jpg", "write";
  
  };
  
  給程序添加文件讀權限
  
  其中    permission java.io.FilePermission "C:\Study\2401.jpg_wh1200.jpg", "read";    一個反斜槓是錯誤的
  
  權限項中出現的項目必須按指定順序出現(permission,permission_class_name,」target_name」,」action」 和 signedBy 「signer_names」)。分號表示項終止。
  
  大小寫對於標識符(permission、signedBy、codeBase 等)來講並不重要,但對於 permission_class_name 或做爲值傳遞過來的字符串而言就很重要了。
  
  有關 Windows 系統上文件路徑規範的注意事項
  
  請注意:在指定 java.io.FilePermission 時,」target_name」 是文件路徑。在 Windows 系統上,不管什麼時候在字符串中(而不是在 codeBase URL 中)直接指定文件路徑,路徑中都須要兩個反斜槓來表明一個實際的反斜槓;
  
  public FileInputStream(FileDescriptor fdObj);
  
  :以FileDescriptor實例初始一個輸入流(FileDescriptor是一個文件描寫敘述符
  
  FileDescriptor:文件描述符類的實例用做表示打開文件,開放套接字或其餘字節源或信宿的底層機器特定結構的不透明句柄。 文件描述符的主要實際用途是建立一個FileInputStream或FileOutputStream來包含它。
  
  三。FileInputStream方法
  
  int    available()
  
  返回今後輸入流中能夠讀取(或跳過)的剩餘字節數的估計值,而不會被下一次調用此輸入流的方法阻塞。
  
  void    close()
  
  關閉此文件輸入流並釋放與流相關聯的任何系統資源。
  
  protected void    finalize()
  
  確保當這個文件輸入流的 close方法沒有更多的引用時被調用。
  
  FileChannel    getChannel()
  
  返回與此文件輸入流相關聯的惟一的FileChannel對象。
  
  https://www.cnblogs.com/duanxz/p/6759814.html
  
  關於FileChannel能夠參考以上博客
  
  FileDescriptor    getFD()
  
  返回表示與此 FileInputStream正在使用的文件系統中實際文件的鏈接的 FileDescriptor對象。
  
  int    read()
  
  從該輸入流讀取一個字節的數據。
  
  int    read(byte[] b)
  
  從該輸入流讀取最多 b.length個字節的數據爲字節數組。
  
  int    read(byte[] b, int off, int len)
  
  從該輸入流讀取最多 len字節的數據爲字節數組。
  
  long    skip(long n)
  
  跳過並從輸入流中丟棄 n字節的數據。
  
  available():要一次讀取多個字節時,常常用到InputStream.available()方法,這個方法能夠在讀寫操做前先得知數據流裏有多少個字節能夠讀取。須要注意的是,若是這個方法用在從本地文件讀取數據時,通常不會遇到問題,但若是是用於網絡操做,就常常會遇到一些麻煩。好比,Socket通信時,對方明明發來了1000個字節,可是本身的程序調用available()方法卻只獲得900,或者100,甚至是0,感受有點莫名其妙,怎麼也找不到緣由。其實,這是由於網絡通信每每是間斷性的,一串字節每每分幾批進行發送。本地程序調用available()方法有時獲得0,這多是對方尚未響應,也多是對方已經響應了,可是數據尚未送達本地。對方發送了1000個字節給你,也許分紅3批到達,這你就要調用3次available()方法才能將數據總數所有獲得。可否使用取決於實現了InputStream這個抽象類的具體子類中有沒有實現available這個方法。若是實現了那麼就能夠取得大小,若是沒有實現那麼就獲取不到。例如FileInputStream就實現了available方法,那麼就能夠用new byte[in.available()];這種方式。可是,網絡編程的時候Socket中取到的InputStream,就沒有實現這個方法,那麼就不可使用這種方式建立數組。
  
  複製代碼
  
  public static void main(String[] args) {
  
  String name="C:\\Study\\2401.jpg_wh1200.jpg";
  
  //        inputStream();
  
  /*Person per=new Student();
  
  per.doSomething();*/
  
  FileInputStream fis=null;
  
  try {
  
  File file=new File(name);
  
  fis=new FileInputStream(file);
  
  int available = fis.available();
  
  System.out.println(available);
  
  long n=500000;
  
  fis.skip(n);
  
  int available2 = fis.available(kunlunyule.com);
  
  System.out.println("available2 is  "+available2 );
  
  } catch (FileNotFoundException e) {
  
  // TODO Auto-generated catch block
  
  e.printStackTrace(www.rhyL158.com);
  
  } catch (IOException e1) {
  
  e1.printStackTrace();
  
  }finally {
  
  if(fis!= null) {
  
  try {
  
  fis.close();
  
  } catch (IOException e) {
  
  e.printStackTrace();
  
  }
  
  }
  
  }
  
  }
  
  複製代碼
  
  控制檯執行結果:
  
  532598
  
  available2 is 32598
  
  read()方法:今後輸入流中每次只讀取讀取一個數據字節。若是沒有輸入可用,則此方法將阻塞。 指定者:類 InputStream 中的 read  返回:下一個數據字節;若是已到達文件末尾,則返回 -1。
  
  一、此方法是從輸入流中讀取一個數據的字節,效率會很是低,更好的方法是用InputStream.read(byte[] b)或者InputStream.read(byte[] b,int off,int len)方法,一次讀取多個字節。通俗點講,即每調用一次read方法,從FileInputStream中讀取一個字節。
  
  二、返回下一個數據字節,若是已達到文件末尾,返回-1,這點除看難以理解,經過代碼測試理解不難。
  
  三、若是沒有輸入可用,則此方法將阻塞。這不用多解釋,你們在學習的時候,用到的Scannner sc = new Scanner(System.in);其中System.in就是InputStream(爲何?不明白的,請到System.class查閱in是個什麼東西!!),你們都深有體會,執行到此句代碼時,將等待用戶輸入   摘自 JAVA-FileInputStream之read方法 博客
  
  本地測試代碼以下:
  
  複製代碼
  
  public class Test1   {
  
  private static String name="C:\\Study\\output.txt";
  
  @Test
  
  public void Test1() {
  
  FileInputStream file=null;
  
  int i=0; //調用read(www.hxyl1618.com)次數
  
  try {
  
  file=new FileInputStream(name);
  
  int read =0;
  
  System.out.println("available is :"+file.available());//
  
  while(read != -1) {返回今後輸入流中能夠讀取(或跳過)的剩餘字節數的估計值  該文件輸入流值爲:68
  
  read= file.read();
  
  i++;
  
  System.out.println(read+"    and   i="+i);
  
  }
  
  } catch (FileNotFoundException e) {
  
  e.printStackTrace();
  
  }catch (IOException e) {
  
  e.printStackTrace(www.hengxuangyul.com);
  
  }finally {
  
  if( file != null ) {
  
  try {
  
  file.close();
  
  } catch (IOException e) {
  
  // TODO Auto-generated catch block
  
  e.printStackTrace(www.yisheng3yul.com);
  
  複製代碼
  
  控制檯輸出結果爲:
  
  控制檯數據結果
  
  對於文件系統中的文件。都可以使用FileInputStream流類以二進制的形式進行讀取。但是由於Java自己的定位在JVM之上,沒有處理計算機底層的能力。所以一些涉及底層處理的方法都是使用native方法調用第三方底層語言進行處理的。
  
  private static native void initIDs();
  
  private native void close0() throws IOException;
  
  private native void open0(String name) throws FileNotFoundException;   :打開文件
  
  private native int read0(www.chaoyul.com) throws IOException;   :讀取一個字節
  
  private native int readBytes(byte b[], int off, int len) throws IOException;  :讀取指定字節數
  
  public native long skip(long n) throws IOException;     丟棄指定字節,下次讀取時,從丟棄後的位置開始讀取
  
  public native int available(www.yczz2019.com) throws IOException;
  
  FileInputStream內部,有幾個native類型的方法,用於調用底層語言來完整對於文件系統的操做:
  
  FileInputStream流類內部提供了一種對於文件操做的機制,但是由於Java語言的侷限,FileInputStream需要經過native方法調用底層語言實現。
  
  Java層調用Native層函數兩種方式html

相關文章
相關標籤/搜索