目录
- IO流概述和分类
- 字节流写入数据(OutputStream)
- FileOutputStream
- 字节流写数据的3种方式
- 字节流写入数据的两个小问题
- 字节流写数据如何换行
- 字节流如何实现追加写入
- 字节流写入数据加入异常处理
- 字节流读取数据(InputStream)
- FileInputStream
- 字节流读取数据的三种方法
- 字节缓冲流(Buffer)
- BufferedOutputStream
- BufferedInputStream
- 字节流复制图片视频案例(附字节流和字节缓冲流速度比较)
- 复制图片
- 复制视频
IO流概述和分类
IO流分类:
- 按数据的流向:
输入流(in):读数据(read)
输出流(out):写数据(write) - 按照数据类型来分:
字节流:字节输入流、字节输出流
字符流:字符输入流、字符输出流 - 一般来说:IO流是按数据类型来分的
- 如果数据通过Windows自带的记事本软件打开,我们还可以读得懂里面的内容,那就是字符流,否则就是字节流。如果你不知道该用哪种类型的流,就是字节流
字节流写入数据(OutputStream)
注意:
- InputStream:表示字节输入流所有类的超类
- OutputStream:表示输出流所有类的超类
- 子类名特点:子类名称都是以其父类名作为子类名的后缀
FileOutputStream
FileOutputStream:所在包:java.io
public class FileOutputStreamextends 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)写入数据 字符数据在文件中显示abyte[] b = {97,98,99,100}; f1.write(b); //void write(byte[] b)写入数据 字符数据在文件中显示abcdbyte[] c = "abcdefghi".getBytes(); //利用String.getBytes()方法获取byte数组 更直观的定义文件中的字符数据f1.write(c); //void write(byte[] b)写入数据 字符数据在文件中显示abcdefghif1.write(c,3,3); //void write(byte[] b,int off,int len)写入数据 //从off索引开始往后输出len长度的数据 输出byte[3]--byte[6]的数据defgf1.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 FileInputStreamextends 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 BufferedOutputStreamextends FilterOutputStream
该类实现缓冲输出流。通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用
BufferedInputStream
所在包:java.io
public class BufferedInputStreamextends 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();