Java-IO之FileDescriptor
FileDescriptor是文件描述符,可以被用来表示开放文件,开放套接字等,FileDescriptor可以被看成某个文件,但无法对该文件进行操作,需要新创建FileDescriptor对应的FileOutputStream再对文件进行操作。
FileDescriptor示例代码:
public class FileDescriptorTest {
private static final String FileName = "file.txt";
private static final String OutText = "Hi FileDescriptor";
public static void main(String[] args) {
testWrite();
testRead();
testStandFD() ;
//System.out.println(OutText);
}
/**
* FileDescriptor.out 的测试程序
* 该程序的效果 等价于 System.out.println(OutText);
*/
private static void testStandFD() {
// 创建FileDescriptor.out 对应的PrintStream
PrintStream out = new PrintStream(new FileOutputStream(FileDescriptor.out));
// 在屏幕上输出“Hi FileDescriptor”
out.println(OutText);
out.close();
}
/**
* FileDescriptor写入示例程序
* (01) 为了说明,"通过文件名创建FileOutputStream"与“通过文件描述符创建FileOutputStream”对象是等效的
* (02) 该程序会在“该源文件”所在目录新建文件"file.txt",并且文件内容是"Aa"。
*/
private static void testWrite() {
try {
// 新建文件“file.txt”对应的FileOutputStream对象
FileOutputStream out1 = new FileOutputStream(FileName);
// 获取文件“file.txt”对应的“文件描述符”
FileDescriptor fdout = out1.getFD();
// 根据“文件描述符”创建“FileOutputStream”对象
FileOutputStream out2 = new FileOutputStream(fdout);
out1.write('A'); // 通过out1向“file.txt”中写入'A'
out2.write('a'); // 通过out2向“file.txt”中写入'A'
if (fdout!=null)
System.out.printf("fdout(%s) is %s\n",fdout, fdout.valid());
out1.close();
out2.close();
} catch(IOException e) {
e.printStackTrace();
}
}
/**
* FileDescriptor读取示例程序
*
* 为了说明,"通过文件名创建FileInputStream"与“通过文件描述符创建FileInputStream”对象是等效的
*/
private static void testRead() {
try {
// 新建文件“file.txt”对应的FileInputStream对象
FileInputStream in1 = new FileInputStream(FileName);
// 获取文件“file.txt”对应的“文件描述符”
FileDescriptor fdin = in1.getFD();
// 根据“文件描述符”创建“FileInputStream”对象
FileInputStream in2 = new FileInputStream(fdin);
System.out.println("in1.read():"+(char)in1.read());
System.out.println("in2.read():"+(char)in2.read());
if (fdin!=null)
System.out.printf("fdin(%s) is %s\n", fdin, fdin.valid());
in1.close();
in2.close();
} catch(IOException e) {
e.printStackTrace();
}
}
}
in1.read():A
in2.read():a
fdin(java.io.FileDescriptor@24de1f47) is true
Hi FileDescriptor
基于JDK8的FileDescriptor的源码:
public final class FileDescriptor {
private int fd;
private long handle;
private Closeable parent;
private List<Closeable> otherParents;
private boolean closed;
/**
* Constructs an (invalid) FileDescriptor
* object.
*/
public /**/ FileDescriptor() {
fd = -1;
handle = -1;
}
static {
initIDs();
}
// Set up JavaIOFileDescriptorAccess in SharedSecrets
static {
sun.misc.SharedSecrets.setJavaIOFileDescriptorAccess(
new sun.misc.JavaIOFileDescriptorAccess() {
public void set(FileDescriptor obj, int fd) {
obj.fd = fd;
}
public int get(FileDescriptor obj) {
return obj.fd;
}
public void setHandle(FileDescriptor obj, long handle) {
obj.handle = handle;
}
public long getHandle(FileDescriptor obj) {
return obj.handle;
}
}
);
}
/**
* A handle to the standard input stream. Usually, this file
* descriptor is not used directly, but rather via the input stream
* known as {@code System.in}.
*
* @see java.lang.System#in
*/
//标准输入流
public static final FileDescriptor in = standardStream(0);
/**
* A handle to the standard output stream. Usually, this file
* descriptor is not used directly, but rather via the output stream
* known as {@code System.out}.
* @see java.lang.System#out
*/
//标准输出流
public static final FileDescriptor out = standardStream(1);
/**
* A handle to the standard error stream. Usually, this file
* descriptor is not used directly, but rather via the output stream
* known as {@code System.err}.
*
* @see java.lang.System#err
*/
//标准错误
public static final FileDescriptor err = standardStream(2);
/**
* Tests if this file descriptor object is valid.
*
* @return {@code true} if the file descriptor object represents a
* valid, open file, socket, or other active I/O connection;
* {@code false} otherwise.
*/
//文件描述对象是否有效
public boolean valid() {
return ((handle != -1) || (fd != -1));
}
/**
* Force all system buffers to synchronize with the underlying
* device. This method returns after all modified data and
* attributes of this FileDescriptor have been written to the
* relevant device(s). In particular, if this FileDescriptor
* refers to a physical storage medium, such as a file in a file
* system, sync will not return until all in-memory modified copies
* of buffers associated with this FileDesecriptor have been
* written to the physical medium.
*
* sync is meant to be used by code that requires physical
* storage (such as a file) to be in a known state For
* example, a class that provided a simple transaction facility
* might use sync to ensure that all changes to a file caused
* by a given transaction were recorded on a storage medium.
*
* sync only affects buffers downstream of this FileDescriptor. If
* any in-memory buffering is being done by the application (for
* example, by a BufferedOutputStream object), those buffers must
* be flushed into the FileDescriptor (for example, by invoking
* OutputStream.flush) before that data will be affected by sync.
*
* @exception SyncFailedException
* Thrown when the buffers cannot be flushed,
* or because the system cannot guarantee that all the
* buffers have been synchronized with physical media.
* @since JDK1.1
*/
public native void sync() throws SyncFailedException;
/* This routine initializes JNI field offsets for the class */
private static native void initIDs();
private static native long set(int d);
private static FileDescriptor standardStream(int fd) {
FileDescriptor desc = new FileDescriptor();
desc.handle = set(fd);
return desc;
}
/*
* Package private methods to track referents.
* If multiple streams point to the same FileDescriptor, we cycle
* through the list of all referents and call close()
*/
/**
* Attach a Closeable to this FD for tracking.
* parent reference is added to otherParents when
* needed to make closeAll simpler.
*/
synchronized void attach(Closeable c) {
if (parent == null) {
// first caller gets to do this
parent = c;
} else if (otherParents == null) {
otherParents = new ArrayList<>();
otherParents.add(parent);
otherParents.add(c);
} else {
otherParents.add(c);
}
}
/**
* Cycle through all Closeables sharing this FD and call
* close() on each one.
*
* The caller closeable gets to call close0().
*/
@SuppressWarnings("try")
synchronized void closeAll(Closeable releaser) throws IOException {
if (!closed) {
closed = true;
IOException ioe = null;
try (Closeable c = releaser) {
if (otherParents != null) {
for (Closeable referent : otherParents) {
try {
referent.close();
} catch(IOException x) {
if (ioe == null) {
ioe = x;
} else {
ioe.addSuppressed(x);
}
}
}
}
} catch(IOException ex) {
/*
* If releaser close() throws IOException
* add other exceptions as suppressed.
*/
if (ioe != null)
ex.addSuppressed(ioe);
ioe = ex;
} finally {
if (ioe != null)
throw ioe;
}
}
}
}
Java-IO之FileDescriptor的更多相关文章
- java io系列09之 FileDescriptor总结
本章对FileDescriptor进行介绍 转载请注明出处:http://www.cnblogs.com/skywang12345/p/io_09.html FileDescriptor 介绍 Fil ...
- Java IO(三)FileDescriptor
Java IO(三)FileDescriptor 一.介绍 FileDescriptor 是文件描述符,用来表示开放文件.开放套接字等.当 FileDescriptor 表示文件时,我们可以通俗的将 ...
- Java IO之字符流和文件
前面的博文介绍了字节流,那字符流又是什么流?从字面意思上看,字节流是面向字节的流,字符流是针对unicode编码的字符流,字符的单位一般比字节大,字节可以处理任何数据类型,通常在处理文本文件内容时,字 ...
- [Java IO]02_字节流
概要 字节流有两个核心抽象类:InputStream 和 OutputStream.所有的字节流类都继承自这两个抽象类. InputStream 负责输入,OutputStream 负责输出. 字节流 ...
- Java IO之字节流
Java中的输入是指从数据源等读到Java程序中,这里的数据源可以是文件,内存或网络连接,输出则是指从Java程序中写到目的地. 输入输出流可以分为以下几种类型(暂时不考虑File类) 类名 中文名 ...
- Java IO设计模式彻底分析 (转载)
一.引子(概括地介绍Java的IO) 无论是哪种编程语言,输入跟输出都是重要的一部分,Java也不例外,而且Java将输入/输出的功能和使用范畴做了很大的扩充.它采用了流的 机制来实现输入/输出,所谓 ...
- JAVA IO 字节流与字符流
文章出自:听云博客 题主将以三个章节的篇幅来讲解JAVA IO的内容 . 第一节JAVA IO包的框架体系和源码分析,第二节,序列化反序列化和IO的设计模块,第三节异步IO. 本文是第一节. ...
- 【JAVA IO流之字符流】
一.概述. java对数据的操作是通过流的方式.java用于操作流的对象都在IO包中.流按照操作数据不同分为两种,字节流和字符流.流按照流向分为输入流,输出流. 输入输出的“入”和“出”是相当于内存来 ...
- Java IO 之 FileInputStream & FileOutputStream源码分析
Writer :BYSocket(泥沙砖瓦浆木匠) 微 博:BYSocket 豆 瓣:BYSocket FaceBook:BYSocket Twitter ...
- java io系列01之 "目录"
java io 系列目录如下: 01. java io系列01之 "目录" 02. java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括 ...
随机推荐
- 关于ajax的content-download时间过慢问题的解决方案与思考
前言: 做前端架构很久很久了,经常到我这里都是些棘手的问题,之前没有养成很好的记录问题的习惯,以后会努力成文,积累. 于是今天就有个这篇文章.关于ajax的content-download时间过慢 ...
- CentOS7.2安装mysql5.6
1.卸载系统自带的Mariadb [root@localhost~]# rpm -qa|grep mariadb //查询出已安装的mariadb [root@localhost~]# rpm -e ...
- python之with的使用
python之with使用 with工作原理 紧跟with后面的语句被求值后,返回对象的__e ...
- java 获得当前时间前指定几个小时的时间?
//@2016-12-13 获取当前时间,指定前面多少小时的时间 //返回格式YYYYMMDDHHMMSS public static String getBeforeHourTime(int iho ...
- javascript装饰器模式
装饰器模式 什么是装饰器 原名decorator 被翻译为装饰器 可以理解为装饰 修饰 包装等意 现实中的作用 一间房子通过装饰可以变得更华丽,功能更多 类似一部手机可以单独使用 但是很多人都愿意家个 ...
- Tomcat关闭日志输出
tomcat中禁用catalina.out的输出,又可能很大. 1.直接修改catalina.sh文件的输出语句. 在文件中找到以下内容. if [ -z "$CATALINA_OUT&qu ...
- 去除html标记和替换script标记
1: /// <summary> 2: /// 去除HTML标记 3: /// </summary> 4: /// <param name="NoHTML&qu ...
- eclipse中启动tomcat,localhost:8080无法访问
问题 eclipse中启动tomcat,项目可以正常运行,但是localhost:8080无法访问. 关闭eclipse中的Tomact,直接从tomcat/bin 下的startup.bat启动,l ...
- Docker配置 DNS
Docker 没有为每个容器专门定制镜像,那么怎么自定义配置容器的主机名和 DNS 配置呢? 秘诀就是它利用虚拟文件来挂载到来容器的 3 个相关配置文件. 在容器中使用 mount 命令可以看到挂载信 ...
- 初始化nodejs+webpack+vuejs
安装nodejs 4.x 参考 curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash - sudo apt-get install ...