Java从入门到放弃20—IO流的分类/字节流/字节流复制文本文件/高效的字节流
01 IO流的分类
按照数据流向划分分为输入流InPutStream和输出流OutPutStream。从硬盘读取到内存叫做输入,从内存写入到硬盘叫输出。
按照读写文件的类型可以分为字节流和字符流。字节流:可以读写任意数据类型的文件。字符流:只能读写文本文件。
注意事项:如果数据所在的文件通过windows自带的记事本打开并能读懂里面的内容,就用字符流。其他用字节流。
02 IO流的继承关系
字节流的顶层父类是InPutStream | OutPutStream (两者都是抽象类,只能通过子类进行实例化)
字节流常用子类SequenceInputstream,FileInputstream,ByteArrayInputstream,ObjectInputstream | FileOutputstream,ByteArrayOutputstream,ObjectOutputstream
字节流可以读写任意类型文件,命名规律是以stream结尾
字符流的顶层父类为Reader | Writer
常用子类 FileReader | FileWriter
由这四个父类派生出来的子类名称都是以其父类名作为子类名的后缀。
03 FileOutputstream
构造方法:FileOutputStream(File file)//创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
FileOutputStream(String name)//创建一个向具有指定 name 的文件中写入数据的输出文件流。
FileOutputStream(File file, boolean append)//创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
FileOutputStream(String name, boolean append)//创建一个向具有指定 name 的文件中写入数据的输出文件流。
参数2:代表是否追加写入,true 追加写入 false 不追加
FileOutputStream的三个write()方法
public void write(int b):写一个字节 超过一个字节 砍掉前面的字节
public void write(byte[] b):写一个字节数组
public void write(byte[] b,int off,int len):写一个字节数组的一部分
FileOutputStream写出数据如何实现数据的换行:
三个系统下的换行符如下:
windows \r\n
Linux \n
Mac \r
//FileOutputStream写出数据加入异常处理
//快捷键ctrl+alt+t
public class MyTest {
public static void main(String[] args) {
FileOutputStream out = null;
try {
out = new FileOutputStream("d.txt");
out.write(100);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//或是通过throws IOException抛出异常
//快捷键 alt+enter
注意事项:创建字节输出流对象了做了几件事情?
a:调用系统资源创建a.txt文件
b:创建了一个fos对象
c:把fos对象指向这个文件
为什么一定要close()?
a: 通知系统释放关于管理a.txt文件的资源
b: 让Io流对象变成垃圾,等待垃圾回收器对其回收
04 FileInputstream
构造方法:
FileInputStream(File file)//通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。
FileInputStream(String name)//通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。
//ctrl+alt+空格 提示文件名
常用方法:
read();一次读一个字节,返回的是int类型,如果读取不到返回-1
read(byte[]);把文件中的数据,读取到容器中,返回值是读取到的有效字节个数,超过有效字节个数的字节返回值为0
read(byte[] b, int off, int len);从此输入流中将最多 len 个字节的数据读入一个 byte 数组中。
注意事项:1.输入流所关联的文件必须存在,如果不存在,会报错
2.流使用完毕要释放资源
public class Test {
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream("e.txt");
//创建一个字节数组,充当容器
byte[] bytes = new byte[1024];
int len = in.read(bytes); //把文件中的数据,读取到容器中,返回值是,读取到的有效字节个数
String s = new String(bytes, 0, len);//把字节数组转成字符串
System.out.println(s);
in.close();
}
}
05 BufferedOutputStream写入数据
缓冲思想:
字节流一次读写一个数组的速度明显比一次读写一个字节的速度快很多,
这是加入了数组这样的缓冲区效果,java本身在设计的时候,
也考虑到了这样的设计思想(装饰设计模式后面讲解),所以提供了字节缓冲区流
BufferedOutputStream该类实现缓冲的输出流。通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必针对每次字节写入调用底层系统。
构造方法:
BufferedOutputStream(OutputStream out) 创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
BufferedOutputStream(OutputStream out, int size) 创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输出流。
06 BufferedInputStream读入数据
BufferedInputStream 为另一个输入流添加一些功能,即缓冲输入以及支持 mark 和 reset 方法的能力。在创建 BufferedInputStream 时,会创建一个内部缓冲区数组。在读取或跳过流中的字节时,可根据需要从包含的输入流再次填充该内部缓冲区,一次填充多个字节。mark 操作记录输入流中的某个点,reset 操作使得在从包含的输入流中获取新字节之前,再次读取自最后一次 mark 操作后读取的所有字节。
构造方法:
BufferedInputStream(InputStream in) 创建一个 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。
BufferedInputStream(InputStream in, int size) 创建具有指定缓冲区大小的 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。
07 案例:字节流复制文件
public class Test {
public static void main(String[] args) throws IOException {
FileInputStream fileInputStream = new FileInputStream("a.txt");
FileOutputStream fileOutputStream = new FileOutputStream("d.txt");
byte[] bytes = new byte[1024 * 8];
int length = 0;
while ((length=fileInputStream.read(bytes))!=-1){
fileOutputStream.write(bytes,0,length);
fileOutputStream.flush();
}
fileInputStream.close();
fileOutputStream.close();
}
}
//使用高效的字节流复制文件
public class Test {
public static void main(String[] args) throws IOException {
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("领悟1.mp3"));
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("领悟.mp3"));
byte[] bytes = new byte[1024 * 8];
int length =0;
while ((length=bufferedInputStream.read(bytes))!=-1){
bufferedOutputStream.write(bytes,0,length);
bufferedOutputStream.flush();
}
bufferedInputStream.close();
bufferedOutputStream.close();
}
}