Java 文件分割与合并
文件分割
将一个文件分成多个小文件,待分割文件大小和子文件大小为已知。要求合并后能正常使用。
问题分析
1 文件分割需要用到的byte数组的大小是恰好等于每个子文件大小,还是小于?
等于:问题会简化。但是如果子文件很大,那么内存就可能达不到byte数组大小的要求。
小于:更加合理,贴近实际。
2 如何确定子文件“装满了”?
考虑byte数组的长度(read的返回值)和子文件写入次数的关系
3 并不是每个子文件的实际大小都能达到规定容量,如何解决这个问题?
byte数组长度为-1时,文件就读完了。
读多少,写多少
说了这几点,估计大家看着还是懵。
我来把问题的解决方法形象化:
//大致思路,仓库-车-桶
//一个仓库(待分割文件)
//一个车(反复运用多次)
//(1-N)个桶(用户定义桶的大小,所以桶的个数一开始就确定了)
//仓库里取出来的东西装到车里,车里的东西再倒到桶里
//一个个桶可以看做数组里的一个个元素
还是看不懂?那就看代码吧~
//巧妙利用length来装子文件
public static void grandFileSplit(File file) throws IOException
{
FileInputStream fis=new FileInputStream(file);
//分割好的文件存放位置可以改
File tempFile=new File("D:\\temp");
if(!tempFile.exists())
{
//不存在了就创建
tempFile.mkdir();
}
byte [] b=new byte[1024];//用小于子文件的数组也可以
int length=0;
long Length=1024*1024;//1MB
int tempFileArgsSize=(int)((file.length()%Length==0)?(file.length()/Length):(file.length()/Length)+1);
for(int i=0;i<tempFileArgsSize;i++)
{
File newFile=new File("D:\\temp\\temp"+(i+1)+".mp3");
FileOutputStream fos=new FileOutputStream(newFile);
BufferedOutputStream bos=new BufferedOutputStream(fos);
int currSize=0;
while((length=fis.read(b))!=-1)
{
currSize+=length;
if(currSize>=Length)
break;
//写入实际长度就好
bos.write(b, 0, length);
}
bos.flush();
bos.close();
}
fis.close();
}
文件合并
将一个个子文件合并为一个大文件。要求合并后能正常使用。
问题分析
这个就比较好理解。依次取出每个子文件的内容,装到大文件就行。
public static void fileMerge(File file) throws IOException
{
//罗列文件夹中所有的文件
File [] fileArgs=file.listFiles();
int length=0;
//这次与1024还是1024*1024无关,只要把一个子文件的内容搬运完就行
byte [] b=new byte[1024];
//指定输出路径
FileOutputStream fos=new FileOutputStream("D:\\luhan.mp3");
for(File f:fileArgs)
{
//拿出所有的文件,(分割),发送
FileInputStream fis=new FileInputStream(f);
while((length=fis.read(b))!=-1)
fos.write(b,0,length);
fis.close();
}
fos.close();
//删除子文件和文件夹
for(File f:fileArgs)
f.delete();
file.delete();
}