IO 概述
概述:
在使用IO流对数据进行传输的时候使用的以字节为单位操作数据的流就叫做字节流
分类:
字节流和流向划分进行结合分为字节输入流和字节输出流
InputStream【字节输入流】
概述:
他是字节输入流的顶层父类,他是一个抽象类,定义所有字节输入流的共性功能常用功能:
int read():
一次读取一个字节数据到内存
int read(byte[] bytes):
使用字节数组去读取多个字节的内容到内存
int available():
返回未读取的字节的个数
close():
关闭流【所有的io流都有的一个方法】
> 注意:
InputStream这个类是一个抽象类,他不能创建对象他的功能自己使用不了,只能去找他的子 类来调用,根据设备的不同,对应的子类也不同,介绍最常用的子类FileInputSTream[文本字节输入流]
FileInputStream
概述:
他是InputStream的子类,他只负责完成内存和文本文件之间数据的输入交互的操作。输入功能都是InputStream的功能。
构造方法:
FileInputStream(File file):
创建一个可以读取指定File对象对应的文件的字节输入流对象
FileInputStream(String path):
创建一个可以读取指定路径对应的文件的字节输入流对象
注意事项:
1、同一个字节输入流对象每读取一个字节,光标向后移动一位,每次读取以光标所在位置开始读取
2、所有的字节数读取完毕继续读取的时候得到的是-1.代码示例:
package com.ujiuye.demo; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; public class FileInputStreamDemo { public static void main(String[] args) { // 想要使用字节输入流读取 a.txt中的数据 // 创建字节输入流的对象 FileInputStream fis = null; try { fis = new FileInputStream("a\\a.txt"); int i = fis.read();// 返回值就是读到的元素 System.out.println(i);// 97 int i1 = fis.read();// 返回值就是读到的元素 System.out.println(i1);// 100 byte[] bs = new byte[5]; int len = fis.read(bs);// 返回值是每次读取的有效字节个数 System.out.println(len);// 5 // 获取 字节数组读到的内容 // for (byte b : bs) { // System.out.print(b + " "); // } //System.out.println(); System.out.println(new String(bs,0,len)); int len1 = fis.read(bs);// 返回值是每次读取的有效字节个数 System.out.println(len1);// 3 // 获取 字节数组读到的内容 // for (byte b : bs) { // System.out.print(b + " "); // } System.out.println(new String(bs,0,len1)); System.out.println(fis.available());// 0 数据读取完毕 System.out.println(fis.read());// -1 数据读取完毕 } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { // 如果创建io流对象时发生异常 关流的时候会空指针异常 if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
OutputStream【字节输出流】
概述:
他是字节输出流的顶层父类,是一个抽象类,定义了所有的字节输出流的共性功能
他自己不能创建对象不能使用自己的功能只能找他的子类
子类根据设备不同有不同的子类,常见的子类:FileOutputStream【文本字节输出流】
常用功能:
void write(int b):
输出字节内容到指定的目标文件中
void write(byte[] arr):
输出字节数组中所有的字节内容到目标文件中
void write(byte[] arr, int offset, int len):
输出字节数组中指定范围的字节内容到目标文件中
offset:输出的字节内容的开始索引值
len:输出的字节个数 【数值不能大于数组长度-offset【开始索引值】】
void close():关闭流
FileOutputStream
概述:
文本字节输出流,是OutputStream的子类,负责内存和磁盘文件之间的数据的输出交互的流, 功能都是OutputStream的功能
构造方法:
FileOutputStream(File file):
创建以指定File对象对应的文件为目标文件的字节输出流对象
FileOutputStream(String path):
创建以指定path路径对应的文件为目标文件的字节输出流对象
注意事项:
1、字节输出流对象创建的时候指定的目标文件不存在自动的给创建文件
【前提:文件所在的目录在磁盘真实存在的】
2、字节输出流对象创建的时候指定的目标文件存在对该文件进行格式化
要想保留原文件的内容,在源文件的内容的基础上进行书写内容需要使用功
能追加续写功能的构造方法:
【续写功能】
FileOutputStream(String path,boolean b):
FileOutputStream(File file,boolean b):
参数b必须是true。
代码示例:package com.ujiuye.demo; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class FileOutputStreamDemo { public static void main(String[] args) { FileOutputStream fos = null; // 想要写内容数据到指定目标文件中 // 创建字节输出流对象 try { fos = new FileOutputStream("n\\jinlian.txt"); // fos = new FileOutputStream("n\\jinlian.txt",true); // 写单个字节到文件 fos.write(101); // 写出字节数组的内容 byte[] bs = "金莲有想法,姜涛流口水".getBytes(); fos.write(bs); // 写出字节数组的指定内容 fos.write("口水流到裤子上,学航就误会了".getBytes(),16,12); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { // 避免空指针异常 if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
文件拷贝
把一个指定的文件复制到指定的另一个路径文件中。
比如:把一张图片复制到另一个目录文件下复制:一个文件数据原封不动的转移到另一个文件
转移的本质是数据
数据转移不可能直接从一个文件到另一个文件 ,数据先从初始文件中到内存,在把内存中搞到
目标文件 初始文件的数据一次性全部进入内存中,需要重复的读取才能把所有的数据搞到内存中,每次
读取有覆盖行为,读的目的转移数据,所以每次读取的时候读到多少同时及时写到目标文件中
步骤: 1、创建字节输入流对象
2、创建字节输出流对象
3、读完了不写
方式:
1、available() 返回值为0
2、read方法返回值为-1
4、边读边写【循环 while循环】
作业:
1、把案例整会
2、使用字节数组进行复制
代码示例:
package com.ujiuye.demo; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class ImgCopy { public static void main(String[] args) { copyFile("img/美女.jpg","m/美女.jpg"); copyFile("n/jinlian.txt","m/jinlian.txt"); // 2、创建字节输出流对象 // 3、读完了不写 // 方式: // 1、available() 返回值为0 // 2、read方法返回值为-1 } private static void copyFile(String path1,String path2) { FileInputStream fis = null; FileOutputStream fos = null; // 1、创建字节输入流对象 try { fis = new FileInputStream(path1); fos = new FileOutputStream(path2); // 4、边读边写【循环 while循环】 // 方式一: // while (fis.available() != 0) { // // 把读到的内容写出去 // int b = fis.read();// 每次读到的内容 // fos.write(b);// 把每次读到的内容写出去 // } // 方式二 int len ; while ((len = fis.read()) != -1) { // int b = fis.read();// 每次读到的内容 fos.write(len);// 把每次读到的内容写出去 } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
字节缓冲流【字节高效率】
概述:
他就是用来给字节流提升效率,对字节流进行包装的,字节缓冲流本身不能操作数据【读取数
据】,但是他的对象可以调用字节流的基本功能【底层还是基本字节流在调用对应的功能】。 就相当于是一个工具流。
作用:
给字节流提升运行效率
分类:
字节输出缓冲流【BufferedOutputStream】
字节输入缓冲流【BufferedInputStream】
构造方法:
BufferedInputStream(InputStream is):
创建一个以is为提升目标的字节输入缓冲流对象
BufferedOutputStream(OutputStream os):
创建一个以os为提升目标的字节输出缓冲流
功能:
就是字节流的功能
字节输出缓冲流的特有方法:
flush():刷新缓冲区。
flush方法和close方法的区别:
1、flush方法只是用来刷新字节输出缓冲流的缓冲区内容的
方法调用之后流对象还存在的可以继续使用
2、close方法用来关闭流对象,默认先调用flush方法刷新缓冲区后关闭流对象
方法调用之后流对象不存在的,不能继续使用的
代码示例:package com.ujiuye.demo; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; public class BufferedIOStreamDemo { public static void main(String[] args) throws Exception { // 创建一个需要提速的字节输入流 FileInputStream fis = new FileInputStream("m\\jinlian.txt"); // 使用字节输入缓冲流 BufferedInputStream bis = new BufferedInputStream(fis); int i = bis.read(); System.out.println(i); byte[] bytes = new byte[2]; int j = bis.read(bytes); System.out.println(new String(bytes,0,j)); // 字节输出缓冲流 // 创建一个字节输出流 FileOutputStream fos = new FileOutputStream("n\\a.txt"); BufferedOutputStream bos = new BufferedOutputStream(fos); bos.write(100); bos.write("姜涛生气了,口水流的太多了,被学航揍了".getBytes()); // 特有方法 // bos.flush();// 刷新缓冲区 bos.close();// 先去调用flush方法刷新缓冲区 再关流 } }
字节缓冲流高效原理【必须要会描述】
原理:
字节输入缓冲流: 第一次调用read方法读数据的时候,字节缓冲流对象现在内存中创建一个长度为8192长的
字节数组【缓冲区】,一次性的从目标文件中读取8192个字节内容到字节数组中,基本流
调用对应的read方法到字节数组中获取数据,当字节数组数据获取完毕,缓冲流对象再到
目标文件获取8192个字节内容回来供基本流调用read方法读取,减少字节输入流在内存和
目标文件之间的交互次数从而提效。 字节输出缓冲流:
第一次调用write方法写出数据的时候,缓冲流对象在内存创建一个长度为8192长的字节 数组【缓冲区】,基本流每次调用write方法写出的字节优先写到字节数组中,字节数组被 写满了【8192个字节】写入下一个字节的时候缓冲区自动的把内部的字节数写到目标文件 中,如果没有写满需要把写入的数据写到目标文件需要掉用flush方法。减少了内存和文 件之间的交互次数,提效了
文件拷贝之缓冲流版
把一个指定的文件复制到指定的另一个路径文件中。
比如:把一张图片复制到另一个目录文件下代码示例:
package com.ujiuye.demo; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.text.Bidi; public class ImgBufferedCopy { private static void copyFile(String path1,String path2) { FileInputStream fis = null; FileOutputStream fos = null; BufferedInputStream bis = null; BufferedOutputStream bos = null; // 1、创建字节输入流对象 try { fis = new FileInputStream(path1); bis = new BufferedInputStream(fis); fos = new FileOutputStream(path2); bos = new BufferedOutputStream(fos); // 4、边读边写【循环 while循环】 // 方式一: // while (fis.available() != 0) { // // 把读到的内容写出去 // int b = fis.read();// 每次读到的内容 // fos.write(b);// 把每次读到的内容写出去 // } // 方式二 int len ; while ((len = bis.read()) != -1) { // int b = fis.read();// 每次读到的内容 bos.write(len);// 把每次读到的内容写出去 } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { if (bos != null) { try { bos.close(); } catch (IOException e) { e.printStackTrace(); } } if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } if (bis != null) { try { bis.close(); } catch (IOException e) { e.printStackTrace(); } } if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } } }