前言
b站java课程学习笔记整理。
b站视频: 黑马程序员全套Java教程_Java基础入门视频教程,零基础小白自学Java必备教程
279.IO流概述和分类
IO是输入和输出。流时一种抽象的概念,指的是对数据传输的总称。
IO流就是用来处理设备间数据传输问题的(例如文件复制,上传和下载)。
把数据从硬盘上加载到内存上,这个动作就是对应的输入:读数据。
把内存中的内容输出到硬盘上,这个动作对应的是写数据。 一般来说,IO流分类是按照数据类型来分的。
分为字符流和字节流:
如果数据可以通过记事本打开,那么就可以使用字节流,如果打不开,那么就使用字符流。默认使用字节流。
280.字节流写数据
字节流抽象类:
InputSteam
: 这个抽象类是表示子节输入流的所有类的超类。
OutputStream
: 这个抽象类是表示字节输出流的所有类的超类。
子类名特点:子类名称都是以其父类名作为子类名的后缀。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package FileOutputStreamDemo;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;public class FileOutputStreamDemo { public static void main (String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("idea_test\\FileOutputStreamDemo.txt" ); fos.write(97 ); fos.write(57 ); fos.write(55 ); fos.close(); } }
总结:
创建字节输出流对象
写入
释放资源
281.字节流写数据的三种方式
方法名
说明
void write(int b)
将指定的子节写入此文件输出流。一次写入一个字节数据
void write(byte[] b)
将b.length子节从指定的字节数组写入此文件输出流,一次写一个字节数组数据
void write(byte[] b, int off, int len)
从off位置开始,写入长度为len的字节数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 package FileOutputStreamDemo;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.nio.charset.StandardCharsets;public class FileOutputStreamDemo { public static void main (String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("idea_test\\FileOutputStreamDemo.txt" ); File file = new File("idea_test\\FileOutputStreamDemo2.txt" ); FileOutputStream fos2 = new FileOutputStream(file); fos.write(97 ); fos.write(98 ); fos.write(99 ); fos.write(100 ); byte [] bytes = {97 ,98 ,99 ,100 }; String line = "abcdefg" ; byte [] byte2 = line.getBytes(StandardCharsets.UTF_8); fos2.write(byte2,1 ,3 ); fos.close(); fos2.close(); } }
282.字节流写数据的换行和追加写入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package FileOutputStreamDemo;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.nio.charset.StandardCharsets;public class FileOutputStreamDemo { public static void main (String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("idea_test\\FileOutputStreamDemo.txt" ); for (int i = 0 ; i < 10 ; i++){ fos.write("hello" .getBytes(StandardCharsets.UTF_8)); fos.write("\n" .getBytes(StandardCharsets.UTF_8)); } fos.close(); FileOutputStream fos2 = new FileOutputStream("idea_test\\FileOutputStreamDemo2.txt" ,true ); for (int i = 0 ; i < 10 ; i++){ fos2.write("hello" .getBytes(StandardCharsets.UTF_8)); fos2.write("\n" .getBytes(StandardCharsets.UTF_8)); } fos2.close(); } }
老师说windows的记事本是/r/n
,linux是/n
,mac是/r
,但是我windows也可以识别/n
……
283.字节流写数据加异常处理
finally
:在异常处理时会提供finally
块来执行所有清除操作,比如IO流中的释放资源。
特点: 被finally
控制的语句一定会执行,除非JVM退出。
标准格式:
1 2 3 4 5 6 7 try { 可能出现异常的代码 }catch (异常类名 变量名){ 异常的处理代码; }finally { 执行所有清除操作; }
示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 package FileOutputStreamDemo;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.nio.charset.StandardCharsets;public class FileOutputStreamDemo { public static void main (String[] args) { FileOutputStream fos = null ; try { fos = new FileOutputStream("idea_test\\FileOutputStreamDemo.txt" ); fos.write("hello" .getBytes(StandardCharsets.UTF_8)); fos.write("\n" .getBytes(StandardCharsets.UTF_8)); } catch (IOException e) { e.printStackTrace(); } finally { if (fos!= null ){ try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
284.字节流读数据
需求:把txt文件内容读取出来在控制台
和写数据流程一样,都是三步。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 package FileInputStreamDemo;import java.io.FileInputStream;import java.io.IOException;public class FileInputStreamDemo { public static void main (String[] args) throws IOException { FileInputStream fis = new FileInputStream("idea_test\\FileOutputStreamDemo.txt" ); int read = fis.read(); System.out.println((char )read); read = fis.read(); System.out.println((char )read); System.out.println("-------------------" ); int by; while ((by = fis.read())!=-1 ){ System.out.println((char )by); } fis.close(); } }
这个是可以读换行的。
285.字节流复制文本文件
需求:把rookie文件夹下的rookie.txt复制到theshy文件夹下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package 复制文本文件;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;public class CopyDemo { public static void main (String[] args) throws IOException { String source = "E:\\Javacode\\JavaSE Code\\rookie\\rookie.txt" ; String destination = "E:\\Javacode\\JavaSE Code\\theshy\\theshy.txt" ; FileInputStream fis = new FileInputStream(source); FileOutputStream fos = new FileOutputStream(destination); int by; while ((by=fis.read())!=-1 ){ fos.write(by); } fis.close(); fos.close(); } }
注意:用字节流时目标路径一定要指向文件,而不是文件夹。否则会抛出拒绝访问 的报错。
286.字节流读数据(一次读一个字节数组的数据)
现在有文本文档内容为:
如果执行如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 package 字节流读取字节数组数据;import java.io.FileInputStream;import java.io.IOException;public class FileOutputStreamRead { public static void main (String[]args) throws IOException { FileInputStream fis = new FileInputStream("idea_test\\FileOutputStreamDemo.txt" ); byte [] bys = new byte [5 ]; int len = fis.read(bys); System.out.println(len); System.out.println(new String(bys)); len = fis.read(bys); System.out.println(len); System.out.println(new String(bys)); len = fis.read(bys); System.out.println(len); System.out.println(new String(bys)); fis.close(); } }
返回的是一串很奇怪的东西:
原理:
文本文档的真实内容是
len是实际读取的fis的数据个数。
定义的数组长度为5。可以理解为 [$ $ $ $ $]
;
第一次读取,len = 5,即读取到了五个字符,得到的字符数组为[h e l l o]
;
第二次读取,len = 5, 即读取到了5个字符,得到的字符数组为[\n w o r l]
;
第三次读取, len = 3, 即读取到了3个字符,得到的字符数组为[d \n \n r l]
;
第三次只读到了d
和两个 \n
,只能替换之前[\n w o r l]
里面的前三个字符,就变成了这样。
改进:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 package 字节流读取字节数组数据;import java.io.FileInputStream;import java.io.IOException;public class FileOutputStreamRead { public static void main (String[]args) throws IOException { FileInputStream fis = new FileInputStream("idea_test\\FileOutputStreamDemo.txt" ); byte [] bys = new byte [5 ]; int len = fis.read(bys); System.out.println(len); System.out.println(new String(bys,0 ,len)); len = fis.read(bys); System.out.println(len); System.out.println(new String(bys,0 ,len)); len = fis.read(bys); System.out.println(len); System.out.println(new String(bys,0 ,len)); fis.close(); } }
使用String
方法,读取几个,转成几个字符串;
使用循环的终极改进:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package 字节流读取字节数组数据;import java.io.FileInputStream;import java.io.IOException;public class FileOutputStreamRead { public static void main (String[]args) throws IOException { FileInputStream fis = new FileInputStream("idea_test\\FileOutputStreamDemo.txt" ); byte [] bys = new byte [1024 ]; int len; while ((len = fis.read(bys))!=-1 ){ System.out.println(new String(bys, 0 , len)); } fis.close(); } }
0是offset
,也就是读取的偏移值。
byte
数组一般定义为1024或者1024的整数倍长度。
287.字节流复制图片
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 package 字节流复制图片;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;public class CopyImage { public static void main (String[] args) throws IOException { String source = "E:\\Javacode\\JavaSE Code\\rookie\\rookie.jpg" ; String destination = "E:\\Javacode\\JavaSE Code\\theshy\\rookie.jpg" ; FileInputStream fis = new FileInputStream(source); FileOutputStream fos = new FileOutputStream(destination); byte [] bys = new byte [1024 ]; int len; while ((len = fis.read(bys))!=-1 ){ fos.write(bys,0 ,len); } fis.close(); fos.close(); } }
所以文本文档用字节来复制,图片用字节数组来复制。
288.字节缓冲流
为字节流提供一个缓冲区,说人话就是”凑够一车人再发车“,可以有效地”省油“。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 package 字节缓冲流;import java.io.*;import java.nio.charset.StandardCharsets;public class Demo { public static void main (String[] args) throws IOException { FileOutputStream fos = new FileOutputStream("idea_test\\FileOutputStreamDemo.txt" ); BufferedOutputStream bos = new BufferedOutputStream(fos); bos.write("hello\r\n" .getBytes(StandardCharsets.UTF_8)); bos.write("world\r\n" .getBytes(StandardCharsets.UTF_8)); bos.close(); FileInputStream fis = new FileInputStream("idea_test\\FileOutputStreamDemo.txt" ); BufferedInputStream bis = new BufferedInputStream(fis); byte [] bys = new byte [1024 ]; int len; while ((len = bis.read(bys))!=-1 ){ System.out.println(new String(bys,0 ,len)); } } }
方法和之前的非缓冲区一样。这个的作用是可以更快的读取和写入。
289.字节流复制视频
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package 字节流复制视频;import java.io.*;public class CopyVideo { public static void main (String[] args) throws IOException { String source = "E:\\Javacode\\JavaSE Code\\rookie\\沙皇一推五.webm" ; String destination = "E:\\Javacode\\JavaSE Code\\theshy\\沙皇一推五.webm" ; BufferedInputStream bis = new BufferedInputStream(new FileInputStream(source)); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destination)); byte [] bys = new byte [1042 ]; int len; while ( (len = bis.read(bys))!=-1 ){ bos.write(bys,0 ,len); } bis.close(); bos.close(); } }
这种方式在复制大型文件(例如视频)时快很多。