8

I have problem upload file nodejs. i have read stack1 and stack2. but i think this different case on terminal output like this :

> Unhandled rejection Error: EXDEV: cross-device link not permitted,
> rename '/tmp/31941-53enly.png' ->
> 'public/files/complaint/Screenshot_2016-05-01_01-16-55.png'
>     at Error (native)
>     at Object.fs.renameSync (fs.js:681:18)
>     at null.<anonymous> (/home/faris/myprojects/orchestrale-server/routes/complaintimage.js:163:20)
>     at tryCatcher (/home/faris/myprojects/orchestrale-server/node_modules/sequelize/node_modules/bluebird/js/release/util.js:16:23)
>     at Promise._settlePromiseFromHandler (/home/faris/myprojects/orchestrale-server/node_modules/sequelize/node_modules/bluebird/js/release/promise.js:502:31)
>     at Promise._settlePromise (/home/faris/myprojects/orchestrale-server/node_modules/sequelize/node_modules/bluebird/js/release/promise.js:559:18)
>     at Promise._settlePromise0 (/home/faris/myprojects/orchestrale-server/node_modules/sequelize/node_modules/bluebird/js/release/promise.js:604:10)
>     at Promise._settlePromises (/home/faris/myprojects/orchestrale-server/node_modules/sequelize/node_modules/bluebird/js/release/promise.js:683:18)
>     at Async._drainQueue (/home/faris/myprojects/orchestrale-server/node_modules/sequelize/node_modules/bluebird/js/release/async.js:138:16)
>     at Async._drainQueues (/home/faris/myprojects/orchestrale-server/node_modules/sequelize/node_modules/bluebird/js/release/async.js:148:10)
>     at Immediate.Async.drainQueues [as _onImmediate] (/home/faris/myprojects/orchestrale-server/node_modules/sequelize/node_modules/bluebird/js/release/async.js:17:14)
>     at processImmediate [as _immediateCallback] (timers.js:383:17)

my code :

  if (_.isEmpty(req.files) == false) {
      var tp = avatar_folder+req.files.file.name;
      fs.renameSync(req.files.file.path, tp, function(err){});
      var avatar = req.files.file.name;
      }

code work on another distro like elementary os, but when i run project on debian jessie or ubuntu 16 LTS that error result on terminal.

any body can't help ? that code just run perfectly on elementary os and arch.

Community
  • 1
  • 1
