一、IO流图:
二、字节流:
在计算机中,无论是图片、文本、音频还是视频,所有的文件都是以二进制(字节)形式存在。IO流中针对字节的输入输出提供了一系列的流,统称为字节流。
在JDK中,提供了两个抽象类InputStream和OutputStream,它们是字节流的顶级父类。所有的字节输入流都继承自InputStream,所有的字节输出流都继承自OutputStream。
1、InputStream的常用方法
**方法声明** **功能描述**
int read () 从输入流读取一个8位的字节,把它转换为0~255之间的整数,并返回这一整数。
int read (byte[] b) 从输入流读取若干字节,把它们保存到参数b指定的字节数组中,返回的整数表示读取字节数。
int read ( byte[] b, int off , int len) 从输入流读取若干字节,把它们保存到参数b指定的字节数组中,off指定字节数组开始保存数据的起始下标,len表示读取的字节数目。
void close() 关闭此输入流并释放与该流关联的所有系统资源。
2、OutputStream常用方法
**方法名称** **方法描述**
void write (int b) 向输出流写入一个字节。
void write ( byte[] b) 把参数b指定的字节数组的所有字节写到输出流。
void write ( byte[] b, int off, int len) 将指定byte数组中从偏移量off开始的len个字节写入输出流。
void flush () 刷新此输出流并强制写出所有缓冲的输出字节。
void close() 关闭此输出流并释放与此相关的所有系统资源。
InputStream和OutputStream是抽象类,不能被实例化。因此针对不同的功能,InputStream和OutputStream提供了不同的子类,这些子类形成了一个体系结构。
![]()
InputStream的子类
![]()
OutputStream的子类
3、字节流读写文件
针对文件的读写,JDK专门提供了两个类,分别是FileInputStream和FileOutputStream。
FileInputStream是InputStream的子类,它是操作文件的字节输入流,专门用于读取文件中的数据。
注意:在读取文件数据时,必须保证文件是存在并且可读的,否则会抛出文件找不到的异常FileNotFoundException
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class IO_01 {
private static FileInputStream fileIn;
public static void main(String[] args) {
try {
/*
* 创建一个文件字节输入流
* FileInputStream(""):
* 1、相对路径: 相对于工程目录 src/In.txt
* 2、绝对路径: 盘符根目录 E:/HomeWork/Eclipse/IO/src/In.txt
*/
fileIn = new FileInputStream("src/In.txt");
//定义一个int类型的变量b,记住每次读取的一个字节
int b = 0;
while (true){
b = fileIn.read();
//如果读取的字节为-1,跳出while循环
if (b == -1){
break;
}
System.out.println(b);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
if( fileIn != null){
fileIn.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
4、FileOutputStream是OutputStream的子类。它是操作文件的字节输出流,专门用于把数据写入文件。
注意:通过FileOutputStream向一个已经存在的文件中写入数据,那么该文件中的数据首先会被清空,再写入新的数据。
FileOutputStream会自己生成指定的文本文件Out.txt
import java.io.FileOutputStream;
import java.io.IOException;
public class IO_02 {
private static FileOutputStream out;
public static void main(String[] args) {
try {
//创建一个文件字节输出流
out = new FileOutputStream("src/Out.txt");
String str = "数据";
/*
* getBytes(): 将一个字符串转化为一个字节数组
* String的getBytes()方法是得到一个系统默认的编码格式的字节数组。
* 将一个string类型的字符串中包含的字符转换成byte类型并且存入一个byte数组中。
* 在java中的所有数据底层都是字节,字节数据可以存入到byte数组。
* 存储字符数据时(字符串就是字符数据),会先进行查表,然后将查询的结果写入设备,
* 读取时也是先查表,把查到的内容打 印到显示设备上,getBytes()是使用默认的字符集进行转换,
* getBytes(“utf-8”)是使用UTF-8编码表进行转换
*/
byte[] b = str.getBytes();
for(int i=0; i<b.length; i++){
//write(int b) 向输出流写入一个字节。
out.write(b[i]);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
if(out != null){
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
5、如果想在已存在的文件内容之后追加新内容,则可使用FileOutputStream的构造函数
FileOutputStream(String fileName, boolean
append)来创建文件输出流对象,并把append参数的值设置为true. FileOutputStream out = new
FileOutputStream(“src/Out.txt”, true);
6、文件的拷贝
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class IO_04 {
private static FileOutputStream out;
private static FileInputStream in;
public static void main(String[] args) {
try {
//读取src目录下source文件夹下的文件
in = new FileInputStream("src/source/PRC 巴音汗 - 80000 (Prod.By DROYC).mp3");
//写入src目录下target文件夹中,形成1.mp3文件
out = new FileOutputStream("src/target/PRC 巴音汗 - 80000 (Prod.By DROYC).mp3.mp3");
//用于存入文件的每一个字节。
int b = 0;
//获取拷贝前的时间
long beginTime = System.currentTimeMillis();
//读取一个字节并判断是否读到文件末尾
while ((b=in.read()) != -1){
out.write(b);
}
//获取拷贝后的时间
long endTime = System.currentTimeMillis();
System.out.println("拷贝文件消耗时间 :"+(endTime-beginTime)/1000+"秒");
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(out != null){
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(in != null){
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
7、字节流的缓冲区
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class IO_04 {
private static FileOutputStream out;
private static FileInputStream in;
public static void main(String[] args) {
try {
//读取src目录下source文件夹下的文件
in = new FileInputStream("src/source/PRC 巴音汗 - 80000 (Prod.By DROYC).mp3");
//写入src目录下target文件夹中,形成1.mp3文件
out = new FileOutputStream("src/target/PRC 巴音汗 - 80000 (Prod.By DROYC).mp3.mp3");
//定义一个int类型的变量len记住读取读入缓冲区的字节数。
int len;
//定义一个字节数组,作为缓冲区
byte[] bs = new byte[2048];
//获取拷贝前的时间
long beginTime = System.currentTimeMillis();
//读取一个字节并判断是否读到文件末尾
while ((len=in.read(bs)) != -1){
//从第一个字节开始,向文件写入len个字符
out.write(bs, 0, len);
// System.out.println(len);
}
//获取拷贝后的时间
long endTime = System.currentTimeMillis();
System.out.println("拷贝文件消耗时间 :"+(endTime-beginTime)+"毫秒");
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(out != null){
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(in != null){
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
8、装修设计模式
装饰设计模式就是通过包装一个类,动态地为它增加功能的一种设计模式。
public class IOTest {
public static void main(String[] args) {
System.out.println("----------------包装前----------------");
A a = new A("ZL");
a.show();
System.out.println("----------------包装后----------------");
B b = new B(a);
b.show();
}
}
class A {
String name;
public A(String name) {
super();
this.name = name;
}
void show() {
System.out.println("我是:" + name + " 爱好写代码");
}
}
class B {
public A a;
public B(A a) {
super();
this.a = a;
}
void show() {
a.show();
System.out.println("会写HelloWorld");
}
}
9、字节流的缓冲区
在IO包中提供两个带缓冲的字节流,分别 是BufferedInputStream和BufferedOutputStream,这两个流都使用了装饰设计模式。它们的构造方法中分别接收InputStream和OutputStream类型的参数作为被包装对象。在读写数据时提供缓冲功能。
应用程序、缓冲流和底层字节流之间的关系如图
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class IO_05 {
private static BufferedOutputStream bos; // 字节输出缓冲流
private static BufferedInputStream bis; // 字节输入缓冲流
public static void main(String[] args) {
try {
bis = new BufferedInputStream(new FileInputStream
("src/source/PRC 巴音汗 - 80000 (Prod.By DROYC).mp3"));
bos = new BufferedOutputStream(new FileOutputStream
("src/target/1.mp3"));
int len;
long startTime = System.currentTimeMillis();
while ((len = bis.read()) != -1) {
bos.write(len);
}
long endTime = System.currentTimeMillis();
System.out.println(endTime - startTime + "毫秒");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bos != null) {
bos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (bis != null) {
bis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}