[一]FileDescriptor文件描述符 标准输入输出错误 文件描述符

文件描述符

 
当应用程序请求打开或者操做文件时,操做系统为应用程序设置一张文件列表,具体的实现形式此处不深刻说明
操做系统会提供给你一个非负整数,做为一个索引号,它的做用就像地址或者说指针或者说偏移量
这个索引号就用来定位文件数据在内存中的位置.
这个概念在类Unix系统叫作文件描述符, linux把全部东西都被当作是文件,好比文件、目录、进程、网络socket、各类硬件设备等
这个概念在Windows下 称之为句柄, 句柄是Windows下各类对象的标识符, 好比文件、资源、菜单、光标、位图等
那么,如今你应该能够理解文件描述符的含义了

文件描述符  之于文件系统(操做系统中的一切都是文件描述符 可使用文件描述符描述任何一个资源对象
就如同Class 之于java语言同样(java中一切都是类,都是一个Class的实例,任何一个类都用Class对象的实例来描述

Java中使用FileDescriptor 来抽象文件描述符这一律念
package java.io;
image_5b923c62_6c7f
对于FileInputStream/FileOutputStream/RandomAccessFile,使用handle来表示底层的文件句柄
对于ServerSocket/Socket,使用fd来表示底层的文件句柄
FileDescriptor的fd和handle的无效值是-1


看下API的描述:
文件描述符类的实例用做与基础机器有关的某种结构的不透明句柄
该结构表示开放文件、开放套接字或者字节的另外一个源或接收者。
文件描述符的主要实际用途是建立一个包含该结构的 FileInputStream 或 FileOutputStream。
 
应用程序不该建立本身的文件描述符。 

其实说白了,就是文件描述符的实例,就是用来表示文件的一个指针/索引. 操做系统经过这个值与应用程序交互
如同你的电话号码同样,在不少场景,他就至关于你,   虽然,他彻底不是你,
好比朋友想找你聊天,有人托你办事,保险公司推销等等,经过电话均可以定位到你
 
并且,你本身能造一个电话号码么?显然不行,必须是运营商提供给你的
咱们的文件描述符,也是如此,应用程序不该该建立本身的文件描述符
他的构造方法,只能建立一个无效的文件描述符

不该该建立本身的文件描述符,能够直接理解为:
这东西是底层实现的内容,操做系统来传递给你
并且,对于文件的其余的一些操做,最底层的实现也仍旧是操做系统来搞
这就至关于操做系统给你的一个指针,钥匙
你须要服务的时候,拿给操做系统便可,具体到底怎么玩,你管不上,也管不了
 
想要理解文件描述符只须要理解,文件的抽象概念是操做系统负责管理维护的
应用程序都是在请求操做系统帮忙,JVM也就是个应用程序
无论那个位置到底存放的是什么,对于应用程序来讲就是一个描述符
操做系统提供了一致性的接口访问途径,就是经过这个描述符
描述符背后究竟是什么,操做系统屏蔽了这些东西
这样子的实现,对应用程序程序员来讲,就是不须要在关注他究竟是个什东西,操做系统来搞定
 
image_5b923c62_27aa
 

FileDescriptor中的三个描述符

FileDescriptor 内置了三个文件描述符 分别是  in   out  err
类型是FileDescriptor  这是java层面的描述
具体的值是 0  1   2  ,这是操做系统层面的描述
 
在linux 中, 每一个进程启动时都打开3个文件(linux 中一切都是文件): 
* 标准输入  0
* 标准输出  1
* 标准错误  2
 
三个描述符,经过调用私有方法 standardStream进行建立初始化
建立一个FileDescriptor 而且,设置他的handle值
内部的set(fd)是一个本地方法
说白了,就是经过调用本地方法,得到操做系统对标准输入/输出/错误的三个文件描述符
 
image_5b923c63_6b43
 
 
image_5b923c63_409e
 
注释中也说的很清楚,文件描述符通常不直接使用
经过使用System.in  System.out System.err
 

文件描述符在System类中的应用

在System 中   in  out err  都是 final  static的
标准的输入输出是共享,可是java是多线程的
所以它们必须受到特别的处理,在系统初始化完成以前,线程严禁使用这几个特殊对象;
又由于这些对象都是静态的,所以java的类加载机制会在System类加载的时候就会初始化,这就形成了一对矛盾;
为解决这对矛盾,System在加载是将它们初始化为null,等加在完成后,经过  initializeSystemClass
 
System中in out  err中的定义部分,全都是final static
注释中也很明确的说明了 将会调用 initializeSystemClass  进行部分初始化工做
 
image_5b923c63_21ce
 
initializeSystemClass 方法的关键部位 以及 本地的setIn0 setOut0 setErr0
initializeSystemClass 方法对于这块来讲,主要就是
使用三个文件描述符  建立了 FileInputStream  以及 FileOutputStream
对于Out以及Err又根据encoding 转换为PrintStream
而后经过本地方法进行设置
因此说,那三个专门的文件描述符通常不直接使用
取而代之的则是使用文件描述符 初始化设置过的流对象
 
image_5b923c63_5566
 
 
应用程序不建立文件描述符, 都是由系统调用, 也就是本地方法来操做的
应用程序只是得到,  而后使用,  所谓使用,最终也仍是须要借助于操做系统
是应用程序 操做文件 时 与操做系统进行交互时,必须的数据项 
相关文章
相关标签/搜索