一.FileOutputStream写出数据的两个小问题:
问题一:换行
假设在本地文件中要输出数据aweihaoshuai 666,在输出这个数据时要换行写出,如下图:
问题二:续写
假设在一个文本文件中已经存在数据aweihaoshuai,如果此时再次写入数据如diyishuai,若不想把原来的数据清空,而是想接着写即续写,如下图:(按照之前的写法使用write方法写出数据会把原有的数据清空再写出数据)
二.换行:
1.换行符:
将数据写入文本文件的过程中,要想实现换行,只需要写出一个换行符即可(注意:不同的操作系统中换行符是不同的)。
操作系统 | 换行符 |
---|---|
Windows操作系统 | \r\n,叫做"回车换行"(\r为回车,\n为换行) |
Linux操作系统 | \n,叫做"换行"(\n为换行) |
Mac操作系统(苹果操作系统) | \r,叫做"回车"(\r为回车) |
对于Windows操作系统,以下图为例:
Windows操作系统的换行符是\r\n,叫做"回车换行"(\r为回车,\n为换行),下面介绍该换行符的来源:在早期的cmd中存在一个规则,比如在上述图片的第25行打字,如果要在第26行开始打字,就需要两步操作,第一步首先要在当前行即第25行回车,以前的回车与现有的回车不一样,回车在早期的系统中是把光标放到这一行的开头即放到第25行的第一个字符o前,换行才是真正的把光标移动到下一行即第26行,所以要想实现把光标从第25行的最后一个字符w的后面移动到第27行,就需要先回车到第25行的第一个字符o前,再换行到第26行,Windows操作系统延续了这个操作。
细节:Windows操作系统中完整的换行符是\r\n,但Java对Windows操作系统的换行符\r\n进行了优化,就是写其中一个\r或者\n,Java也可以实现换行,因为Java在底层会进行补全->建议:不要省略,还是写全了比较好。
2.代码演示:
a.创建ByteStreamDemo4类与a.txt文本文件,如下图:
b.把kankelaoyezuishuai写出到文本文件a.txt,代码如下:
package com.itheima.mybytestream;
import java.io.FileOutputStream;
import java.io.IOException;
public class ByteStreamDemo4 {public static void main(String[] args) throws IOException {//1.创建对象FileOutputStream fos=new FileOutputStream("a.txt");
//2.写出数据/*需求:现在要把kankelaoyezuishuai写出到文本文件a.txt,其中需要用到write方法,* 但是在写的过程中该如何写呢?难道要一次一次地调用write方法传入要写出的字符的ASCII码吗,* 显然比较繁琐,因为要写入的数据可能会很长,因此要使用其他方法,解决方案如下: *///2.1.创建一个字符串->字符串就是要写出的内容String str="kankelaoyezuishuai";//2.2.str调用空参的getBytes方法:getBytes方法可以把str变成字节数组(字节数组存放的就是对应字符的ASCII码),有了字节数组就可以用write方法一起写到文件中byte[] arr = str.getBytes(); //getBytes方法的返回值是byte[]//2.3.写出数据fos.write(arr);
//3.释放资源fos.close();}
}
运行结果:
c.在a.txt文件原有数据的基础上,换行写出数据666
package com.itheima.mybytestream;
import java.io.FileOutputStream;
import java.io.IOException;
public class ByteStreamDemo4 {public static void main(String[] args) throws IOException {//1.创建对象FileOutputStream fos=new FileOutputStream("a.txt");
//2.写出数据String str1="kankelaoyezuishuai";byte[] bytes1 = str1.getBytes();fos.write(bytes1);String str2="666";byte[] bytes2 = str2.getBytes();fos.write(bytes2);
//3.释放资源fos.close();}
}
运行结果:
666并没有被换行处理,正确的写法需要在写出666之前写出一个换行符,修改方案如下:
package com.itheima.mybytestream;
import java.io.FileOutputStream;
import java.io.IOException;
public class ByteStreamDemo4 {public static void main(String[] args) throws IOException {//1.创建对象FileOutputStream fos=new FileOutputStream("a.txt");
//2.写出数据String str1="kankelaoyezuishuai";byte[] bytes1 = str1.getBytes();fos.write(bytes1);
/*再次写出一个换行符即可,注意:不同的操作系统中换行符是不同的*/String wrap="\r\n"; //定义一个字符串记录换行符(此时是Windows操作系统,换行符是\r\n)byte[] bytes2 = wrap.getBytes(); //获取wrap即换行符的ASCII码并放到数组中fos.write(bytes2); //此时就相当于做了一个换行操作
String str2="666";byte[] bytes3 = str2.getBytes();fos.write(bytes3);
//3.释放资源fos.close();}
}
运行结果:
三.续写:
1.续写开关:
在创建FileOutputStream对象时,FileOutputStream方法有一个包含两个形参的构造方法->第一个形参是文件,第二个形参是续写开关,如下图:
如下图,首先看FileOutputStream类里最简单的FileOutputStream构造方法:
如上图,该构造方法的形参是字符串name,这个构造方法的底层会把字符串name(name不为空时)表示的路径先变成File对象,第二个参数的默认值是false->所以就是把路径还有false传递给另外一个FileOutputStream构造方法,如下图:
上述图片的FileOutputStream构造方法才是真正的核心代码,该构造方法有两个形参,第一个形参是文件路径,第二个形参是续写开关,
对于第二个形参,如果传递false(默认传递false),意味着关闭续写,所以在创建对象时会把文件进行清空,清空了才保证不是续写的,
如果手动传递true,就表示打开续写,续写功能一旦打开,文件内容就不会被清空了,就会接着原来的数据写入数据。
总结:如果想要续写,打开续写开关即可,开关位置即创建FileOutputStream对象的第二个形参,第二个形参默认是false,表示关闭续写,此时创建对象会清空文件,第二个形参如果手动传递true,表示打开续写,此时创建对象不会清空文件。
2.代码演示:
未续写前:
如上图,此时第9行的FileOutputStream方法只传递了一个参数,意味着默认关闭续写,在a.txt文件中此时已经有两行数据了,现在要在这两行数据不被清空的基础上续写数据,解决方案如下:只需要打开续写即可->FileOutputStream方法的第二个形参手动传入true
package com.itheima.mybytestream;
import java.io.FileOutputStream;
import java.io.IOException;
public class ByteStreamDemo4 {public static void main(String[] args) throws IOException {//1.创建对象FileOutputStream fos=new FileOutputStream("a.txt",true); //第二个参数传入true,表示打开续写
//2.写出数据String str1="kankelaoyezuishuai";byte[] bytes1 = str1.getBytes();fos.write(bytes1);
/*再次写出一个换行符即可,注意:不同的操作系统中换行符是不同的*/String wrap="\r\n"; //定义一个字符串记录换行符(此时是Windows操作系统,换行符是\r\n)byte[] bytes2 = wrap.getBytes(); //获取wrap即换行符的ASCII码并放到数组中fos.write(bytes2); //此时就相当于做了一个换行操作
String str2="666";byte[] bytes3 = str2.getBytes();fos.write(bytes3);
//3.释放资源fos.close();}
}
运行结果: