一。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; 

:以路径的方式初始一个输入流。其内部调用的是以下的构造方法

  1. public FileInputStream(String name) throws FileNotFoundException {
  2. this(name != null ? new File(name) : null);//当name不为空,就生成一个File对象 作为FileInputStream(File file)构造函数的参数
  3. }
  • public FileInputStream(File file) throws FileNotFoundException; 

:以File实例的方法初始一个输入流

源码为:

  1. public FileInputStream(File file) throws FileNotFoundException {
  2. String name = (file != null ? file.getPath() : null);
  3. SecurityManager security = System.getSecurityManager();
  4. if (security != null) {
  5. security.checkRead(name);
  6. }
  7. if (name == null) {
  8. throw new NullPointerException();
  9. }
  10. if (file.isInvalid()) {
  11. throw new FileNotFoundException("Invalid file path");
  12. }
  13. fd = new FileDescriptor();
  14. fd.attach(this);
  15. path = name;
  16. open(name);
  17. }

FileInputStream(File file) 构造方法

构造方法内部解析

SecurityManager security = System.getSecurityManager();

其中 当运行未知的Java程序的时候,该程序可能有恶意代码(删除系统文件、重启系统等),为了防止运行恶意代码对系统产生影响,需要对运行的代码的权限进行控制,这时候就要启用Java安全管理器(SecurityManager)。

1.默认的安全管理器配置文件是 $JAVA_HOME/jre/lib/security/java.policy,即当未指定配置文件时,将会使用该配置。

使用之前需要启动SecurityManager,启动有两种方式:参数方式、编码方式

    启动程序的时候通过附加参数启动安全管理器:

  1.     -Djava.security.manager

    若要同时指定配置文件的位置那么示例如下:

  1.     -Djava.security.manager -Djava.security.policy="E:/java.policy"
  1.     "="表示这个策略文件将和默认的策略文件一同发挥作用; "=="表示只使用指定的策略文件 。如 -Djava.security.policy==E:/temp/test1.policy或者 -Djava.security.policy=bin/com/test/test1.policy 
  1.     编码方式(不建议):
  1.     System.setSecurityManager(new SecurityManager());
  2.  
  3. 参数方式启动:

  1. 保存后在运行security就不为null ,走进security.checkRead(name); 抛错(使用了默认配置文件)

  1.  

这时候解决方式:(1)关闭安全管理器;(2)赋予该程序读取文件权限

打开管理器配置文件添加:

  1. grant {
  2.  
  3. permission java.io.FilePermission "C:\\Study\\*", "read";
  4. permission java.io.FilePermission "C:\\Study\\2401.jpg_wh1200.jpg", "write";
  5.  
  6. };

给程序添加文件读权限

其中    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:文件描述符类的实例用作表示打开文件,开放套接字或其他字节源或信宿的底层机器特定结构的不透明句柄。 文件描述符的主要实际用途是创建一个FileInputStreamFileOutputStream来包含它。

三。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,就没有实现这个方法,那么就不可以使用这种方式创建数组。

  1. public static void main(String[] args) {
  2. String name="C:\\Study\\2401.jpg_wh1200.jpg";
  3. // inputStream();
  4. /*Person per=new Student();
  5. per.doSomething();*/
  6. FileInputStream fis=null;
  7. try {
  8. File file=new File(name);
  9. fis=new FileInputStream(file);
  10. int available = fis.available();
  11. System.out.println(available);
  12. long n=500000;
  13. fis.skip(n);
  14. int available2 = fis.available();
  15. System.out.println("available2 is "+available2 );
  16.  
  17. } catch (FileNotFoundException e) {
  18. // TODO Auto-generated catch block
  19. e.printStackTrace();
  20. } catch (IOException e1) {
  21. e1.printStackTrace();
  22. }finally {
  23. if(fis!= null) {
  24. try {
  25. fis.close();
  26. } catch (IOException e) {
  27. e.printStackTrace();
  28. }
  29. }
  30. }
  31. }

控制台执行结果:

532598
available2 is 32598

read()方法:从此输入流中每次只读取读取一个数据字节。如果没有输入可用,则此方法将阻塞。 指定者:类 InputStream 中的 read  返回:下一个数据字节;如果已到达文件末尾,则返回 -1。

1、此方法是从输入流中读取一个数据的字节,效率会非常低,更好的方法是用InputStream.read(byte[] b)或者InputStream.read(byte[] b,int off,int len)方法,一次读取多个字节。通俗点讲,即每调用一次read方法,从FileInputStream中读取一个字节。

  2、返回下一个数据字节,如果已达到文件末尾,返回-1,这点除看难以理解,通过代码测试理解不难。

