OutputStream
有很多子类,我们从最简单的一个子类开始。
java.io.FileOutputStream
类是文件输出流,用于将数据写出到文件。
1. 构造方法
public FileOutputStream(File file)
:创建文件输出流以写入由指定的 File对象表示的文件。public FileOutputStream(String name)
: 创建文件输出流以指定的名称写入文件。
参数
写入数据的目的地
String name
:是一个文件的路径File file
:是一个文件
构造方法的作用
- 创建一个``FileOutputStream`对象
- 会根据构造方法中传递的文件/文件路径,创建一个空的文件
- 会把
FileOutputStream
对象指向创建好的文件
写入数据的原理(内存–>硬盘)
java程序–>JVM(java虚拟机)–>OS(操作系统)–>OS调用写数据的方法–>把数据写入到文件中
2. 使用步骤 【重点】
- 创建一个FileOutputStream对象,构造方法中传递写入数据的目的地
- 调用FileOutputStream对象中的方法write,把数据写入到文件中
- 释放资源(流使用会占用一定的内存,使用完毕要把内存清空,提供程序的效率)
注意
当你创建一个流对象时,必须传入一个文件路径。
- 该路径下,如果没有这个文件,会创建该文件。
- 如果有这个文件,会清空这个文件的数据。
构造举例,代码如下:
public class FileOutputStreamConstructor throws IOException {
public static void main(String[] args) {
// 使用File对象创建流对象
File file = new File("a.txt");
FileOutputStream fos = new FileOutputStream(file);
// 使用文件名称创建流对象
FileOutputStream fos = new FileOutputStream("b.txt");
}
}
3. 常用方法
1. 写出字节数据
write(int b)
方法,每次可以写出一个字节数据
注意
- 虽然参数为int类型四个字节,但是只会保留一个字节的信息写出。
- 流操作完毕后,必须调用close方法释放系统资源
代码演示:
public class FOSWrite {
public static void main(String[] args) throws IOException {
// 使用文件名称创建流对象
FileOutputStream fos = new FileOutputStream("fos.txt");
// 写出数据 100
fos.write(97); // 写出第1个字节
fos.write(98); // 写出第2个字节
fos.write(99); // 写出第3个字节
// 关闭资源
fos.close();
}
}
结果:
abc
2. 写出字节数组
public void write(byte[] b)
:将`` b.length`字节从指定的字节数组写入此输出流。
一次写多个字节
- 如果写的第一个字节是正数(0-127),那么显示的时候会查询ASCII表
- 如果写的第一个字节是负数,那第一个字节会和第二个字节,两个字节组成一个中文显示,查询系统默认码表(GBK)
代码演示:
public class FOSWrite {
public static void main(String[] args) throws IOException {
// 使用文件名称创建流对象
FileOutputStream fos = new FileOutputStream("fos.txt");
// 字符串转换为字节数组
byte[] b = "你好".getBytes();
// 写出字节数组数据
fos.write(b);
byte[] bytes1 = {-65,-66,-67,68,69}; // 烤紻E
fos.write(bytes1);
// 关闭资源
fos.close();
}
}
3. 写出指定长度字节数组和写入字符的方法
-
public void write(byte[] b, int off, int len)
:把字节数组的一部分写入到文件中int off
:数组的开始索引int len
:写几个字节 -
byte[] getBytes()
:(使用String类中的方法)把字符串转换为字节数组。
代码演示:
public class FOSWrite {
public static void main(String[] args) throws IOException {
// 使用文件名称创建流对象
FileOutputStream fos = new FileOutputStream("fos.txt");
// 字符串转换为字节数组
byte[] b = "abcde".getBytes();
// 写出从索引2开始,2个字节。索引2是c,两个字节,也就是cd。
fos.write(b,2,2);
byte[] bytes2 = "你好".getBytes();
/*
System.out.println(bytes2); // [B@50cbc42f
System.out.println(Arrays.toString(bytes2));
// [-28, -67, -96, -27, -91, -67] UTF-8:三个字节是一个中文
*/
fos.write(bytes2);
//释放资源
fos.close();
}
}
结果:
cd烤紻E
4. 数据追加续写
经过以上的演示,每次程序运行,创建输出流对象,都会清空目标文件中的数据。如何保留目标文件中数据,还能继续添加新数据呢?
构造方法
public FileOutputStream(File file, boolean append)
: 创建文件输出流以写入由指定的 File对象表示的文件。public FileOutputStream(String name, boolean append)
: 创建文件输出流以指定的名称写入文件。
这两个构造方法,参数中都需要传入一个boolean类型的值,true
表示追加数据,false
表示清空原有数据。这样创建的输出流对象,就可以指定是否追加续写了
参数
String name,File file
:写入数据的目的地boolean append
:追加写开关true
:创建对象不会覆盖源文件,继续在文件的末尾追加写数据false
:创建一个新文件,覆盖源文件
代码演示:
public class FOSWrite {
public static void main(String[] args) throws IOException {
// 使用文件名称创建流对象
FileOutputStream fos = new FileOutputStream("fos.txt",true);
// 字符串转换为字节数组
byte[] b = "abcde".getBytes();
// 写出从索引2开始,2个字节。索引2是c,两个字节,也就是cd。
fos.write(b);
// 关闭资源
fos.close();
}
}
结果:
文件操作前:cd
文件操作后:cdabcde
5. 写出换行
回车符\r
和换行符\n
- 回车符:回到一行的开头(return)。
- 换行符:下一行(newline)。
系统中的换行
- Windows系统里,每行结尾是
回车+换行
,即\r\n
; - Unix系统里,每行结尾只有
换行
,即\n
; - Mac系统里,每行结尾是
回车
,即\r
。从 Mac OS X开始与Linux统一。
代码演示:
public class FOSWrite {
public static void main(String[] args) throws IOException {
// 使用文件名称创建流对象
FileOutputStream fos = new FileOutputStream("fos.txt");
// 定义字节数组
byte[] words = {97,98,99,100,101};
// 遍历数组
for (int i = 0; i < words.length; i++) {
// 写出一个字节
fos.write(words[i]);
// 写出一个换行, 换行符号转成数组写出
fos.write("\r\n".getBytes());
}
// 关闭资源
fos.close();
}
}
结果:
a
b
c
d
e