Java-IO之FileDescriptor

来源:互联网 发布:网络推广大熊猫优化 编辑:程序博客网 时间:2024/05/22 00:37

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;                }        }    }}



0 0
原创粉丝点击