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实例的方法初始一个输入流
源码为:
- 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);
- }
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 对象。 |
关于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();
- System.out.println("available2 is "+available2 );
- } catch (FileNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } 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。
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方法 博客
本地测试代码如下:
- public class Test1 {
- private static String name="C:\\Study\\output.txt";
- @Test
- public void Test1() {
- FileInputStream file=null;
- int i=0; //调用read()次数
- 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();
- }finally {
- if( file != null ) {
- try {
- file.close();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- }
- }
控制台输出结果为:
- available is :68
- 228 and i=1
- 189 and i=2
- 160 and i=3
- 229 and i=4
- 165 and i=5
- 189 and i=6
- 239 and i=7
- 188 and i=8
- 140 and i=9
- 230 and i=10
- 136 and i=11
- 145 and i=12
- 230 and i=13
- 152 and i=14
- 175 and i=15
- 229 and i=16
- 188 and i=17
- 160 and i=18
- 228 and i=19
- 184 and i=20
- 137 and i=21
- 32 and i=22
- 230 and i=23
- 136 and i=24
- 145 and i=25
- 228 and i=26
- 187 and i=27
- 138 and i=28
- 229 and i=29
- 164 and i=30
- 169 and i=31
- 229 and i=32
- 190 and i=33
- 136 and i=34
- 229 and i=35
- 188 and i=36
- 128 and i=37
- 229 and i=38
- 191 and i=39
- 131 and i=40
- 229 and i=41
- 146 and i=42
- 140 and i=43
- 228 and i=44
- 189 and i=45
- 160 and i=46
- 231 and i=47
- 186 and i=48
- 166 and i=49
- 228 and i=50
- 188 and i=51
- 154 and i=52
- 32 and i=53
- 232 and i=54
- 175 and i=55
- 183 and i=56
- 229 and i=57
- 164 and i=58
- 154 and i=59
- 229 and i=60
- 164 and i=61
- 154 and i=62
- 230 and i=63
- 140 and i=64
- 135 and i=65
- 230 and i=66
- 149 and i=67
- 153 and i=68
- -1 and i=69
控制台数据结果
- 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基础学习_io流之FileInputStream的更多相关文章
- Java基础学习-IO流
package IObasics; import java.io.FileWriter; import java.io.IOException; /*IO流 * 通过数据流.序列化和文件系统提供系统输 ...
- JAVA基础学习day20--IO流二-缓冲流、字节流
一.缓冲流 1.1.字符流的缓冲区 缓冲区的出现是为了提高IO的读写效率 对应类 BufferedReader BufferedWriter 缓冲区要结合流才可以使用 在流的基础上对流的功能进行了增强 ...
- JAVA基础学习day22--IO流四-对象序列化、管道流、RandomAccessFile、DataStream、ByteArrayStream、转换流的字符编码
一.对象序列化 1.1.对象序列化 被操作的对象需要实现Serializable接口 1.2.对象序列化流ObjectOutputStream与ObjectInputStream ObjectInpu ...
- JAVA基础学习day21--IO流三-File、Properties、PrintWriter与合并、分割流
一.File 1.1.File概述 文件和目录路径名的抽象表示形式. 用户界面和操作系统使用与系统相关的路径名字符串 来命名文件和目录.此类呈现分层路径名的一个抽象的.与系统无关的视图.抽象路径名 有 ...
- JAVA基础学习day19--IO流一、FileWrite与FileReader
一.IO简述 1.1.简述 IO:input/output IO流用来处理设备之间的数据传输 Java对数据的操作是通过流的方式 Java用于操作流的对象都在IO包中. 1.2.结构 字节流抽象类: ...
- java基础学习总结——流
一.JAVA流式输入/输出原理
- JAVA基础学习之流的简述及演示案例、用缓冲区方法buffer读写文件、File类对象的使用、Serializable标记接口(6)
1.流的简述及演示案例输入流和输出流相对于内存设备而言.将外设中的数据读取到内存中:输入将内存的数写入到外设中:输出.字符流的由来:其实就是:字节流读取文字字节数据后,不直接操作而是先查指定的编码表. ...
- 转载-java基础学习汇总
共2页: 1 2 下一页 Java制作证书的工具keytool用法总结 孤傲苍狼 2014-06-24 11:03 阅读:25751 评论:3 Java基础学习总结——Java对象的序列化和 ...
- 尚学堂JAVA基础学习笔记
目录 尚学堂JAVA基础学习笔记 写在前面 第1章 JAVA入门 第2章 数据类型和运算符 第3章 控制语句 第4章 Java面向对象基础 1. 面向对象基础 2. 面向对象的内存分析 3. 构造方法 ...
随机推荐
- Java 自定义异常(转载)
1.异常的分类 1. 非运行时异常(Checked Exception) Java中凡是继承自Exception但不是继承自RuntimeException的类都是非运行时异常. 2. 运行时异常(R ...
- 在java项目启动时就执行某操作
在java启动时大概有四种,此处只介绍3种 1.在启动的方法上使用通过@PostConstruct方法实现初始化bean进行操作 2.通过bean实现InitializingBean接口 @Overr ...
- 使用docker运行GitLab
从docker镜像拉取代码,docker pull gitlab/gitlab-ce:latest. 创建/srv/gitlab目录sudo mkdir /srv/gitlab 启动GitLab CE ...
- TCP11种状态集之TIME_WAIT
先看一个实例,上代码: #!/usr/bin/env python3 # _*_ coding:utf- _*_ import socket sk = socket.socket() sk.bind( ...
- Codeforces Gym101518E:The Pharaoh's Curse(BFS + 离散化)
题目链接 题意 给出一个n*m的地图,人的当前位置是'S',还有不超过两个的箱子'X',任意多个按钮'B',不超过100个可以走的点'.',还有一个在边界的出口'E',当且仅当所有的按钮都被箱子盖住的 ...
- Nginx Location匹配顺序
理论部分 文字释义匹配规则如下: 略述: 1.nginx服务器首先在server块的多个location块中搜索是否有标准的uri和请求字符串匹配.如果有多个标准uri可以匹配,就匹配其中匹配度最高的 ...
- mpvue开发微信小程序
前段时间,美团开源了mpvue这个项目,使得我们又多了一种用来开发小程序的框架选项.由于mpvue框架是完全基于Vue框架的(重写了其runtime和compiler),因此在用法上面是高度和Vue一 ...
- c++学习书籍推荐《C++语言的设计与演化》下载
百度云及其他网盘下载地址:点我 编辑推荐 <C++语言的设计与演化>由C++语言的设计者Bjarne Stroustrup著就,是一本阐述C++语言的设计及开发过程的无可争辩的内情手册.S ...
- C语言学习推荐《C语言参考手册(原书第5版)》下载
- CDQZ集训DAY10 日记
又一次跪了,跪在了神奇的数据范围上. T1上来打完暴力之后觉得是数据结构题,像三维偏序,于是开始往各种数据结构上想,主席树,线段树+calc,平衡树,树套树,CDQ……最终在经过一番思考之后选择去打C ...