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. Linux下双网卡Firewalld的配置流程

    实验室拟态存储的项目需要通过LVS-NAT模式通过LVS服务器来区隔内外网的服务,所以安全防护的重心则落在了LVS服务器之上.笔者最终选择通过firewalld放行端口的方式来实现需求,由于firew ...

  2. jdk1.7和jdk1.8区别

    转自:http://www.2cto.com/kf/201307/225968.html 本文是我学习了解了jdk7和jdk8的一些新特性的一些资料,有兴趣的大家可以浏览下下面的内容. 官方文档:ht ...

  3. 解决scroll在ios上卡顿问题和兼容ios不支持:active伪类情况

    //有时候因为滚动层级元素过多会产生卡顿,特别在ios上十分明显,如果不想更换其他实现方式,可以加:-webkit-overflow-scrolling: touch; 开启硬件加速: 兼容ios不支 ...

  4. JVM之Java虚拟机详解

    这篇文章解释了Java 虚拟机(JVM)的内部架构.下图显示了遵守Java SE 7 规范的典型的 JVM 核心内部组件. 上图显示的组件分两个章节解释.第一章讨论针对每个线程创建的组件,第二章节讨论 ...

  5. MeshCollider双面化脚本

    由于MeshCollider组件可以挂载多个,所以不需要Mesh重新合并了. 除了反转法线还需要反转所有三角面的顺序 脚本如下: using System.Collections; using Sys ...

  6. javascript 中如何判断是否是JSON格式的字符串

    var stringToJson = function(value){ try{ eval('('+value+')'); return angular.fromJson(value); } catc ...

  7. PHP $_GET 变量

    $_GET 变量 预定义的 $_GET 变量用于收集来自 method="get" 的表单中的值. 从带有 GET 方法的表单发送的信息,对任何人都是可见的(会显示在浏览器的地址栏 ...

  8. zookeeper基本原理及适用场景 转:http://blog.chinaunix.net/uid-26748613-id-4536290.html

    1.1 zookeeper简介 Zookeeper 是 Hadoop 生态系统中的协同实现,是Hadoop集群管理的一个必不可少的模块,它主要来控制集群中的数据,如它管理Hadoop集群中的NameN ...

  9. 在Spring Boot框架下使用WebSocket实现聊天功能

    上一篇博客我们介绍了在Spring Boot框架下使用WebSocket实现消息推送,消息推送是一对多,服务器发消息发送给所有的浏览器,这次我们来看看如何使用WebSocket实现消息的一对一发送,模 ...

  10. 安卓热修复之AndFIX

    我致力于最新的前沿安卓技术分析和使用教学,不打算将很多很深的东西,因为有多少人愿意沉下你的心境去学习难点?我一般只会简单提及.文字错漏在所难免还希望同学们喜欢 热修复介绍 热修复是什么? 如果你一个项 ...