文件切割和合并
文件的切割使用场景:
平时当我们向某个论坛或者某个网站上传文件的时候,如果某个网站设置一次性只能上传固定大小的文件,那么我们就会把我们的文件进行切割几份然后在上传。
还有,假设我们掌握了某个技术,准备要在网上卖电子书或者视频之类的,那么我们一般会先给用户一些体验的资料或者视频,然后客户满意,在分期给其他的部分,这种情况也涉及到文件的切割。
文件切割方式:
按照每个碎片文件的大小切割,比如2M一个来切(掌握)。
需求:切割D:\test\制服诱惑.avi。
分析:
数据源:使用一个输入流从需要被切割的文件中开始读取字节数据,每次都读取指定的字节数据,比如每次读取2M。一个avi文件,属于字节数据,应该用字节流,输入。FileInputStream。
目的地:把上述每次读取的字节数据统一写到同一个文件中,然后后面读取的数据继续写到其他的文件中。也就是说通过上述对数据源的操作最终会生成多个碎片文件。多个碎片文件,属于字节数据,用字节流,FileOutputStream。数据源每次读取2M数据,把读到的结果写出到一个碎片文件。碎片文件的名字不断变化。动态生成。用一个递增的数字表示文件名。
切割文件的思想如下图所示:
思路:
A:创建输入流,关联一个源文件,D:\test\制服诱惑.avi。
B:读取数据,一次读2M
C:创建输出流,关联1个碎片文件
D:写出数据到碎片文件
E:关闭输出流
F:循环结束,关闭输入流
代码如下所示:
/*
* 切割文件
* 需求:切割D:\\test\\制服诱惑.avi。
* 步骤:
* 1)创建输入流对象,关联源文件
* 2)读取数据,一次读取2M
* 3)创建输出流对象,关联一个碎片文件
* 4)写出数据到碎片文件
* 5)关闭输出流
* 6)循环结束后,关闭输入流
*/
public class CutFile {
public static void main(String[] args) throws IOException {
// 1)创建输入流对象,关联源文件
FileInputStream fis = new FileInputStream("D:\\test\\制服诱惑.avi");
//2)读取数据,一次读取2M 定义数组
byte[] b=new byte[1024*1024*2];
//定义变量记录字节数
int len=0;
//定义变量充当碎片文件的名字
int name=1;
while((len=fis.read(b))!=-1)
{
// 3)创建输出流对象,关联一个碎片文件
//这样写只会在指定的目录中生成一个1.avi,把之前的都覆盖了,有问题
// FileOutputStream fos = new FileOutputStream("F:\\parts\\1.avi");
FileOutputStream fos = new FileOutputStream("F:\\parts\\"+name+".avi");
//4)写出数据到碎片文件
fos.write(b, 0, len);
//5)关闭输出流
fos.close();
name++;
}
//6)循环结束后,关闭输入流
fis.close();
}
}
说明:上述代码切割完成之后,会在指定的路径下生成几个大小为2M的文件,但是由于系统的原因,在系统的硬盘上的所有文件中都有一个文件标识头和结尾标识。而系统只会识别文件的头标识,所以只会播放第一个切割后的文件,其他的文件都不会播放。
补充:对于mp3格式就可以播放,是因为所有播放器的原因,所有播放器都能够识别二进制为mp3的数据。
文件的合并:
合并文件,需要多个输入流分别读取不同的碎片文件中的数据,然后使用同一个输出流写到一个文件中。
分析:
数据源:多个碎片文件,字节数据,用字节流。FileInputStream
循环遍历多个碎片文件,拿到每一个文件,创建输入流关联这个碎片文件,读取数据输出到目的地。
目的地:一个文件,字节数据,用字节流,FileOutputStream
思路:
A:创建输出流,关联目的地文件
B:for循环,获取每个碎片文件。
C:创建输入流,关联这个碎片文件
D:读写数据
E:关闭输入流
F:循环结束,关闭输出流
代码如下所示:
/*
* 合并文件:
* 思想:需要使用不同的输入流来读取不同的碎片文件,然后使用同一个输出流写到同一文件中
* 分析:
* 数据源:多个碎片文件,字节数据,使用字节流。FileInputStream。
* 循环遍历多个碎片文件,拿到每一个文件。创建输入流对象关联这个碎片文件,读取数据输出到目的地。
* 目的地:一个文件,字节数据,字节流,FileOutputStream
* 步骤:
* 1)创建输出流对象,关联目的地文件
* 2)循环遍历碎片文件
* 3)创建输入流对象,关联这个碎片文件
* 4)读写数据
* 5)循环结束一次,关闭输入流
* 6)整个循环结束,关闭输出流
*/
public class FixFile {
public static void main(String[] args) throws IOException {
// 1)创建输出流对象,关联目的地文件
FileOutputStream fos = new FileOutputStream("F:\\柳岩.jpg");
//2)循环遍历碎片文件
for (int i = 1; i <=7; i++)
{
//3)创建输入流对象,关联这个碎片文件
FileInputStream fis = new FileInputStream("F:\\parts\\"+i+".jpg");
//4)读写数据
byte[] b=new byte[1024];
int len=0;
while((len=fis.read(b))!=-1)
{
//有数据,写数据
fos.write(b, 0, len);
}
//5)循环结束一次,关闭输入流
fis.close();
}
//6)整个循环结束,关闭输出流
fos.close();
}
}