JavaIO 使用缓冲字节流和文件字节流拷贝文件
文件字节流复制文件的原理是:读取一个个字节(或者字节数组),然后再写入文件中去。
缓冲字节流复制文件的原理是:读取一个个字节(或者字节数组)放到缓冲字节数组中,等到缓冲字节数组读满后,再把这几次读取到的字节一并写到文件中去。这样使用缓冲字节流,就能少写几次文件,进而节省时间。
测试代码:
(1)批量读取比较:
public class TestBuffered_File
{
public static void copyFileBufferd(File srcFile,File destFile,int bufsize) throws IOException
{
if(!srcFile.exists())
{
throw new FileNotFoundException("文件"+srcFile+"不存在");
}
if(!srcFile.isFile())
{
throw new IllegalArgumentException(srcFile+"不是文件");
}
//创建缓冲字节流对象,内部缓冲设置为bufSize
BufferedInputStream in=new BufferedInputStream(
new FileInputStream(srcFile),bufsize);
BufferedOutputStream out=new BufferedOutputStream(
new FileOutputStream(destFile),bufsize);
int size=0;
byte[] buffer=new byte[512];
//读到字节串到内部缓存,默认缓冲区的大小是8192字节
while((size=in.read(buffer))!=-1)
{
out.write(buffer,0,size);//把读取到的字节串写入到缓冲区,缓冲区写满会自动写入文件
// out.flush();//刷新缓冲区写入文件
}
out.flush();//刷新缓冲区写入文件
in.close();
out.close();
}
/**
* 使用FileInputStream和FileOutputStream 按字节数组拷贝文件
* @param srcFile 源文件File对象
* @param targetFile 目标文件File对象
* @throws IOException
*/
public static void copyFileByBytes(File srcFile,File targetFile) throws IOException
{
if(!srcFile.exists())
{
throw new IllegalArgumentException( srcFile+"文件不存在");
}
if(!srcFile.isFile())
{
throw new IllegalArgumentException( srcFile+"不是文件");
}
FileInputStream in=new FileInputStream(srcFile);
FileOutputStream out=new FileOutputStream(targetFile);
byte[] buf=new byte[512];
int size=0;
while((size=in.read(buf, 0, buf.length))!=-1)
{
out.write(buf, 0, size);
out.flush();//刷新写入文件中去。
}
in.close();
out.close();
}
/**
* 把时间戳(long 毫秒数)转换为格式化时间字符串
* @param timeStamp long毫秒数
* @return 格式化时间字符串
*/
public static String timeStampToDateString(long timeStamp)
{
Date date = new Date(timeStamp);
/*
m 小时中的分钟数
s 分钟中的秒数
S 毫秒数
*/
DateFormat format = new SimpleDateFormat("mm:ss:SS");
String dateString=format.format(date);
return dateString;
}
public static void main(String[] args)
{
String packagePath;
try
{
//使用缓冲字节流拷贝文件
long start=System.currentTimeMillis();//获取当前的时间戳
packagePath = FilePath.getSrcPackagePath(TestBufferedCopy.class);
copyFileBufferd(new File(packagePath+"李玉刚_刚好遇见你.mp3"),
new File(packagePath+"李玉刚_刚好遇见你副本4.mp3"),1024*10);
long end=System.currentTimeMillis();//获取复制后的时间戳
System.out.println("使用缓冲字节流(每次读取字节数组512)拷贝文件用时(分钟:秒:毫秒):"
+timeStampToDateString(end-start));
//使用文件字节流,按字节数组拷贝文件
start=System.currentTimeMillis();
copyFileByBytes(new File(packagePath+"李玉刚_刚好遇见你.mp3"),
new File(packagePath+"李玉刚_刚好遇见你副本5.mp3"));
end=System.currentTimeMillis();
System.out.println("使用文件字节流(每次读取字节数组512)拷贝文件用时(分钟:秒:毫秒):"
+timeStampToDateString(end-start));
} catch (UnsupportedEncodingException e1)
{
e1.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
运行结果:
使用缓冲字节流(每次读取字节数组512)拷贝文件用时(分钟:秒:毫秒):00:00:34
使用文件字节流(每次读取字节数组512)拷贝文件用时(分钟:秒:毫秒):00:00:101
可见,每次读取相同的字节数组的条件下,缓冲字节流多了缓冲,进而减少写入文件的次数,从而比文件字节流用时少。
(2)逐个字节读取比较:
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.lan.filepath.FilePath;
public class TestBuffered_FileByByte
{
public static void copyFileBufferdByByte(File srcFile, File destFile, int bufsize)
throws IOException
{
if (!srcFile.exists())
{
throw new FileNotFoundException("文件" + srcFile + "不存在");
}
if (!srcFile.isFile())
{
throw new IllegalArgumentException(srcFile + "不是文件");
}
// 创建缓冲字节流对象,内部缓冲设置为bufSize
BufferedInputStream in = new BufferedInputStream(
new FileInputStream(srcFile), bufsize);
BufferedOutputStream out = new BufferedOutputStream(
new FileOutputStream(destFile), bufsize);
int size = 0;
// 读到字节串到内部缓存,默认缓冲区的大小是8192字节
while ((size = in.read()) != -1)
{
out.write(size);// 把读取到的字节写入到缓冲区,缓冲区写满会自动写入文件
}
out.flush();// 刷新缓冲区写入文件
in.close();
out.close();
}
/**
* 使用FileInputStream和FileOutputStream 按字节数组拷贝文件
*
* @param srcFile
* 源文件File对象
* @param targetFile
* 目标文件File对象
* @throws IOException
*/
public static void copyFileByByte(File srcFile, File targetFile)
throws IOException
{
if (!srcFile.exists())
{
throw new IllegalArgumentException(srcFile + "文件不存在");
}
if (!srcFile.isFile())
{
throw new IllegalArgumentException(srcFile + "不是文件");
}
FileInputStream in = new FileInputStream(srcFile);
FileOutputStream out = new FileOutputStream(targetFile);
int size = 0;
while ((size = in.read()) != -1)
{
out.write(size);
}
in.close();
out.close();
}
/**
* 把时间戳(long 毫秒数)转换为格式化时间字符串
*
* @param timeStamp
* long毫秒数
* @return 格式化时间字符串
*/
public static String timeStampToDateString(long timeStamp)
{
Date date = new Date(timeStamp);
/*
* m 小时中的分钟数 s 分钟中的秒数 S 毫秒数
*/
DateFormat format = new SimpleDateFormat("mm:ss:SS");
String dateString = format.format(date);
return dateString;
}
public static void main(String[] args)
{
String packagePath;
try
{
// 使用缓冲字节流拷贝文件
long start = System.currentTimeMillis();// 获取当前的时间戳
packagePath = FilePath.getSrcPackagePath(TestBufferedCopy.class);
copyFileBufferdByByte(new File(packagePath + "李玉刚_刚好遇见你.mp3"),
new File(packagePath + "李玉刚_刚好遇见你副本6.mp3"), 1024 * 10);
long end = System.currentTimeMillis();// 获取复制后的时间戳
System.out.println("使用缓冲字节流(逐个字节)拷贝文件用时(分钟:秒:毫秒):"
+ timeStampToDateString(end - start));
// 使用文件字节流,按字节数组拷贝文件
start = System.currentTimeMillis();
copyFileByByte(new File(packagePath + "李玉刚_刚好遇见你.mp3"),
new File(packagePath + "李玉刚_刚好遇见你副本7.mp3"));
end = System.currentTimeMillis();
System.out.println("使用文件字节流(逐个字节)拷贝文件用时(分钟:秒:毫秒):"
+ timeStampToDateString(end - start));
} catch (UnsupportedEncodingException e1)
{
e1.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
}
}
运行结果:
使用缓冲字节流(逐个字节)拷贝文件用时(分钟:秒:毫秒):00:00:279
使用文件字节流(逐个字节)拷贝文件用时(分钟:秒:毫秒):00:35:982
可以看到逐个字节逐个字节的来拷贝文件,使用文件字节流要读一个字节写一个字节,耗时很大。虽然也是每次读取一个字节一个字节的读取,但是使用缓冲字节流读取满缓冲,才写一次文件,也就是读取1024 * 10次,才写一次文件。相比于使用文件字节流节省了1024 * 10-1次写文件的操作。这样就节省更多的时间。
总结:
(1) 如果使用文件字节流,复制文件,每次读取一个数组,写一个数组,比每次读取一个字节,写一个字节更快。
(2) 使用缓冲字节流比文件字节流更快(多分配内存(缓冲)):每次读取一个数组放到一个大的数组中去(缓冲),然后大的数组(缓冲)满了再一次性写入。
还没有评论,来说两句吧...