前言
Github:/yihonglei/jdk-source-code-reading(java-io)
一 FileOutputStream 概述
FileOutputStream往文件中写入字节流,父类为OutputStream,所以可以将FileOutputStream赋值给OutputStream使用。
二 FileOutputStream 使用分析
FileOutputStream父类为OutputStream,其源码结构如下,
构造器
- public FileOutputStream(File file) throws FileNotFoundException;
- public FileOutputStream(File file, boolean append) throws FileNotFoundException;
- public FileOutputStream(FileDescriptor fdObj);
- public FileOutputStream(String name) throws FileNotFoundException;
- public FileOutputStream(String name, boolean append) throws FileNotFoundException;
方法
- public void write(int b) throws IOException;
- public void write(byte[] b) throws IOException;
- public void write(byte[] b, int off, int len) throws IOException;
- public void close() throws IOException;
- public void flush() throws IOException;
- protected void finalize() throws IOException;
- public FileChannel getChannel();
- public final FileDescriptor getFD() throws IOException;
以下通过实例分析重要方法。
write(int b)
FileOutputStream的write(int b)将包含了待写入字节的int变量作为参数写入到当前文件输出流中。
package ;
import ;
import ;
import ;
import ;
/**
* write(int b):把单个字节写入到输出流中。
*
* @author yihonglei
*/
public class FileOutputStream1 {
public static void main(String[] args) {
// 指定构造文件(如果指定文件不存在,会创建对应文件)
File file = new File("C:\\mycode\\");
// 根据文件创建文件输出流
try (OutputStream os = new FileOutputStream(file)) {
// 创建要写入输出流的数据
String str = "abcdefg";
byte[] data = ();
// 通过write(int b)将数据写入到输出流,操作系统设备根据输出流处理到终端文件
for (byte b : data) {
(b);
}
} catch (IOException e) {
();
}
}
}
write(byte[] b)
FileOutputStream的write(byte[] b)将长度的字节数组写入到文件输出流中。
package ;
import ;
import ;
import ;
import ;
/**
* write(byte b[]):将字节数组中全部数据写入到输出流中。
*
* @author yihonglei
*/
public class FileOutputStream2 {
public static void main(String[] args) {
// 指定构造文件(如果指定文件不存在,会创建对应文件)
File file = new File("C:\\mycode\\");
// 根据文件创建文件输出流
try (OutputStream os = new FileOutputStream(file)) {
// 创建要写入输出流的数据
String str = "abcdefg";
byte[] data = ();
// 将数据字节数组一次行写入到FileOutputStream(文件输出流)中
(data);
} catch (IOException e) {
();
}
}
}
write(byte[] b, int off, int len)
FileOutputStream 的 write(byte[] b, int off, int len) 将字节数组 b 从 off 位置到 len 位置的字节写入到文件输出流中。
package ;
import ;
import ;
import ;
import ;
/**
* write(byte b[], int off, int len):把字节数据中从offset位置开始,length个字节的数据写入到输出流。
*
* @author yihonglei
*/
public class FileOutputStream3 {
public static void main(String[] args) {
// 指定构造文件(如果指定文件不存在,会创建对应文件)
File file = new File("C:\\mycode\\");
// 根据文件创建文件输出流
try (OutputStream os = new FileOutputStream(file)) {
// 创建要写入输出流的数据
String str = "abcdefg";
byte[] data = ();
// 从offset位置开始,length个字节的数据写入到输出流
(data, 1, );
} catch (IOException e) {
();
}
}
}
flush()
当你往FileOutputStream里写数据的时候,这些数据有可能会缓存在内存中。
在之后的某个时间,比如,每次都只有X份数据可写,或者FileOutputStream关闭的时候,才会真正地写入磁盘。
当FileOutputStream没被关闭,而你又想确保写入到FileOutputStream中的数据写入到磁盘中,可以调用flush()方法,
该方法可以保证所有写入到FileOutputStream的数据全部写入到磁盘中。
三 文件内容的覆盖(Override)和追加(Appending)
当我们创建了一个指向已存在文件的FileOutputStream,你可以选择覆盖整个文件,
或者在文件末尾追加内容。通过使用不同的构造函数可以实现不同的目的。
其中一个构造函数取文件名作为参数,会覆盖任何此文件名指向的文件。
OutputStream output = new FileOutputStream("C:\\mycode\\");
另外一个构造函数取2个参数:文件名和一个布尔值,布尔值表明你是否需要覆盖文件,
如果为true,表示将文件内容追加到已存在文件,否则,覆盖掉已存在文件。
构造函数源码:
public FileOutputStream(File file, boolean append) throws FileNotFoundException;
构造函数例子:
OutputStream output = new FileOutputStream("C:\\mycode\\", true); // 内容追加到文件
OutputStream output = new FileOutputStream("C:\\mycode\\", false); // 不追加,而是覆盖掉文件
追加到文件
package ;
import ;
import ;
import ;
import ;
/**
* 在finally语句块中关闭流,此方案虽然能关闭流,但是并不完美。
*
* @author yihonglei
*/
public class FileOutputStream4 {
public static void main(String[] args) {
// 指定构建文件
File file = new File("C:\\mycode\\");
OutputStream os = null;
try {
// 创建文件输出流
os = new FileOutputStream(file);
// 创建要写入输出流的数据
String str = "abcdefg";
byte[] data = ();
// 将数据字节数组一次行写入到FileOutputStream(文件输出流)中
(data);
} catch (IOException e) {
();
} finally {
try {
// 关闭输出流
();
} catch (IOException e) {
();
}
}
}
}
覆盖掉文件
package ;
import ;
import ;
import ;
import ;
/**
* FileOutputStream(File file, boolean append)的append设置为false,覆盖掉文件。
* 如果为false,与FileOutputStream(File)构造器一致。
*
* @author yihonglei
*/
public class FileOutputStream5 {
public static void main(String[] args) {
// 指定构建源文件
File file = new File("C:\\mycode\\");
// 根据文件创建不可以追加文件内容的文件输出流
try (OutputStream os = new FileOutputStream(file, false)) {
// 要写入的数据,转化为字节数组
String str = "abcdefg";
byte[] bytes = ();
// 将字节数组写入到输出流,如果多执行几次,会发现文件内容并没有改变,每次都被覆盖掉了
(bytes);
} catch (IOException e) {
();
}
}
}