vue-upload-component icon indicating copy to clipboard operation
vue-upload-component copied to clipboard

why, File is corrupt after chunk file?

Open fathan opened this issue 5 years ago • 2 comments

by the way, your plugin is very cool....

I'm using server side backend with Node.js + Express.js. i find a problem in my code. when uploading the file to server. process chunk is completed and file stored to my directory. but, when i open the file. my file is corrupt and not opened!!

and there is message: The file “742e3292-c849-4803-aa36-c75c89c2fa5e.psd” could not be opened. It may be damaged or use a file format that Preview doesn’t recognize.

my code node express is:

import models from '../../models/index';
import multer from 'multer';
import fs from 'fs';
import rimraf from 'rimraf';
import { uuid } from 'uuidv4';
import merge from 'merge-files';

const chunk = (req, res, next) => {
  const tmpDir = __dirname + '/../../tmp';
  const uploadDir = __dirname + '/../../uploads';

  if (req.body.phase === 'start') {
    const session_id = uuid();
    const max_size = 1 * 1024 * 1024;

    rimraf.sync(`${tmpDir}/${session_id}`);
    fs.mkdirSync(`${tmpDir}/${session_id}`);

    return res.send({
      data: {
        end_offset: max_size,
        session_id
      },
      status: "success"
    });
  }

  if (req.body.phase === 'upload') {
    if (!req.files || Object.keys(req.files).length === 0) {
      res.status(400).send('No files were uploaded.');
      return;
    }
    if (!req.body.session_id) {
      res.status(400).send('Invalid session_id.');
      return;
    }

    const uploadPath = `${tmpDir}/${req.body.session_id}/${req.body.start_offset}.part`;
    console.log(uploadPath);
    req.files.chunk.mv(uploadPath, (err) => {
      return res.send({
        status: "success"
      });
    });
  }

  if (req.body.phase === 'finish') {
    let files = fs.readdirSync(`${tmpDir}/${req.body.session_id}`);
    let uploaded = files.filter(name => name.indexOf(".part")>0).sort((x, y) => {
      return (parseInt(x) < parseInt(y)) ? 1 : -1
    }).map(name => `${tmpDir}/${req.body.session_id}/${name}`);

    console.log(uploaded);

    merge(uploaded, `${uploadDir}/${req.body.session_id}.psd`).then(e => {
      rimraf.sync(`${tmpDir}/${req.body.session_id}`)
      return res.send({
        status: "success",
        file: `${req.body.session_id}.psd`
      });
    })
  }
};

i wonder if you can't help me @lian-yue ?

fathan avatar Apr 18 '20 11:04 fathan

Hi @fathan ,

Greetings!! Did you figure this out, I too am dealing with the same problem.

Thanks. BR

Nithinbs18 avatar Dec 09 '20 14:12 Nithinbs18

I figured it out the sorting order was wrong that caused the files to merge incorrectly;

if somebody faces the same issue please use the below snippet;

if (req.body.phase === 'finish') {
    let files = fs.readdirSync(`${tmpDir}/${req.body.session_id}`);
    let uploaded = files.filter(name => name.indexOf(".part")>0).sort((x, y) => {
      return (parseInt(x) < parseInt(y)) ? 1 : -1
    }).map(name => `${tmpDir}/${req.body.session_id}/${name}`);

    console.log(uploaded);

    merge(uploaded, `${uploadDir}/${req.body.session_id}.psd`).then(e => {
      rimraf.sync(`${tmpDir}/${req.body.session_id}`)
      return res.send({
        status: "success",
        file: `${req.body.session_id}.psd`
      });
    })
  }

Nithinbs18 avatar Dec 10 '20 21:12 Nithinbs18