目录
字节流两大基类:
InputStream :字节读取流
OutputStream:字节写入流
字节流常用基本读写操作
int available():返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取(或跳过)的估计剩余字节数(获取要读取文件总的字节数)。容易造成内存溢出,慎重使用。
import java.io.*;
class FileStream{
public static void main(String[] args)throws IOException{
readFile_3();
}
// 字节读取流,数组大小正好的读取
public static void readFile_3()throws IOException{
FileInputStream fis=new FileInputStream("fos.txt");
// int num = fis.available(); // 获取要读取文件总的字节数
byte[] buf=new byte[fis.available()]; // 定义一个刚刚好的缓冲区,大小正好,不用再循环。
// 但是这种方式要慎重使用,当要读取的文件过大时,容易发生内存溢出。
fis.read(buf);
System.out.println(new String(buf));
fis.close();
}
// 字节读取流,数组读取
public static void readFile_2()throws IOException{
FileInputStream fis=new FileInputStream("fos.txt");
byte[] buf=new byte[1024];
int len=0;
while((len=fis.read(buf))!=-1){
System.out.println(new String(buf,0,len));
}
fis.close();
}
// 字节读取流,单个读取
public static void readFile_1()throws IOException{
FileInputStream fis=new FileInputStream("fos.txt");
int ch=0;
while((ch=fis.read())!=-1){
System.out.println((char)ch);
}
fis.close();
}
// 字节写入流
public static void writeFile()throws IOException{
FileOutputStream fos=new FileOutputStream("fos.txt");
fos.write("abcde".getBytes());
fos.close();
}
}
案例:复制图片
需求:复制一个图片
思路:
1.用字节读取流对象和图片关联。
2.用字节写入流对象创建一个图片文件。用于存储获取到的图片数据。
3.通过循环读写,完成数据的存储。
4.关闭资源。
编码:
import java.io.*;
class CopyPic{
public static void main(String[] args){
FileOutputStream fos=null;
FileInputStream fis=null;
try{
fos=new FileOutputStream("F:\\2.jpg");
fis=new FileInputStream("F:\\1.jpg");
byte[] buf=new byte[1024];
int len=0;
while((len=fis.read(buf))!=-1){
fos.write(buf,0,len);
}
}catch(IOException ex){
throw new RuntimeException("复制图片失败!");
}finally{
try{
if(fis!=null)
fis.close();
}catch(IOException ex){
throw new RuntimeException("读取关闭失败!");
}
try{
if(fos!=null)
fos.close();
}catch(IOException ex){
throw new RuntimeException("写入关闭失败!");
}
}
}
}
案例:复制音频
需求:演示avi视频复制,通过缓冲区提高效率。
缓冲区对象:
BufferedOutputStream
BufferedInputStream
import java.io.*;
class CopyAvi{
public static void main(String[] args)throws IOException{
long start=System.currentTimeMillis();
copy_2();
long end=System.currentTimeMillis();
System.out.println("运行时间:"+(end-start)+" 毫秒");
}
// 通过字节流的缓冲区完成复制,效率高
public static void copy_2()throws IOException{
BufferedInputStream bufis=new BufferedInputStream(new FileInputStream("F:\\1.avi"));
BufferedOutputStream bufos=new BufferedOutputStream(new FileOutputStream("F:\\2.avi"));
byte[] buf=new byte[1024*1024];
int len=0;
while((len=bufis.read(buf))!=-1){
bufos.write(buf,0,len);
}
bufos.close();
bufis.close();
}
// 通过字节流的缓冲区完成复制
public static void copy_1()throws IOException{
BufferedInputStream bufis=new BufferedInputStream(new FileInputStream("F:\\1.avi"));
BufferedOutputStream bufos=new BufferedOutputStream(new FileOutputStream("F:\\2.avi"));
int by=0;
while((by=bufis.read())!=-1){
bufos.write(by);
}
bufos.close();
bufis.close();
}
}
自定义BufferedInputStream
/*
自定义BufferedInputStream
*/
import java.io.*;
class MyBufferedInputStream{
private InputStream in;
private byte[] buf=new byte[1024*4];
private int pos=0,count=0;
MyBufferedInputStream(InputStream in){
this.in=in;
}
// 一次读一个字节,从缓冲区(字节数组)获取
public int myRead()throws IOException{
// 通过in对象读取硬盘上数据,并存储buf中
if(count==0){
count=in.read(buf);
if(count<0)
return -1;
pos=0;
byte b=buf[pos];
count--;
pos++;
return b&255;
}else if(count>0){
byte b=buf[pos];
count--;
pos++;
return b&0xff;
}
return -1;
}
public void myClose()throws IOException{
in.close();
}
}
/*调用*/
public static void main(String[] args)throws IOException{
long start=System.currentTimeMillis();
copy_3();
long end=System.currentTimeMillis();
System.out.println("运行时间:"+(end-start)+" 毫秒");
}
public static void copy_3()throws IOException{
MyBufferedInputStream bufis=new MyBufferedInputStream(new FileInputStream("F:\\1.avi"));
BufferedOutputStream bufos=new BufferedOutputStream(new FileOutputStream("F:\\2.avi"));
int by=0;
// System.out.println("第一个字节:"+bufis.myRead()); // 注释,否则会少写一次
while((by=bufis.myRead())!=-1){
bufos.write(by);
}
bufos.close();
bufis.myClose();
}