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

相关文章
相关标签/搜索