操作本地文件的字节输出流,可以把程序中的数据写到本地文件中。
// 1.创建对象
// 写出 -> 输出流 OutputStream
FileOutputStream fos = new FileOutputStream("a.txt");
// 2.写出数据
fos.write(98);
// 3.释放资源
fos.close();
创建字节输出流对象
参数是字符串表示的路径或者File对象都是可以的。如果文件不存在会创建一个新的文件,但是要保证父级路径是存在的。如果文件已经存在,则会清空文件。
写数据
write方法的参数是整数,但是实际上写到本地文件中的是整数ASCII上对应的字符。
一次写多个字节
// 1.创建对象
FileOutputStream fos = new FileOutputStream("a.txt");
// 2.写出数据
// 一次写一个字符数据
fos.write(97); // a
fos.write(98); // b
// ②、一次写入一个字符数组
byte[] bytes = { 97, 98, 99, 100, 101 };
fos.write(bytes);
//一次写一个字符数组的部分数据
// 参数一:数组 ;参数二:起始索引 ; 参数三:个数
fos.write(bytes, 1, 2); // b c
// 3.释放资源
fos.close();
续写和换行
如果想要续写,打开续写开关即可
打开位置,创建对象的第二个参数
默认false:表示关闭,此时创建对象会清空文件
手动true:表示打开续写,此时创建对象不会清空文件
new FileOutputStream("a.txt",true);
如果想要换行
String str3 = "\r\n";
byte[] bytes3 = str3.getBytes();
fos.write(bytes3);
// 1.创建对象
FileInputStream fis = new FileInputStream("a.txt");
// a.txt : abcde
// 2.读取数据
int b1 = fis.read();
System.out.println(b1); // 97
System.out.println((char) b1); // 强转: a
// 读取不到就会返回 -1
// 3.释放资源
fis.close();
一次读一个字节,读出来的是数据在ASCII上对应的数字。读取到文件末尾时,read方法返回 -1。
循环读取:
// 1.创建对象
FileInputStream fis = new FileInputStream("a.txt");
// a.txt : abcde
// 2.循环读取
//定义第三方变量
int b;
while ((b = fis.read()) != -1) {
System.out.println((char) b);
}
// 释放资源
fis.close();
一次可以读取一个字节数组,每次读取会尽可能把数组填满。
// 1.创建对象
FileInputStream fis = new FileInputStream("a.txt");
// 2.读取数据
byte[] bytes = new byte[2];
//一次读取多个字节数据:具体读多少,跟数组的长度有关
//返回值:本次读取到了多少个字节数据
int len = fis.read(bytes);
System.out.println(len);
String str= new String(bytes);
System.out.println(str);
//3.释放资源
fis.close();
案例:文件拷贝
// 1.创建对象
FileInputStream fis = new FileInputStream("movie.mp4");
FileOutputStream fos = new FileOutputStream("a\\copy.mp4");
// 2.拷贝
// 需要边读边写
int b;
while ((b = fis.read()) != -1) {
fos.write(b);
}
// 3.释放资源
// 规则: 先开的最后关闭
fos.close();
fis.close();
缺点:FileInputStream 一次读写一个字节,速度慢。可以利用FileInputStream使用 byte[] 数组一次遍历多个数据。
// 1.创建对象
FileInputStream fis = new FileInputStream("D:\\aaa\\movie.mp4");
FileOutputStream fos = new FileOutputStream("aaa\\copy.mp4");
// 2.拷贝
int len;
byte[] bytes = new byte[1024 * 1024 * 5]; // 5兆大小
while ((len = fis.read(bytes)) != -1) {
fos.write(bytes,0,len);
}
// 3.释放资源
fos.close();
fis.close();
输入流:一次读取一个字节,遇到中文时,一次读多个字节再写到文件中。
输出流:底层会把数据按照指定的编码方式,变成字节再写到文件中。
适用场景:文件中有中文。
// 1.创建对象并关联本地文件
FileReader fr = new FileReader("a.txt");
// 2.读取数据
// 细节1:字符流的底层就是字节流
// 默认一个字节一个字节的读取的
// 如果遇到中文,就会一次读取多个字节,GBK一次两个字节 UTF-8一次三个字节
// 细节2:读取之后,方法底层会进行解码并转换成十进制
// 十进制作为返回值 并作为字符集上的数字
// 细节3:想要看中文 可以对十进制进行强转
//空参read
int ch;
while ((ch = fr.read()) != -1) {
System.out.println((char) ch);
}
//带参read:读取数据、解码、强转三者合并,把强转之后字符放进数组
//空参的read + 强转类型转换
char[] chars = new char[2];
int len;
while((len = fr.read(chars)) != -1) {
//把数组中的数据变成字符串再进行打印
System.out.println(new String(chars,0,len));
}
// 3.释放资源
fr.close();
// 1.创建对象 续写开关打开
FileWriter fw = new FileWriter("a.txt", true);
// 2.写数据
fw.write(25105); // 写一个字符
fw.write("你好?"); // 写一个字符串 9个字节
char[] chars = { 'a', 'b', 'c', '我' };
fw.write(chars); // 写一个字符数组
// 3.释放资源
fw.close();
如果write方法的参数是整数,但是实际上写到本地文件中的是整数在字符集上对应的字符。
字符流原理分析
创建字符输入流对象底层:关联文件,并创建缓冲区(长度为8192的字节数组)
读取数据底层:判断缓冲区中是否有数据可以读取。缓冲区没有数据:就从文件中获取数据,装到缓冲区中,每次尽可能装满缓冲区;如果文件中也没用数据时,返回 -1。缓冲区有数据:就从缓冲区中读取。 空参的read方法:一次读取一个字节,遇到中文一次读多个字节,把字节解码并转成十进制返回。 有参的read方法:把读取字节、解码、强转三步合并,强转之后的字符放到数组当中。
缓冲流也称为高效流或者高级流。缓冲流自带缓冲区、可以提高基本字节流、字符流读写数据的性能。
原理:底层自带了长度为8192的缓冲区提高性能
首先基本流会读取数据,把读到的数据放到缓冲输入流的缓冲区,一次性会读8192个字节数据。下面代码中创建的中间变量b就是不断倒手两边的数据,将左边缓冲区的数据一个一个的放到右边缓冲区,当右边缓冲区填满了就会自动利用基本流向目的地写出数据。循环上述步骤,直到读到文件末尾返回-1。
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("aaa\\a.txt"));
int b;
while ((b = bis.read()) != -1){
bos.write(b);
}
bos.close();
bis.close();
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("aaa\\a.txt"));
byte[] bytes = new byte[8192];
int len;
while ((len = bis.read(bytes)) != -1){
bos.write(bytes,0,len);
}
bos.close();
bis.close();
原理:底层自带了长度为8192的缓冲区提高性能。字符流同样也带有8192字节大小的缓冲区,所有性能提高不大,主要学习字符缓冲流两个特有的方法:输入流的readLine()和输出流的newLine()。
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
BufferedWriter bw = new BufferedWriter(new FileWriter("aaa\\a.txt"));
bw.write("你好");
bw.newLine();
bw.close();
来源:B站黑马学习视频