文件切割和合并
文件的切割使用场景:
平时当我们向某个论坛或者某个网站上传文件的时候,如果某个网站设置一次性只能上传固定大小的文件,那么我们就会把我们的文件进行切割几份然后在上传。
还有,假设我们掌握了某个技术,准备要在网上卖电子书或者视频之类的,那么我们一般会先给用户一些体验的资料或者视频,然后客户满意,在分期给其他的部分,这种情况也涉及到文件的切割。
文件切割方式:
按照每个碎片文件的大小切割,比如2M一个来切(掌握)。
需求:切割D:\test\制服诱惑.avi。
分析:
数据源:使用一个输入流从需要被切割的文件中开始读取字节数据,每次都读取指定的字节数据,比如每次读取2M。一个avi文件,属于字节数据,应该用字节流,输入。FileInputStream。
目的地:把上述每次读取的字节数据统一写到同一个文件中,然后后面读取的数据继续写到其他的文件中。也就是说通过上述对数据源的操作最终会生成多个碎片文件。多个碎片文件,属于字节数据,用字节流,FileOutputStream。数据源每次读取2M数据,把读到的结果写出到一个碎片文件。碎片文件的名字不断变化。动态生成。用一个递增的数字表示文件名。
切割文件的思想如下图所示:
1.png
思路:
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(); } }
作者:Villain丶Cc
链接:https://www.jianshu.com/p/32736d8e3a11