java IO(三):FileOutputStream

此类用于向文件中写入数据或是创建文件。

首先对于其构造方法,虽然有四个,分别是

复制代码
1.public FileOutputStream(String name) throws FileNotFoundException {
        this(name != null ? new File(name) : null, false);
    }


2.public FileOutputStream(String name, boolean append)
        throws FileNotFoundException
    {
        this(name != null ? new File(name) : null, append);
    }


3.public FileOutputStream(File file) throws FileNotFoundException {
        this(file, false);
    }


4.public FileOutputStream(File file, boolean append)
        throws FileNotFoundException
    {
        String name = (file != null ? file.getPath() : null);
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkWrite(name);
        }
        if (name == null) {
            throw new NullPointerException();
        }
        if (file.isInvalid()) {
            throw new FileNotFoundException("Invalid file path");
        }
        this.fd = new FileDescriptor();
        fd.attach(this);
        this.append = append;
        this.path = name;

        open(name, append);
    }
复制代码

可以看到这4个构造方法,究其本质,其实都是第四个构造方法。上面的三个构造方法不过是调用这第四个构造方法而已,name代表路径,append为true时表示写入的字节添加至文件的末尾,为false时表示新内容直接覆盖原内容。

有趣的是FileOutputStream的构造方法在输入路径构造时若文件不存在并不会报错,而是直接创建该文件,只有不存在且无法创建文件时才会报FileNotFoundException异常,所以通常来说,该流的构造方法也可以用于生成系统文件。

接着是FileOutputStream的一些常用API。

1.public void write(int b) throws IOException {
        write(b, append);
    }//这里调用的这个write是一个native方法,看不到源码,功能是写一个字节到输出流中

2.public void write(byte b[]) throws IOException {
        writeBytes(b, 0, b.length, append);
    }//此方法调用的是writebytes方法,同样也是一个native方法,功能是写入b.length个字    
      //节到输出流中。这里append就是构造方法中的那个append,默认为false

这里的writeBytes方法可以参照其父类OutputStream中的write方法来理解

复制代码
public void write(byte b[], int off, int len) throws IOException {
        if (b == null) {
            throw new NullPointerException();
        } else if ((off < 0) || (off > b.length) || (len < 0) ||
                   ((off + len) > b.length) || ((off + len) < 0)) {
            throw new IndexOutOfBoundsException();
        } else if (len == 0) {
            return;
        }
        for (int i = 0 ; i < len ; i++) {
            write(b[off + i]);
        }
    }
复制代码

可以看到也不过是使用循环多次调用write(int b)方法来实现的。同时该方法还能灵活控制想要输入的内容,off为偏移量,len代表要输出的长度。所以这几种write方法从效率上来说,也差不多。

无论输入流还是输出流,最后使用完了都必须要关闭,不然会一直占有系统资源,所以使用完毕请调用close方法将其释放

复制代码
public void close() throws IOException {
        synchronized (closeLock) {
            if (closed) {
                return;
            }
            closed = true;
        }

        if (channel != null) {
            channel.close();
        }

        fd.closeAll(new Closeable() {
            public void close() throws IOException {
               close0();
           }
        });
    }
复制代码

posted on   尤达  阅读(277)  评论(0编辑  收藏  举报

努力加载评论中...

导航

点击右上角即可分享
微信分享提示