简介
FileOutputStream流是指文件字节输出流,专用于输出原始字节流,如图像数据等,其继承OutputStream类,拥有输出流的基本特性
源码分析
package java.io;import java.nio.channels.FileChannel;import sun.nio.ch.FileChannelImpl;/*** @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*/publicclass FileOutputStream extends OutputStream{/*** 文件描述符,打开文件句柄*/private final FileDescriptor fd;/*** 是否在文件末尾追加*/private final boolean append;/*** 文件通道*/private FileChannel channel;/*** 文件路径*/private final String path;// 锁机制对象,用于调用close方法时的同步锁对象private final Object closeLock = new Object();// 当前输出流是否已关闭private volatile boolean closed = false;/*** 构造方法,传入表示文件路径的字符串,并构造File对象,调用别的构造方法* @param name the system-dependent filename* @see java.lang.SecurityManager#checkWrite(java.lang.String)*/public FileOutputStream(String name) throws FileNotFoundException {this(name != null ? new File(name) : null, false);}/*** 传入表示文件路径的字符串和是否追加标识,将字符串初始化为File对象,并调用别的构造方法* @param name the system-dependent file name* @param append if <code>true</code>, then bytes will be written* to the end of the file rather than the beginning* @see java.lang.SecurityManager#checkWrite(java.lang.String)* @since JDK1.1*/public FileOutputStream(String name, boolean append)throws FileNotFoundException{this(name != null ? new File(name) : null, append);}/*** 传入File对象,调用别的构造方法* @param file the file to be opened for writing.* @see java.io.File#getPath()* @see java.lang.SecurityException* @see java.lang.SecurityManager#checkWrite(java.lang.String)*/public FileOutputStream(File file) throws FileNotFoundException {this(file, false);}/*** 传入文件对象和是否追加标识,构造输出流对象* @param file the file to be opened for writing.* @param append if <code>true</code>, then bytes will be written* to the end of the file rather than the beginning* @see java.io.File#getPath()* @see java.lang.SecurityException* @see java.lang.SecurityManager#checkWrite(java.lang.String)* @since 1.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);}/*** 创建一个向指定文件描述符处写入数据的输出文件流* @param fdObj the file descriptor to be opened for writing* @see java.lang.SecurityManager#checkWrite(java.io.FileDescriptor)*/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方法,开启输出流* @param name name of file to be opened* @param append whether the file is to be opened in append mode*/private native void open0(String name, boolean append)throws FileNotFoundException;// wrap native call to allow instrumentation/*** 打开文件,并标识追加还是覆盖* @param name name of file to be opened* @param append whether the file is to be opened in append mode*/private void open(String name, boolean append)throws FileNotFoundException {open0(name, append);}/*** native方法,向文件输出一个字节内容,并指定是追加到原有内容后面还是覆盖原有内容* @param b the byte to be written. 需要输出的字节* @param append {@code true} if the write operation first* advances the position to the end of file 是否追加*/private native void write(int b, boolean append) throws IOException;/*** 向文件输出一个字节内容* @param b the byte to be written.* @exception IOException if an I/O error occurs.*/public void write(int b) throws IOException {write(b, append);}/*** native方法,向文件输出byte数组从off下标之后的len个字节,并指定是否追加* @param b the data to be written 字节数组* @param off the start offset in the data 输出内容在字节数组的起始位置* @param len the number of bytes that are written 输出多少个字节* @param append {@code true} to first advance the position to the* end of file 是否追加*/private native void writeBytes(byte b[], int off, int len, boolean append)throws IOException;/*** 向文件输出字节数组的全部内容* @param b the data.*/public void write(byte b[]) throws IOException {writeBytes(b, 0, b.length, append);}/*** 向文件输出字节数组从off下标开始的len个字节* @param b the data.* @param off the start offset in the data.* @param len the number of bytes to write.*/public void write(byte b[], int off, int len) throws IOException {writeBytes(b, off, len, append);}/*** 关闭输出流* @revised 1.4* @spec JSR-51*/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();}});}/*** 获取文件描述符(文件句柄)* @return the <code>FileDescriptor</code> object that represents* the connection to the file in the file system being used* by this <code>FileOutputStream</code> object.* @see java.io.FileDescriptor*/public final FileDescriptor getFD() throws IOException {if (fd != null) {return fd;}throw new IOException();}/*** 获取通道* @return the file channel associated with this file output stream* @since 1.4* @spec JSR-51*/public FileChannel getChannel() {synchronized (this) {if (channel == null) {channel = FileChannelImpl.open(fd, path, false, true, append, this);}return channel;}}/*** 释放资源,同时刷新缓存,强制将缓存中的内容写入文件* @see java.io.FileInputStream#close()*/protected void finalize() throws IOException {if (fd != null) {if (fd == FileDescriptor.out || fd == FileDescriptor.err) {flush();} else {/**/close();}}}private native void close0() throws IOException;private static native void initIDs();static {initIDs();}}
简单使用
package com.java.io;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @description
* @date: 2021-01-18 22:01
*/
public class FileOutputStreamExample {
public static void main(String[] args) {
commonExample();
}
public static void commonExample() {
String filePath = "D:\\IDEAWorkSpace\\JAVALearn\\io\\src\\resource\\fileOut.txt";
FileOutputStream fileOutputStream = null;
try {
fileOutputStream = new FileOutputStream(filePath);
fileOutputStream.write("Test Message".getBytes());
// 默认是追加到Test Message后面
fileOutputStream.write(" Test Text".getBytes());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(null != fileOutputStream){
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
输出结果:
