字节流的基本流:FileOutputStream
- 写入和读出的正确辨识
- 为什么不能用来写入中文
- FileOutStream写数据的3种方式
- 解决续写和换行问题
我们的File类只能操作文件本身,而对于文件中的数据而无法操作,我们的IO流以此存在,可以将程序(内存)中的数据写入到文件中,也可以把文件中的数据读出到程序(内存)中
写入和读出的正确辨识
我们的文件输出流FileOutStream之所以这样命名,我们是以程序(内存)为参照的,流的方向从程序到文件,即输出到文件,所有称为输出流,所有输出流用于从内存中写入数据到文件。而流的方向从文件到内存,即为输入流,用于读出数据。
为什么不能用来写入中文
因为字节流在读取汉字的时候没能读完整个汉字。我们的字节流每次只能读取1个字节,而按照GBK编码汉字占用2个字节,用Unicode编码汉字占用3个字节。字节流每次读取一个字节就进行编码和解码操作,肯定会导致出现乱码的情况
举例说明
由于FileOutputStream无法写入汉字,我们使用FileInputStream读出汉字进行验证
- 运行结果
FileOutputStream写数据的3种方式
FileOutputStream是字节流的基本流,可以把程序中的数据写到本地文件中
- 书写数据的基本步骤
package com;
import java.io.*;
public class ByteStreamDemo1 {
public static void main(String[] args) throws IOException {
/*
演示:字节输出流FileOutputStream :由程序中写出文字到文件中
需求:写出一段文字到本地文件中(暂时不写中文)
在相对路径下的aa.txt文件中写入数据
实现步骤:
1.创建对象
2.写出数据
3.释放资源
*/
//1.创建流的对象
//创建该流需要抛出异常 为了防止路径不存在
FileOutputStream fos = new FileOutputStream("small\\www.txt");//FileOutputStream用于操作本地文件
fos.write(97);//写入数据
fos.close();//关闭资源
}
}
写入数据的细节
package com;
import java.io.*;
public class ByteStreamDemo1 {
public static void main(String[] args) throws IOException {
/*
演示:字节输出流FileOutputStream :由程序中写出文字到文件中
需求:写出一段文字到本地文件中(暂时不写中文)
在相对路径下的aa.txt文件中写入数据
实现步骤:
1.创建对象
细节1:参数是字符串表示的路径或者是File对象都是可以的(如果写的是字符串内部也会new对象)
细节2:如果该路径下的文件不存在会常见一个新的文件,但是要保证父级路径是存在的
细节3:如果文件已经存在,则会清空文件
2.写出数据
细节:write方法的参数是整数,但实际上是写到本地文件中的是整数在ASCII上对应的字符
3.释放资源
每次使用完流之后都要释放资源
如果没有释放资源,则该文件一直被java占用,在后台中则无法删除该文件
*/
//1.创建流的对象
//创建该流需要抛出异常 为了防止路径不存在
FileOutputStream fos = new FileOutputStream("small\\www.txt");//FileOutputStream用于操作本地文件
fos.write(97);//写入数据
//fos.close();//关闭资源
while (true) ;
}
}
写入数据的3种方式
在写入数据时,一次写入一个字节的话,如果数据比较多就太麻烦了,以此java推出了以此写入一个字节数组
package com;
import java.io.*;
public class ByteStreamDemo1 {
public static void main(String[] args) throws IOException {
//FileOutputStream的三种写出方式
/*
void write(int b) 一次写一个字节数据
void write(byte[]b) 一次写一个字节数组数据
void write(byte[]b,int off,int len) 一次写一个字节数组的部分数据
参数1:数组名
参数2:起始索引
参数3:个数
*/
//1.创建对象
FileOutputStream fos = new FileOutputStream("small\\www.txt");//创建代码和文件之间的流通道
//2.写入数据
/* fos.write(97);
fos.write(99);*/
byte[]bytes = {97,98,99,100};
//fos.write(bytes);//全部读入字节数组
fos.write(bytes,1,3);
fos.close();//释放资源
}
}
解决续写和换行问题
换行问题
其实可以通过写入一个换行符来表示在文件中换行,在windows的操作系统中,换行包含回车\r和换行\n两部分
package com;
import java.io.*;
public class ByteStreamDemo1 {
public static void main(String[] args) throws IOException {
/*
换行写:
在两行之间写出换行符即可
windows \r\n
Linux \n
Mac \r
细节:
在java中,对Windows中的换行符进行了优化
完整的换行符是\r\n,但我们只需要写\r或者\n
java会在其底层进行补全
建议:完整书写
*/
//1.创建流的对象
FileOutputStream fos = new FileOutputStream("small\\www.txt");
//2.书写数据(现在已经可以书写字母和数字)
//2.1先用字符串表示要数据的数据
String str = "hello world";
//将数据转化为字节数组
final byte[] bytes = str.getBytes();//将数据转化为字节数组
fos.write(bytes);//将字节数组里面的内容写入到文件中
//2.2 进行换行
//将换行符用字符串表示
String str1 = "\r\n";
final byte[] bytes1 = str1.getBytes();
fos.write(bytes1);//对人换行符
//2.3 写入第二行的数据
String str3 = "swtYYDS";
final byte[] bytes2 = str3.getBytes();
fos.write(bytes2);
//3.关闭资源
fos.close();
}
}
续写问题
FileOutputStream有一个注意事项就是在每次进行写入之前都会对文件中的内容进行情况操作,即无法进行续写。其实在我们的FileOutStream的构造方法中专门来这样一个参数来决定是否进行续写
上面的构造方法的参数boolean append表示的是否进行续写,在我们没有填写这个参数的时候,默认是false即不开启续写,当我们要开启续写,将其手动改成true即可
package com;
import java.io.*;
public class ByteStreamDemo1 {
public static void main(String[] args) throws IOException {
/*
换行写:
在两行之间写出换行符即可
windows \r\n
Linux \n
Mac \r
细节:
在java中,对Windows中的换行符进行了优化
完整的换行符是\r\n,但我们只需要写\r或者\n
java会在其底层进行补全
建议:完整书写
*/
/*
续写:该构造方法传递的开关理解为是否开启续写
如果想要续写,打开开关即可
开关为止,构造方法的第二个参数
开关默认为false:表示关闭续写,此时创建对象将会清空文件
手动传递true,表示打开续写,此时创建对象不会清空文件
*/
//1.创建流的对象
FileOutputStream fos = new FileOutputStream("small\\www.txt",true);
//2.书写数据(现在已经可以书写字母和数字)
//2.1先用字符串表示要数据的数据
String str = "hello world";
//将数据转化为字节数组
final byte[] bytes = str.getBytes();//将数据转化为字节数组
fos.write(bytes);//将字节数组里面的内容写入到文件中
//2.2 进行换行
//将换行符用字符串表示
String str1 = "\r\n";
final byte[] bytes1 = str1.getBytes();
fos.write(bytes1);//对人换行符
//2.3 写入第二行的数据
String str3 = "swtYYDS";
final byte[] bytes2 = str3.getBytes();
fos.write(bytes2);
//3.关闭资源
fos.close();
}
}