该类继承自OutputStream
引入了如下包:
import java.nio.channels.FileChannel; import sun.nio.ch.FileChannelImpl;
类头注释如下:
/** * A file output stream is an output stream for writing data to a * <code>File</code> or to a <code>FileDescriptor</code>. Whether or not * a file is available or may be created depends upon the underlying * platform. Some platforms, in particular, allow a file to be opened * for writing by only one <tt>FileOutputStream</tt> (or other * file-writing object) at a time. In such situations the constructors in * this class will fail if the file involved is already open. * * <p><code>FileOutputStream</code> is meant for writing streams of raw bytes * such as image data. For writing streams of characters, consider using * <code>FileWriter</code>. * * @author Arthur van Hoff * @see java.io.File * @see java.io.FileDescriptor * @see java.io.FileInputStream * @see java.nio.file.Files#newOutputStream * @since JDK1.0 */
大意如下:
文件输出流用于向FIle类或者FileDescriptor类中写入数据
文件是否可用或者是否能被创建取决于底层平台
尤其一些平台,在同一时刻一个文件只允许被一个FileOutputStream流(或者其他文件写入类)写入
在这种情况下,如果指定文件已经被打开,该类的构造方法将失败
FileOutputStream用来写入未被加工过的字节流,如图像数据
如果要写入字符流,推荐使用FileWriter
该类含有如下的成员变量:
文件描述符(系统给的
private final FileDescriptor fd;
判定文件是否为追加打开的(为追加打开则为true
private final boolean append;
文件管道
private FileChannel channel;
文件路径(用文件描述符创建则为空
private final String path;
关闭锁
private final Object closeLock = new Object();
流关闭标志
private volatile boolean closed = false;
含有如下的方法:
构造方法:传入文件路径,默认不关联
public FileOutputStream(String name) throws FileNotFoundException { this(name != null ? new File(name) : null, false); }
构造方法:传入文件路径和关联打开标示
public FileOutputStream(String name, boolean append) throws FileNotFoundException { this(name != null ? new File(name) : null, append); }
构造方法:默认不关联,传入File对象
public FileOutputStream(File file) throws FileNotFoundException { this(file, false); }
核心构造方法:传入File对象和关联标示
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);//打开文件 }
构造函数:创建一个向指定文件描述符处写入数据的输出文件流,该文件描述符表示一个到文件系统中的某个实际文件的现有连接。
public FileOutputStream(FileDescriptor fdObj) { SecurityManager security = System.getSecurityManager(); if (fdObj == null) { throw new NullPointerException(); } if (security != null) { security.checkWrite(fdObj);//检查该对象能否写入 } this.fd = fdObj; this.append = false; this.path = null; fd.attach(this); }
native开启函数(应该是调用底层获得文件的打开和写入权限
private native void open0(String name, boolean append) throws FileNotFoundException;
native写入函数(文件关联性在构造时就设定好了
private native void write(int b, boolean append) throws IOException;
写入特定字节
public void write(int b) throws IOException { write(b, append); }
native写入字节数组
private native void writeBytes(byte b[], int off, int len, boolean append) throws IOException;
将传入的数组全部写入
public void write(byte b[]) throws IOException { writeBytes(b, 0, b.length, append); }
将传入数组的特定部分写入
public void write(byte b[], int off, int len) throws IOException { writeBytes(b, off, len, append); }
关闭输出流并释放该流所占用的系统资源(如果关联了FileChannel也一并关闭)
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(); } }); }
获得文件描述符(存在
public final FileDescriptor getFD() throws IOException { if (fd != null) { return fd; } throw new IOException(); }
返回与该文件输出流连接的FileChannel对象
public FileChannel getChannel() { synchronized (this) { if (channel == null) { channel = FileChannelImpl.open(fd, path, false, true, append, this); } return channel; } }
关闭所有与该文件的链接并确定close方法被调用
protected void finalize() throws IOException { if (fd != null) {//文件描述符还存在(未被注销 if (fd == FileDescriptor.out || fd == FileDescriptor.err) {//如果是标准输出和错误流,则清空缓冲区 flush(); } else { /* if fd is shared, the references in FileDescriptor * will ensure that finalizer is only called when * safe to do so. All references using the fd have * become unreachable. We can call close() */ close(); } } }
关闭并注销该对象
private native void close0() throws IOException;
初始化JNI
private static native void initIDs(); static { initIDs(); }
该类也是常用类型,希望大家可以尽量熟悉该类用法和内容