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();
            }
    }
}
运行结果:
fdout(java.io.FileDescriptor@1ea21c07) is true

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的更多相关文章

  1. java io系列09之 FileDescriptor总结

    本章对FileDescriptor进行介绍 转载请注明出处:http://www.cnblogs.com/skywang12345/p/io_09.html FileDescriptor 介绍 Fil ...

  2. Java IO(三)FileDescriptor

    Java IO(三)FileDescriptor 一.介绍 FileDescriptor 是文件描述符,用来表示开放文件.开放套接字等.当 FileDescriptor 表示文件时,我们可以通俗的将 ...

  3. Java IO之字符流和文件

    前面的博文介绍了字节流,那字符流又是什么流?从字面意思上看,字节流是面向字节的流,字符流是针对unicode编码的字符流,字符的单位一般比字节大,字节可以处理任何数据类型,通常在处理文本文件内容时,字 ...

  4. [Java IO]02_字节流

    概要 字节流有两个核心抽象类:InputStream 和 OutputStream.所有的字节流类都继承自这两个抽象类. InputStream 负责输入,OutputStream 负责输出. 字节流 ...

  5. Java IO之字节流

    Java中的输入是指从数据源等读到Java程序中,这里的数据源可以是文件,内存或网络连接,输出则是指从Java程序中写到目的地. 输入输出流可以分为以下几种类型(暂时不考虑File类) 类名 中文名 ...

  6. Java IO设计模式彻底分析 (转载)

    一.引子(概括地介绍Java的IO) 无论是哪种编程语言,输入跟输出都是重要的一部分,Java也不例外,而且Java将输入/输出的功能和使用范畴做了很大的扩充.它采用了流的 机制来实现输入/输出,所谓 ...

  7. JAVA IO 字节流与字符流

    文章出自:听云博客 题主将以三个章节的篇幅来讲解JAVA IO的内容 . 第一节JAVA IO包的框架体系和源码分析,第二节,序列化反序列化和IO的设计模块,第三节异步IO. 本文是第一节.     ...

  8. 【JAVA IO流之字符流】

    一.概述. java对数据的操作是通过流的方式.java用于操作流的对象都在IO包中.流按照操作数据不同分为两种,字节流和字符流.流按照流向分为输入流,输出流. 输入输出的“入”和“出”是相当于内存来 ...

  9. Java IO 之 FileInputStream & FileOutputStream源码分析

    Writer      :BYSocket(泥沙砖瓦浆木匠) 微         博:BYSocket 豆         瓣:BYSocket FaceBook:BYSocket Twitter   ...

  10. java io系列01之 "目录"

    java io 系列目录如下: 01. java io系列01之  "目录" 02. java io系列02之 ByteArrayInputStream的简介,源码分析和示例(包括 ...

随机推荐

  1. H3C交换机如何配置管理VLAN

    1.输入"system-view"(简写"sys"),进入系统配置模式[H3C],2.下面就可以开始取消默认管理vlan了,输入"undo inter ...

  2. 前端开发利器VSCode

    最近找到一款非常好用的开发利器,VSCode.一直认为微软做的东西都很一般,这个软件让我刮目相看了. 之前使用webstorm卡的不行,换了这个非常好用. 用着还不错,这里记录下一些使用的心得. VS ...

  3. Sublime Text3时间戳查看转换插件的开发

    平常配置表中,经常需要用到时间配置,比如活动开始结束.从可读性上,我们喜欢2017-04-27 17:00:00,从程序角度,我们喜欢用1493283600.前者是包含时区概念的,而后者市区无关,所以 ...

  4. Servlet 执行流程 生命周期 ServletConfig 线程安全

    Day34 servlet 三.如何使用Servlet 1.继承GenericServlet类(通用) (1)GenericServlet类有一个关键的设计,定义了一个私有的ServletConfig ...

  5. 学习C语言第一天!

    整理心得笔记: 1)c语言程序由函数构成,每个函数可以实现一个或多个功能.  2)一个正规程序可以有多个函数,但是有且只有一个主函数.  3)函数只有在被调用的时候才执行,主函数由系统调用执行.  4 ...

  6. 多表insert操作详解

    --1.无条件的多表insert all ; ; ; --没有条件,向多个目标表全量插入,必须有all insert all --不指定emp_1后面的列,也不指定values,那么emp_1中的所有 ...

  7. 将Python当作计算器

    在交互模式中,最近一个表达式的值赋给变量 _.这样我们就可以把它当作一个桌面计算器,很方便的用于连续计算.例如: >>> price = 1.25 #声明变量price >&g ...

  8. JavaScript 知识图谱

  9. 安卓高级2 Volley框架的使用案例

    初始化类: MyApp.java package qianfeng.com.day37_volley_pull.app; import android.app.Application; import ...

  10. iOS开源加密相册Agony的实现(二)

    简介 虽然目前市面上有一些不错的加密相册App,但不是内置广告,就是对上传的张数有所限制.本文介绍了一个加密相册的制作过程,该加密相册将包括多密码(输入不同的密码即可访问不同的空间,可掩人耳目).Wi ...