断点续传文件

总的步骤:

1.上传注册:检查文件是否上传,已上传则直接返回,检查文件上传路径是否存在,不存在则创建
2.分块检查:检查分块文件是否上传,已上传则返回true,未上传则检查上传路径是否存在,不存在则创建.
3.分块上传:将分块文件上传到指定的路径.
4.合并分块:将所有分块文件合并为一个文件,在数据库记录文件信息.
相关知识点:
1.new File的相关知识点:new File():既可以创建文件,又可以创建目录。但切记文件对象创建后,指定的文件或目录不一定物理上存在 。
2.RandomAccessFile类的详解

  • 因为RandomAccessFile可以自由访问文件的任意位置,所以如果我们希望只访问文件的部分内容,那就可以使用RandomAccessFile类,中的seek方法指定插入的位置。

3.FileInputstream相关知识点: FileInputStream流被称为文件字节输入流,意思指对文件数据以字节的形式进行读取操作如读取图片视频等

  • InputStream不可以读取文件,它是一个Abstract的类,根本不可能实例化,是所有输入流的基类。而FileInputStream是InputStream的一个实现类,用于读取诸如图像数据之类的原始字节流。要读取字符流,请考虑使用 FileReader。

1.上传注册:

//mkdirs:对当前文件夹的字符串创建文件,创建多级目录。
    //exists:判断文件是否存在。
    public ResponseResult register(String fileMd5, String fileName, Long fileSize, String mimetype, String fileExt) {
        String fileFloadPath = this.getFileFloadPath(fileMd5);
        String filePath = this.getFilePath(fileMd5, fileExt);
        File file = new File(filePath);
        boolean exists = file.exists();

        Optional<MediaFile> optional = mediaFileRepository.findById(fileMd5);
        if(exists&& optional.isPresent()){
            //文件存在
            ExceptionCast.cast(MediaCode.UPLOAD_FILE_REGISTER_EXIST);
        }
        File fileFolder = new File(fileFloadPath);
        if(!fileFolder.exists()){
            fileFolder.mkdirs();
        }

        return new ResponseResult(CommonCode.SUCCESS);

    }

2.分块检查

 public CheckChunkResult checkchunk(String fileMd5, Integer chunk, Integer chunkSize) {
        String chunkFileFloadPath = getChunkFileFloadPath(fileMd5);
        File chunkFile= new File(chunkFileFloadPath+chunk);
        if(chunkFile.exists()){
            return new CheckChunkResult(CommonCode.SUCCESS,true);
        }else{
            //块文件不存在
            return new CheckChunkResult(CommonCode.SUCCESS,false);
        }

    }

3.上传分块

//上传分块
    public ResponseResult uploadchunk(MultipartFile file, String fileMd5, Integer chunk) {
        //检查分块目录,如果不存在则要自动创建
        //得到分块目录
        String chunkFileFloadPath = getChunkFileFloadPath(fileMd5);
        //得到分块文件路径
        String chunkFilePath=chunkFileFloadPath+chunk;
        File chunkFileFolder = new File(chunkFileFloadPath);
        //如果不存在则要自动创建
        if(!chunkFileFolder.exists()){
            chunkFileFolder.mkdirs();
        }
        InputStream inputStream=null;
        FileOutputStream fileOutputStream =null;
        try {
             inputStream = file.getInputStream();
             fileOutputStream = new FileOutputStream(new File(chunkFilePath));
            IOUtils.copy(inputStream,fileOutputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return new ResponseResult(CommonCode.SUCCESS);
    }

4.合并分块

//合并分块
    public ResponseResult mergechunks(String fileMd5, String fileName, Long fileSize, String mimetype, String fileExt) {
        //1、合并所有分块
        //得到分块文件的属目录
        String chunkFileFloadPath = getChunkFileFloadPath(fileMd5);
        File chunkFileFload = new File(chunkFileFloadPath);
        File[] fileArray = chunkFileFload.listFiles();

        List<File> fileList = Arrays.asList(fileArray);
        //创建合并的文件
        String filePath = getFilePath(fileMd5, fileExt);
        File mergeFile = new File(filePath);

        //执行合并
        mergeFile= mergeFile(fileList, mergeFile);
        if(mergeFile==null){
            //合并文件失败
            ExceptionCast.cast(MediaCode.MERGE_FILE_FAIL);
        }
        //2、校验文件的md5值是否和前端传入的md5一样
        boolean checkFileMd5 = checkFileMd5(mergeFile, fileMd5);
        if(!checkFileMd5){
            //校验文件失败
            ExceptionCast.cast(MediaCode.MERGE_FILE_CHECKFAIL);
        }
        //3、将文件的信息写入mongodb
        MediaFile mediaFile = new MediaFile();
        mediaFile.setFileId(fileMd5);
        mediaFile.setFileOriginalName(fileName);
        mediaFile.setFileName(fileMd5 + "." +fileExt);
        //文件路径保存相对路径
        String filePath1 = fileMd5.substring(0,1) + "/" + fileMd5.substring(1,2) + "/" + fileMd5 + "/";
        mediaFile.setFilePath(filePath1);
        mediaFile.setFileSize(fileSize);
        mediaFile.setUploadTime(new Date());
        mediaFile.setMimeType(mimetype);
        mediaFile.setFileType(fileExt);
        //状态为上传成功
        mediaFile.setFileStatus("301002");
        mediaFileRepository.save(mediaFile);
        return new ResponseResult(CommonCode.SUCCESS);
    }

其中

 //合并文件
    private File mergeFile(List<File> fileList,File mergeFile){
        Collections.sort(fileList, new Comparator<File>() {
            @Override
            public int compare(File o1, File o2) {
                if(Integer.parseInt(o1.getName())>Integer.parseInt(o2.getName())){
                    return 1;
                }
                return -1;
            }
        });
        try {
            byte[] b = new byte[1024];
            RandomAccessFile raf_write = new RandomAccessFile(mergeFile, "rw");
            for(File chunkFile:fileList){
                int len =-1;
                RandomAccessFile raf_read = new RandomAccessFile(chunkFile, "r");
                while((len=raf_read.read(b))!=-1){
                    raf_write.write(b,0,len);
                }
                raf_read.close();
            }
            raf_write.close();
            return mergeFile;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值