3、如果没有输入可用,则此方法将阻塞。这不用多解释,大家在学习的时候,用到的Scannner sc = new Scanner(System.in);其中System.in就是InputStream(为什么?不明白的,请到System.class查阅in是个什么东西!!),大家都深有体会,执行到此句代码时,将等待用户输入  摘自 JAVA-FileInputStream之read方法 博客

本地测试代码如下:

  1. public class Test1 {
  2.  
  3. private static String name="C:\\Study\\output.txt";
  4. @Test
  5. public void Test1() {
  6.  
  7. FileInputStream file=null;
  8. int i=0; //调用read()次数
  9. try {
  10. file=new FileInputStream(name);
  11. int read =0;
  12. System.out.println("available is :"+file.available());//
  13. while(read != -1) {返回从此输入流中可以读取(或跳过)的剩余字节数的估计值 该文件输入流值为:68
  14. read= file.read();
  15. i++;
  16. System.out.println(read+" and i="+i);
  17. }
  18. } catch (FileNotFoundException e) {
  19. e.printStackTrace();
  20. }catch (IOException e) {
  21. e.printStackTrace();
  22. }finally {
  23. if( file != null ) {
  24. try {
  25. file.close();
  26. } catch (IOException e) {
  27. // TODO Auto-generated catch block
  28. e.printStackTrace();
  29. }
  30. }
  31. }
  32. }
  33. }

控制台输出结果为:

  1. available is :68
  2. 228 and i=1
  3. 189 and i=2
  4. 160 and i=3
  5. 229 and i=4
  6. 165 and i=5
  7. 189 and i=6
  8. 239 and i=7
  9. 188 and i=8
  10. 140 and i=9
  11. 230 and i=10
  12. 136 and i=11
  13. 145 and i=12
  14. 230 and i=13
  15. 152 and i=14
  16. 175 and i=15
  17. 229 and i=16
  18. 188 and i=17
  19. 160 and i=18
  20. 228 and i=19
  21. 184 and i=20
  22. 137 and i=21
  23. 32 and i=22
  24. 230 and i=23
  25. 136 and i=24
  26. 145 and i=25
  27. 228 and i=26
  28. 187 and i=27
  29. 138 and i=28
  30. 229 and i=29
  31. 164 and i=30
  32. 169 and i=31
  33. 229 and i=32
  34. 190 and i=33
  35. 136 and i=34
  36. 229 and i=35
  37. 188 and i=36
  38. 128 and i=37
  39. 229 and i=38
  40. 191 and i=39
  41. 131 and i=40
  42. 229 and i=41
  43. 146 and i=42
  44. 140 and i=43
  45. 228 and i=44
  46. 189 and i=45
  47. 160 and i=46
  48. 231 and i=47
  49. 186 and i=48
  50. 166 and i=49
  51. 228 and i=50
  52. 188 and i=51
  53. 154 and i=52
  54. 32 and i=53
  55. 232 and i=54
  56. 175 and i=55
  57. 183 and i=56
  58. 229 and i=57
  59. 164 and i=58
  60. 154 and i=59
  61. 229 and i=60
  62. 164 and i=61
  63. 154 and i=62
  64. 230 and i=63
  65. 140 and i=64
  66. 135 and i=65
  67. 230 and i=66
  68. 149 and i=67
  69. 153 and i=68
  70. -1 and i=69

控制台数据结果

对于文件系统中的文件。都能够使用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() 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() throws IOException;

FileInputStream内部,有几个native类型的方法,用于调用底层语言来完整对于文件系统的操作:

FileInputStream流类内部提供了一种对于文件操作的机制,可是因为Java语言的局限,FileInputStream须要通过native方法调用底层语言实现

Java层调用Native层函数两种方式

什么是native

