Java支持对文件的顺序存取和随机存取操作,对文件的读/写操作通过流(stream)来实现。
一、流的概念:流是指一组有顺序、有起点和终点的字节集合,是对数据传输的总称或抽象。
二、流的分类
根据流的方向:输入流、输出流。
根据流中元素的类型:字节流、字符流。
三、流的基本操作
读操作:从流中取得数据的操作;
写操作:向流中添加数据的操作;
四、流类
流的读/写操作的最小单位是字节。
字节输入流类( InputStream):抽象类
字节输出流类(OutPutStream):抽象类
四、文件操作流类:
文件输入流类(FileInputStream):InPutStream类的子类
主要构造方法:
public FileInputStream(String name) throws FileNotFoundException
public FileInputStream(File file ) throws FileNotFoundException
//为指定文件创建文件字节输入流对象
常见方法:
public int read ( ) throws IOException;
//读取下一个字节,如果已到达文件末尾,则返回-1;
public int read(byte[ ] b) throws IOException:
//读取b.length个字节,如果已到达文件末尾,则返回 -1。
(读取的数据占满缓存区,返回值为缓冲区数组长度;读取的数据没有占满缓存区,返回实际读取的字节数)
public int read(byte[ ] b, in off, in len) throwsIOException
//从数组b中从off位置开始读取len个字节,如果已到达文件末尾,则返回-1。
public long skip(long n) throwsIOException
//从输入流中跳过并丢弃n
个字节的数据。
public int available( ) throws IOException
//返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取(或跳过)的估计剩余字节数。
public void close( ) throws IOException
//关闭此文件输入流、,释放与此流有关的所有系统资源。
protected void finalize( ) throws IOException
/ /确保在不再引用文件输入流时调用其 close 方法。
文件输出流类(FileOutputStream):OutPutStream类的子类
主要构造方法:
public FileOutPutStream(String name) throws FileNotFoundExceptinon
public FileOutPutStream (File file) throws FileNotFoundExceptipn
public FileOutputStream(String name, boolen append) throws FileNotFoundException
//为指定文件创建文件字节输出流对象。(其中,append指定文件的写入方式,append取值为true时,为添加方式,数据添加在原文件末尾;append取值为false时,为重写方式,数据从原文件开始处写入,默认为false)
常见方法:
public void write(int b) throws IOException
//将指定字节写入此文件输出流。
public void write(byte[ ] b) throws IOException
//将 b.length 个字节从指定 byte 数组写入此文件输出流中。
public void write(byte[ ] b, int off, int len) throws IOException
// 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。
public void close( ) throws IOException
//关闭此文件输出流,释放与此流有关的所有系统资源。关闭之后文件输出流不能再用于写入字节。
protected void finalize( ) throws IOException
//清理到文件的连接,并确保在不再引用此文件输出流时调用其close 方法。
五、应用——复制文件
1、逐个字节复制
public class CopyFile{
private FileInputStream in=null;
private FileOutputStream out=null;
public void copyFile(String srcfilePathName,String destfilePathName){
try{
in=new FileInputStream(srcfilePathName);
out=new FileOutputStream(destfilePathName);
int i=in.read( );
while(i!=-1){
out.write(i);
i=in.read( );
}
}catch(IOException e){
e.printStackTrace();
}finally{
try{
in.close();
out.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
逐个字节读取,运行速度很慢。
2、借助字节缓冲区一次性读写整个文件
public class CopyFile{
private FileInputStream in=null;
private FileOutputStream out=null;
public void copyFile(File srcfile,File destfile){
try{
in=new FileInputStream(srcfile);
out=new FileOutputStream(destfile);
byte[] buf = new byte[(int)srcfile.length()];
in.read(buf);
out.write(buf);
}catch(IOException e){
e.printStackTrace();
}finally{
try{
in.close();
out.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
运行速度很快,对于小文件可以迅速准确复制,但对于大型文件(尤其是接近或则超过内存大小的文件)易出现很大的问题。
3、每次读取一定字节长度的文件
public void copyFile(String srcfilePath,String destfilePath){
try{
in=new FileInputStream(srcfilePath);
out=new FileOutputStream(destfilePath);
byte[] buf = new byte[1024];
int i=in.read(buf);
while(i!=-1){
out.write(buf);
i=in.read(buf);
}
}catch(IOException e){
e.printStackTrace();
}finally{
try{
in.close();
out.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
}
运行速度较快,但是复制出的文件字节数极有可能会变大。
修正如下:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyFile{
private FileInputStream in = null;
private FileOutputStream out = null;
public void copyFile(String srcPath,String destPath){
try {
in = new FileInputStream(srcPath);
out = new FileOutputStream(destPath);
byte[] buf = new byte[1024];
int i = in.read(buf);
while(i!=-1){
if(i==1024){
out.write(buf);
}else{
out.write(buf,1,i);
}
i = in.read(buf);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
in.close();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}