字节流(IO流)概述、字节流(写入/输出)数据(3种)和换行、追加写入、异常处理办法、字节缓冲流、字节流复制图片视频案例
目录
IO流概述和分类
IO流分类:
- 按数据的流向:
输入流(in):读数据(read)
输出流(out):写数据(write) - 按照数据类型来分:
字节流:字节输入流、字节输出流
字符流:字符输入流、字符输出流 - 一般来说:IO流是按数据类型来分的
- 如果数据通过Windows自带的记事本软件打开,我们还可以读得懂里面的内容,那就是字符流,否则就是字节流。如果你不知道该用哪种类型的流,就是字节流
字节流写入数据(OutputStream)
注意:
- InputStream:表示字节输入流所有类的超类
- OutputStream:表示输出流所有类的超类
- 子类名特点:子类名称都是以其父类名作为子类名的后缀
FileOutputStream
FileOutputStream:
所在包:java.io
public class FileOutputStream
extends OutputStream
FileOutputStream:文件输出流用于将数据写入File:
构造方法FileOutputStream(String name):
创建文件输出流以指定的名称写入文件
FileOutputStream fos=new FileOutputStream("myByteStream\\fos.txt");
//该类一共做了三件事情
A:调用了系统功能创建了文件(fos.txt) //就算该抽象文件名的文件不存在也会自动创建该文件
B:创建了字节输出流对象
C:让字节输出流对象指向创建好的文件 //类似指针
//调用写入方法void write(int b);
fos.write(97);
//最后IO流要释放资源 调用close方法:关闭此文件输出流并释放与此流相关联的任何系统资源
fos.close();
字节流写数据的3种方式
方法名 | 作用 |
---|---|
void write(int b) | 将指定的字节写入此文件输出流,一次写一个字节数据 |
void write(byte[] by) | 将b.length字节从指定的字节数组写入子文件输出流,一次写一个字节数组数据 |
void write(byte[] b,int off,int len) | 将len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流,一次写一个字节数组的部分数据(以off为索引写len长度的数据) |
void flush() | 清空流并强制将缓冲区中所有数据写入流中 |
代码示例:
输出流的两种构造函数
FileOutputStream(String name);
FileOutputStream(File file);
FileOutputStream f1 = new FileOutputStream();
f1.write(97);
//void write(int b)写入数据 字符数据在文件中显示a
byte[] b = {
97,98,99,100};
f1.write(b);
//void write(byte[] b)写入数据 字符数据在文件中显示abcd
byte[] c = "abcdefghi".getBytes();
//利用String.getBytes()方法获取byte数组 更直观的定义文件中的字符数据
f1.write(c);
//void write(byte[] b)写入数据 字符数据在文件中显示abcdefghi
f1.write(c,3,3);
//void write(byte[] b,int off,int len)写入数据
//从off索引开始往后输出len长度的数据 输出byte[3]--byte[6]的数据defg
f1.close();
字节流写入数据的两个小问题
字节流写数据如何换行
写完数据后,加上换行符:
Windows:\r\n
Linux:\n
Mac:\r
例:f1.write(97);
f1.write("\r\n".getBytes());
//注意换行符是String类型,需要用getBytes()方法将String类型转换为byte[]类型才能完成转换
字节流如何实现追加写入
public FileOutputStream(String name,boolean append);
创建文件输出流以指定的名称写入文件。
如果第二个参数值为true,则字节将写入文件的末尾而不是开头(在没有append参数的情况下默认写入文件开头
字节流写入数据加入异常处理
finally:在异常处理时提供finally块来执行所有清除操作。比如IO流中的释放资源
特点:被finally控制的语句一定会执行,除非JVM退出
字节流异常处理标准格式:
try{
可能出现异常的代码;
}catch(异常类名 变量名){
变量名.异常处理代码;
}finally{
执行所有清除操作;
}
代码示例:
Public static void main(String[] args){
FileOutputStream f1 = null;
//定义在try外面避免执行finally语句时找不到f1变量 注意在外部定义时要进行初始化(f1=null)
try{
f1 = new FileOutputStream("D:\\java000\\test001\\java.txt");
f1.write(97);
}catch(IOException e){
e.printStackTrace();
}finally{
try{
if(f1 != null)
f1.close();
//执行f1=new FileOutputStream("D:\\java000\\test001\\java.txt");
//时因该考虑初始化失败问题所以加入if避免空指针异常
}catch(IOException e){
e.printStackTrace();
}
}
}
字节流读取数据(InputStream)
使用字节流读数据的步骤:
1.创建字节输入流对象
2.调用字节输入流对象的读数据方法
3.释放资源
FileInputStream
所在包:java.io
public class FileInputStream
extends InputStream
构造函数:
FileInputStream(String name);
代码示例:
FileInputStream f1 = new FileInputStream("test001\\java.txt");
int by=f1.read(); //调用字节输入流对象的读数据方法
System.out.print(by);
f1.close();
字节流读取数据的三种方法
方法名 | 作用 |
---|---|
int read() | 从这个输入流读取一个字节的数据 |
int read(byte[] b) | 读取b.length字节的数据,从这个输入流到一个字节数组 |
int read(byte[] b,int off,int len) | 读取len字节的数据,从这个输入流到一个字节数组 |
long skip(long n) | 从输入流跳过,丢弃n字节的数据输入流 |
代码示例:
read(int b);
例:
FileInputStream f1 = new FileInputStream("D:\\java000\\test001\\java.txt");
int by;
while((by = f1.read())!=-1){
System.out.print((char)by);
}
f1.close();
read(byte[] b);
例:
FlieInputStream f1 = new FlieInputStream("D:\\java000\\test001\\java.txt");
byte[] by = new byte[1024]
//一般长度设置为1024的倍数
int len;
while(( len = f1.read(by) ) != -1){
//注意:len=f1.read(by);中len表示f1文件中读到的字符数量
//当byte[n]中n小于len时 read()读出的是n长度的字符
System.out.print( new String(by) );
//len表示read方法所读到的字符数量
}
f1.close();
read(byte[] b,int off,intlen);
例:
FileInputStream f1 = new FileInputStream("D:\\java000\\test001\\java.txt");
byte[] b = new byte[1024];
int len;
while( ( len=f1.read(by) )!=-1 ){
System.out.print( new String(by,0,len) );
//new String(byte[] bytes,int offset,int length):
通过使用平台默认字符集解码指定的字节子阵列来构造新的String.
就是转换byte[0]~byte[len]成为新的String
}
字节缓冲流(Buffer)
BufferedOutputStream
所在包:java.io
public class BufferedOutputStream
extends FilterOutputStream
该类实现缓冲输出流。通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用
BufferedInputStream
所在包:java.io
public class BufferedInputStream
extends FilterInputStream
创建BufferedInputStream将创建一个内部缓冲区数组。当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节。
构造方法:
字节缓冲输出流:BufferedOutputStream(OutputStream out)
字节缓冲输入流:BufferedInputStream(InputStream in)
为什么构造方法需要的是字节流,而不是具体的文件或者路径呢?
字节缓冲流仅仅提供缓冲区,而真正的读写数据还得依靠基本的字节流对象进行操作
代码示例:
字节缓冲输出流:
BufferedOutputStream bf1 = new BufferedOutputStream( new FileOutputStream("test001\\java.txt") );
bf1.write("abcdefg\r\n".getBytes); //String转换为byte类型用String.Bytes();方法
bf1.close();
字节缓冲输入流:
BufferedInputStream bf2 = new BufferedInputStream( new FileInputStream("test001\\java.txt") );
byte[] by = new byte[1024];
int len;
while( (len=bf2.read(by))!=-1 ){
System.out.print( new String(by,0,len) );
}
bf2.close();
字节流复制图片视频案例(附字节流和字节缓冲流速度比较)
复制图片
代码示例:
使用字节数组读写复制即可:
FileInputStream in = new FileInputStream("数据源文件");
FileOutputStream out = new FileOutputStream("目的地文件");
byte[] by=new byte[1024];
int len;
while( (len=in.read(by))!=-1 ){
out.write(by,0,len);
}
in.close();
out.close();
注意:字节流复制可以复制任意文件
流程:
1.创建输入流(InputStream)
2.创建输出流(OutputStream)
3.循环复制
4.close释放资源
复制视频
利用四种方法来复制视频,并比较四种方法之间哪种方法最快
1.基本字节流一次读写一个字节 //最慢
2.基本字节流一次读写一个字节数组 //比第1种快60+倍
3.字节缓冲流一次读写一个字节 //比第3种慢一点点
4.字节缓冲流一次读写一个字节数组 //最快
时间记录由System.currentTimeMillis();方法记录
int start = System.currentTimeMillis();
int end = System.currentTimeMillis();
代码示例:
1.基本字节流一次读写一个字节:
FileOutputStream fout1=new FileOutputStream("复制目的地");
FileInputStream fin1=new FileInputStream("视频源");
int by;
while( (by=fin1.read() ) != -1){
fout1.write(by);
}
fout1.close();
fin.close();
2.基本字节流一次读写一个字节数组:
FileOutputStream fout1=new FileOutputStream("复制目的地");
FileInputStream fin1=new FileInputStream("视频源");
int len;
byte[] by = new byte[1024];
while( (len=fin1.read(by))!=-1 ){
fout1.write(by,0,len);
//将len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流,
//一次写一个字节数组的部分数据(以off为索引写len长度的数据)
}
fout1.close();
fin.close();
3.字节缓冲流一次读写一个字节:
BufferedOutputStream bout1=new BufferedOutputStream("存入目标");
BufferedInputStream bin1=new BufferedInputStream("目标源文件");
int by;
while( (by=bin1.read())!=-1 ){
bout1.write(by);
}
bout1.close();
bin1.close();
4.字节缓冲流一次读写一个字节数组:
BufferedOutputStream bout1=new BufferedOutputStream("存入目标");
BufferedInputStream bin1=new BufferedInputStream("目标源文件");
int len;
byte[] by=new byte[1024];
while( (len=bin1.read())!=-1 ){
bout1.write(by,0,len);
}
bout1.close();
bin1.close();