java基础学习_io流之FileInputStream的更多相关文章

  1. Java基础学习-IO流

    package IObasics; import java.io.FileWriter; import java.io.IOException; /*IO流 * 通过数据流.序列化和文件系统提供系统输 ...

  2. JAVA基础学习day20--IO流二-缓冲流、字节流

    一.缓冲流 1.1.字符流的缓冲区 缓冲区的出现是为了提高IO的读写效率 对应类 BufferedReader BufferedWriter 缓冲区要结合流才可以使用 在流的基础上对流的功能进行了增强 ...

  3. JAVA基础学习day22--IO流四-对象序列化、管道流、RandomAccessFile、DataStream、ByteArrayStream、转换流的字符编码

    一.对象序列化 1.1.对象序列化 被操作的对象需要实现Serializable接口 1.2.对象序列化流ObjectOutputStream与ObjectInputStream ObjectInpu ...

  4. JAVA基础学习day21--IO流三-File、Properties、PrintWriter与合并、分割流

    一.File 1.1.File概述 文件和目录路径名的抽象表示形式. 用户界面和操作系统使用与系统相关的路径名字符串 来命名文件和目录.此类呈现分层路径名的一个抽象的.与系统无关的视图.抽象路径名 有 ...

  5. JAVA基础学习day19--IO流一、FileWrite与FileReader

    一.IO简述 1.1.简述 IO:input/output IO流用来处理设备之间的数据传输 Java对数据的操作是通过流的方式 Java用于操作流的对象都在IO包中. 1.2.结构 字节流抽象类: ...

  6. java基础学习总结——流

    一.JAVA流式输入/输出原理

  7. JAVA基础学习之流的简述及演示案例、用缓冲区方法buffer读写文件、File类对象的使用、Serializable标记接口(6)

    1.流的简述及演示案例输入流和输出流相对于内存设备而言.将外设中的数据读取到内存中:输入将内存的数写入到外设中:输出.字符流的由来:其实就是:字节流读取文字字节数据后,不直接操作而是先查指定的编码表. ...

  8. 转载-java基础学习汇总

    共2页: 1 2 下一页  Java制作证书的工具keytool用法总结 孤傲苍狼 2014-06-24 11:03 阅读:25751 评论:3     Java基础学习总结——Java对象的序列化和 ...

  9. 尚学堂JAVA基础学习笔记

    目录 尚学堂JAVA基础学习笔记 写在前面 第1章 JAVA入门 第2章 数据类型和运算符 第3章 控制语句 第4章 Java面向对象基础 1. 面向对象基础 2. 面向对象的内存分析 3. 构造方法 ...

随机推荐

  1. Java 自定义异常(转载)

    1.异常的分类 1. 非运行时异常(Checked Exception) Java中凡是继承自Exception但不是继承自RuntimeException的类都是非运行时异常. 2. 运行时异常(R ...

  2. 在java项目启动时就执行某操作

    在java启动时大概有四种,此处只介绍3种 1.在启动的方法上使用通过@PostConstruct方法实现初始化bean进行操作 2.通过bean实现InitializingBean接口 @Overr ...

  3. 使用docker运行GitLab

    从docker镜像拉取代码,docker pull gitlab/gitlab-ce:latest. 创建/srv/gitlab目录sudo mkdir /srv/gitlab 启动GitLab CE ...

  4. TCP11种状态集之TIME_WAIT

    先看一个实例,上代码: #!/usr/bin/env python3 # _*_ coding:utf- _*_ import socket sk = socket.socket() sk.bind( ...

  5. Codeforces Gym101518E:The Pharaoh's Curse(BFS + 离散化)

    题目链接 题意 给出一个n*m的地图,人的当前位置是'S',还有不超过两个的箱子'X',任意多个按钮'B',不超过100个可以走的点'.',还有一个在边界的出口'E',当且仅当所有的按钮都被箱子盖住的 ...

  6. Nginx Location匹配顺序

    理论部分 文字释义匹配规则如下: 略述: 1.nginx服务器首先在server块的多个location块中搜索是否有标准的uri和请求字符串匹配.如果有多个标准uri可以匹配,就匹配其中匹配度最高的 ...

  7. mpvue开发微信小程序

    前段时间,美团开源了mpvue这个项目,使得我们又多了一种用来开发小程序的框架选项.由于mpvue框架是完全基于Vue框架的(重写了其runtime和compiler),因此在用法上面是高度和Vue一 ...

  8. c++学习书籍推荐《C++语言的设计与演化》下载

    百度云及其他网盘下载地址:点我 编辑推荐 <C++语言的设计与演化>由C++语言的设计者Bjarne Stroustrup著就,是一本阐述C++语言的设计及开发过程的无可争辩的内情手册.S ...

  9. C语言学习推荐《C语言参考手册(原书第5版)》下载

  10. CDQZ集训DAY10 日记

    又一次跪了,跪在了神奇的数据范围上. T1上来打完暴力之后觉得是数据结构题,像三维偏序,于是开始往各种数据结构上想,主席树,线段树+calc,平衡树,树套树,CDQ……最终在经过一番思考之后选择去打C ...