Faris Ridho
  • 91
  • 1
  • 1
  • 4
  • Both questions you link to are caused by the exact same issue (you can't rename files across file systems/partitions). You should try and see if you can configure the upload middleware to use a temporary directory on the same file system as the final location of the files. The reason this may work on other distributions is that some won't create a separate partition for `/tmp`. – robertklep May 11 '16 at 08:38

10 Answers10

17

Same problem. Workaround: Read the temp file, write the file in new location and remove the temp file:

        // Read the file
        fs.readFile(oldpath, function (err, data) {
            if (err) throw err;
            console.log('File read!');

            // Write the file
            fs.writeFile(newpath, data, function (err) {
                if (err) throw err;
                res.write('File uploaded and moved!');
                res.end();
                console.log('File written!');
            });

            // Delete the file
            fs.unlink(oldpath, function (err) {
                if (err) throw err;
                console.log('File deleted!');
            });
        });
framontb
  • 760
  • 10
  • 28
6

You can use 'mv' packgage to resolve this issue Link NPM: https://www.npmjs.com/package/mv How to use:

Replace some old code with fs.rename:

    fs.rename(temp_path, target_path, (err) => {
        if (err) {
            console.log('> FileServer.jsx | route: "/files/upload" | err:', err);
            throw err;
        }
    });

With:

    const mv = require('mv');
    mv(temp_path, target_path, function (err) {
        if (err) {
            console.log('> FileServer.jsx | route: "/files/upload" | err:', err);
            throw err;
        }
    });
VnDevil
  • 1,167
  • 13
  • 13
  • I've been using `fs.rename` with Docker volume bind to copy the uploaded file from `/tmp` to `/app/uploads` directory. This is perfectly solved the problem. – Renjith Mar 20 '21 at 10:40
1

it assisted me when working with nodejs , the concept should be the same https://stackoverflow.com/a/43206506/7878987

1
var http = require('http');
var formidable = require('formidable');
var fs = require('fs');
var mv = require('mv');

http.createServer(function (req, res) {
  if (req.url == '/fileupload') {
    var form = new formidable.IncomingForm();
    form.parse(req, function (err, fields, files) {
      var oldpath = files.filetoupload.path;
     console.log(oldpath);
      var newpath = 'F:/change path to your project dir/' + files.filetoupload.name;
      mv(oldpath, newpath, function (err) {
        if (err) throw err;
        res.write('File uploaded and moved!');
        res.end();
      });
 });
  } else {
    res.writeHead(200, {'Content-Type': 'text/html'});
    res.write('<form action="fileupload" method="post" enctype="multipart/form-data">');
    res.write('<input type="file" name="filetoupload"><br>');
    res.write('<input type="submit">');
    res.write('</form>');
    return res.end();
  }enter code here
}).listen(8080); 
Vijay Kumar
  • 81
  • 1
  • 12
0

In order to resolve this problem, you can rewrite as:

fs.writeFile(path_where_to_write, file, function(err) {
    if (err) throw err; /*do something else.*/
});
/*and then Remove the file from tmp location*/
fs.unlink(tempPath);

and for multiple files, you could iterate this block based on length of files.

nityanarayan44
  • 348
  • 4
  • 10
0
var http = require('http');
var formidable = require('formidable');
var fs = require('fs');

http.createServer(function (req, res) {
if (req.url == '/fileupload') {
var form = new formidable.IncomingForm();
form.parse(req, function (err, fields, files) {
var oldpath = files.filetoupload.path;
console.log(oldpath);
var newpath = 'F:/your folder name/' + files.filetoupload.name;
fs.readFile(oldpath, function (err, data) {
if (err) throw err;
console.log('File read!');

// Write the file
fs.writeFile(newpath, data, function (err) {
if (err) throw err;
res.write('File uploaded and moved!');
res.end();
console.log('File written!');
});

// Delete the file
fs.unlink(oldpath, function (err) {
if (err) throw err;
console.log('File deleted!');
});
});
});
} else {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write('<form action="fileupload" method="post" enctype="multipart/form- 
data">');
res.write('<input type="file" name="filetoupload"><br>');
res.write('<input type="submit">');
res.write('</form>');
return res.end();
}
}).listen(8080);
  • Please consider adding some explanation to your answer. OP will learn much more from that than just copy-pasting the correct solution. – ViG Mar 29 '18 at 11:33
0

You have to use fs.writeFileSync otherwise oldfile can be deleted before copied

fs.writeFileSync(newpath, data, function (err) {
    if (err) throw err;
    res.write('File uploaded and moved!');
    res.end();
    console.log('File written!');
});

// Delete the file
fs.unlink(oldpath, function (err) {
    if (err) throw err;
    console.log('File deleted!');
});
Community
  • 1
  • 1
0

This issue occurs when your temp folder is in a different drive and Node code is in a different drive.

It will throw this error.

Solution is in another StackOverflow question .

What does the "EXDEV: cross-device link not permitted" error mean?

solution from this post :

As per the new NodeJS, the solution is don`t move, copy it

fs.copyFileSync(oldpath, newpath);
fs.unlink(oldpath,()=>{});

My windows 11 is in SSD and my Codes are in HDD. The uploaded image will be downloaded in windows drive and I am trying to move it to HDD.

0

In my case, Its working within same disc(drive) path means within c:/ , Error occurred if new path disk drive is different from temp path disk drive.

N.S
  • 139
  • 1
  • 1
  • 12
-1

yes, you can resole this problem as.

  1. install mv by command

    npm install mv --save
    
  2. add mv in your nodejs file

    var mv = require('mv');
    
  3. move file as:

    mv('source_file', 'destination_file,' function(err) {
        if (err) { throw err; }
    console.log('file moved successfully');
    };
    
Pini Cheyni
  • 4,496
  • 2
  • 37
  • 52