黑马程序员—IO流学习小结(1)(Java)
----------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
一、 IO流概述
流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象。即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。IO包括输入和输出流。
二、 Java中的IO流
Java对数据的操作是通过流的方式进行的。Java用于操作流的类都在IO包中,按流向分为两种:输入流,输出流。按操作类型分为两种:字节流和字符流 。字节流可以操作任何数据,因为在计算机中任何数据都是以字节的形式存储的,字符流只能操作纯字符数据。
三、 Java的IO字节流编程基础
1. IO流常用父类
字节流的抽象父类: InputStream ,OutputStream
字符流的抽象父类: Reader , Writer
2. 字节输入流FileInputStream使用read()方法读取字节。read()方法读取的是一个字节,返回是int,而不是byte。这是因为字节输入流可以操作任意类型的文件,比如图片音频等,这些文件底层都是以二进制形式的存储的,如果每次读取都返回byte,有可能在读到中间的时候遇到111111111,而11111111是byte类型的-1,我们的程序是遇到-1就会停止不读了,后面的数据就读不到了,所以在读取的时候用int类型接收,如果11111111会在其前面补上24个0凑足4个字节,那么byte类型的-1就变成int类型的255了这样可以保证整个数据读完,而结束标记的-1就是int类型。
示例程序
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("xxx.txt"); //创建流对象
int b;
while((b = fis.read()) != -1) {
System.out.println(b);
}
fis.close();
}
3. 字节输出流FileOutputStream使用write()方法输出字节。FileOutputStream在创建对象的时候是如果没有这个文件会帮我创建出来,如果有这个文件就会先将文件清空所以用FileOutputStream实现数据的追加写入,需将append参数传入构造方法。
示例程序
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("yyy.txt",true);//如果想续写就在第二个参数传true
fos.write(97);
fos.write(98);
fos.close();
}
4. IO流拷贝文件方法
1)字节流一次读写一个字节复制文件,拷贝效率比较低
FileInputStream fis = new FileInputStream("xxx.mp3"); //创建输入流对象,关xxx.mp3
FileOutputStream fos = new FileOutputStream("copy.mp3");//创建输出流对象,关联copy.mp3
int b;
while((b = fis.read()) != -1) {
fos.write(b);
}
fis.close();
fos.close();
2)available()方法,一次读写,效率提高,但创建一个与文件一样大小的字节数组有可能会内存溢出
FileInputStream fis = new FileInputStream("xxx.mp3");/创建输入流对象,关联xxx.mp3
FileOutputStream fos = new FileOutputStream("copy.mp3");//创建输出流对象,关联copy.mp3
byte[] arr = new byte[fis.available()]; //创建与文件一样大小的字节数组
fis.read(arr); //将文件上的字节读取到内存中
fos.write(arr); //将字节数组中的字节数据写到文件上
fis.close();
fos.close();
3) 小数组拷贝,速度和安全性合适
FileInputStream fis = new FileInputStream("xxx.mp3");
FileOutputStream fos = new FileOutputStream("copy.mp3");
byte[] arr = new byte[1024 * 8];
int len;
while((len = fis.read(arr)) != -1) {//如果忘记加arr,返回的就不是读取的字节个数,而是字节的码表值
fos.write(arr,0,len);
}
fis.close();
fos.close();
5. BufferedInputStream内置了一个缓冲区(数组),从BufferedInputStream中读取一个字节时BufferedInputStream会一次性从文件中读取8192个, 存在缓冲区中, 返回给程序一个,程序再次读取时, 就不用找文件了, 直接从缓冲区中获取,直到缓冲区中所有的都被使用过, 才重新从文件中读取8192个。
6. BufferedOutputStream也内置了一个缓冲区(数组), 程序向流中写出字节时, 不会直接写到文件, 先写到缓冲区中, 直到缓冲区写满, BufferedOutputStream才会把缓冲区中的数据一次性写到文件里
缓冲流拷贝
FileInputStream fis = huancongnew FileInputStream("致青春.mp3");
//创建文件输入流对象,关联致青春.mp3
BufferedInputStream bis = new BufferedInputStream(fis);
//创建缓冲区对fis装饰
FileOutputStream fos = new FileOutputStream("copy.mp3");
//创建输出流对象,关联copy.mp3
BufferedOutputStream bos = new BufferedOutputStream(fos);
//创建缓冲区对fos装饰
int b;
while((b = bis.read()) != -1) {
bos.write(b);
}
bis.close(); //只关装饰后的对象即可
bos.close();
7. 小数组的读写和带Buffered的读取比较
定义小数组如果是8192个字节大小和Buffered比较的话定义小数组会略胜一筹,因为读和写操作的是同一个数组,而Buffered操作的是两个数组。
8. IO流的方法
flush()方法用来刷新缓冲区的,刷新后可以再次写出
close()方法用来关闭流释放资源的的,如果是带缓冲区的流对象的close()方法,不但会关闭流,还会再关闭流之前刷新缓冲区,关闭后不能再
后继
|
|