断点续传1:(学成在线项目大文件分块复盘)

本文详细描述了如何使用Java中的RandomAccessFile类实现文件的分块功能,包括读取源文件、创建分块文件、并确保数据的正确写入,适用于处理大文件的高效处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     1:编写一个测试文件分块的接口

定义一个File类型的变量sourceFile接收用File类读取要分块的文件

File sourceFile=new File("D:/Download/upload-video/变形金刚视频剪辑素材.mp4");

定义一个路径存储分块后的小文件

String chunkPath="D:/Download/upload-video/chunk/";

指定分块文件的大小(此处为5M;补充:

计算机默认情况下最小的存储单位是字节(byte); 1M=1024K;1K=1024byte(字节);1byte=8bit(比特);即1024byte*1024byte=1M
分块大小:表示定义了一个 long 类型的变量 chunkSize,其值为 1024*1024*5,即 5MB。

long chunkSize=1024*1024*5;

计算将要分块文件的分块总数(

计算需要分成多少块:分块数量(必须向上取整,避免分块有小数,小数被舍去,导致文件分块丢失)

)

long chunkNum=(long)Math.ceil(sourceFile.length()*1.0/chunkSize);
建立字节数组,用于缓存从源文件读取的数据:缓冲区大小1kb
byte[] b=new byte[1024];
使用RandomAccessFile来实现快速随机访问文件,以只读方式打开源文件
        /**
         * - 构造方法:RandomAccessFile(String name, String mode),用于创建RandomAccessFile对象,其中name为文件名,mode为文件打开模式("r"表示只读,"rw"表示读写)。
         * - seek(long pos)方法:用于将文件指针移动到指定位置。
         * - read()方法:用于读取一个字节。
         * - read(byte[] b)方法:用于读取一定数量的字节到一个字节数组中。
         * - write(int b)方法:用于写入一个字节。
         * - write(byte[] b)方法:用于写入一个字节数组。
         * */
        RandomAccessFile raf_read=new RandomAccessFile(sourceFile,"r");
//        循环处理每个分块:使用for循环将待分块的文件分成多个小文件。
        for(int i=0;i<chunkNum;i++){
//            根据序号创建新的块文件:首先创建一个File对象,指向分块后的文件目录    补充:Java中有自动类型转换的机制。在这里,Java会将int类型的i自动转换为String类型,所以chunkPath+i是它是 chunkPath 和 i 的拼接结果。不会出现报错
            File file=new File(chunkPath+i);
            if (file.exists()){
//              如果块文件已经存在,先删除。然后在本地磁盘上创建该目录
                file.delete();
            }
//            创建新的块文件:创建这个分块文件(理解为只有文件名的空文件)
            boolean newFile=file.createNewFile();
            // 如果成功创建新文件,则开始向其中写入数据
            if (newFile){
//                创建一个RandomAccessFile对象raf_write,用于写入分块后的文件。
                RandomAccessFile raf_write=new RandomAccessFile(file,"rw");
                int len=-1;
//                使用while循环读取待分块的文件
                while ((len=raf_read.read(b))!=-1){
//                    将读取到的数据写入分块后的文件中
                    raf_write.write(b,0,len);
//                    直到该文件的大小达到chunkSize即1M
                    if (file.length()>=chunkSize){
                        break;
                    }
                }
                raf_write.close();
                System.out.println("完成分块"+i);
            }
        }

完整代码:
 

//    测试文件分块方法
@Test
    public void testChunk() throws IOException{
//        创建了一个名为sourceFile的文件对象,这个对象可以用于读取或操作指定的文件,这里的sourceFile对象指向本地磁盘上的待分块文件。
        File sourceFile=new File("D:/Download/upload-video/transform.mp4");
//        分块后的文件存储路径
        String chunkPath="D:/Download/upload-video/chunk/";
        File chunkFile=new File(chunkPath);
        if (!chunkFile.exists()){
//            如果文件不存在就创建这个文件
            chunkFile.mkdir();
        }
//       提示:计算机默认情况下最小的存储单位是字节(byte); 1M=1024K;1K=1024byte(字节);1byte=8bit(比特);即1024byte*1024byte=1M
//        分块大小:表示定义了一个 long 类型的变量 chunkSize,其值为 1024*1024*5,即 5MB。
        long chunkSize=1024*1024*5;
        //计算需要分成多少块:分块数量(必须向上取整,避免分块有小数,小数被舍去,导致文件分块丢失)
        //Math.ceil() 函数用于向上取整,确保结果不包含小数部分。即使在除法操作中可能会出现小数部分,取整操作也会将其向上舍入到最接近的整数。
        //强制转换为 long 确保结果是一个整数数据类型,以便在后续的计算和逻辑中使用。
        //将sourceFile.length()乘以1.0然后再除以chunkSize的目的是将除法操作的结果转换为浮点数(double),而不是整数(int)。这样做的原因是为了确保精确的浮点数除法,以避免在除法操作中截断小数部分。
        long chunkNum=(long)Math.ceil(sourceFile.length()*1.0/chunkSize);
        System.out.println("分块总数:"+chunkNum);
//      建立字节数组,用于缓存从源文件读取的数据:缓冲区大小1kb
        byte[] b=new byte[1024];
//      使用RandomAccessFile来实现快速随机访问文件,以只读方式打开源文件
        /**
         * - 构造方法:RandomAccessFile(String name, String mode),用于创建RandomAccessFile对象,其中name为文件名,mode为文件打开模式("r"表示只读,"rw"表示读写)。
         * - seek(long pos)方法:用于将文件指针移动到指定位置。
         * - read()方法:用于读取一个字节。
         * - read(byte[] b)方法:用于读取一定数量的字节到一个字节数组中。
         * - write(int b)方法:用于写入一个字节。
         * - write(byte[] b)方法:用于写入一个字节数组。
         * */
        RandomAccessFile raf_read=new RandomAccessFile(sourceFile,"r");
//        循环处理每个分块:使用for循环将待分块的文件分成多个小文件。
        for(int i=0;i<chunkNum;i++){
//            根据序号创建新的块文件:首先创建一个File对象,
//            补充:Java中有自动类型转换的机制。在这里,Java会将int类型的i自动转换为String类型,所以chunkPath+i是它是 chunkPath 和 i 的拼接结果。不会出现报错
            File file=new File(chunkPath+i);
            if (file.exists()){
//              如果块文件已经存在,先删除。然后在本地磁盘上创建该目录
                file.delete();
            }
//            创建新的块文件:创建这个分块文件(理解为只有文件名的空文件)
            boolean newFile=file.createNewFile();
            // 如果成功创建新文件,则开始向其中写入数据
            if (newFile){
//                创建一个RandomAccessFile对象raf_write,用于写入分块后的文件。
                RandomAccessFile raf_write=new RandomAccessFile(file,"rw");
                int len=-1;
//                使用while循环读取待分块的文件
                while ((len=raf_read.read(b))!=-1){
//                    将读取到的数据写入分块后的文件中
                    raf_write.write(b,0,len);
//                    直到该文件的大小达到chunkSize即1M
                    if (file.length()>=chunkSize){
                        break;
                    }
                }
                raf_write.close();
                System.out.println("完成分块"+i);
            }
        }
        raf_read.close();
    }

测试结果:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值