【问题标题】:Error: EXDEV: cross-device link not permitted, rename '/tmp/ on Ubuntu 16.04 LTS错误:EXDEV:不允许跨设备链接,在 Ubuntu 16.04 LTS 上重命名“/tmp/”
【发布时间】:2016-05-11 05:19:50
【问题描述】:

我在上传文件 nodejs 时遇到问题。我读过了 stack1stack2。但我认为这种不同的情况 在这样的终端输出上:

> 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)

我的代码:

  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;
      }

代码在另一个发行版上工作,比如基本操作系统,但是当我在 debian jessie 或 ubuntu 16 LTS 上运行项目时,终端上会出现错误。

任何身体都无法帮助?该代码在基本操作系统和拱门上完美运行。

【问题讨论】:

  • 您链接到的两个问题都是由完全相同的问题引起的(您无法跨文件系统/分区重命名文件)。您应该尝试查看是否可以将上传中间件配置为使用同一文件系统上的临时目录作为文件的最终位置。这可能适用于其他发行版的原因是有些发行版不会为 /tmp 创建单独的分区。

标签: node.js postgresql ubuntu-16.04 cross-device


【解决方案1】:

同样的问题。解决方法:读取临时文件,将文件写入新位置并删除临时文件:

        // 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!');
            });
        });

【讨论】:

  • 像魅力一样工作。谢谢。
【解决方案2】:

您可以使用“mv”包来解决此问题 链接 NPM:https://www.npmjs.com/package/mv 使用方法:

用 fs.rename 替换一些旧代码:

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

与:

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

【讨论】:

  • 我一直在使用 fs.rename 和 Docker 卷绑定将上传的文件从 /tmp 复制到 /app/uploads 目录。这样就完美解决了问题。
【解决方案3】:

它在使用 nodejs 时帮助了我,概念应该是相同的https://stackoverflow.com/a/43206506/7878987

【讨论】:

  • 请在您的仅链接答案中添加一些上下文!
【解决方案4】:
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); 

【讨论】:

    【解决方案5】:

    为了解决这个问题,可以改写为:

    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);
    

    对于多个文件,您可以根据文件长度迭代此块。

    【讨论】:

      【解决方案6】:
      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);
      

      【讨论】:

      • 请考虑为您的答案添加一些解释。 OP 将从中学到更多,而不仅仅是复制粘贴正确的解决方案。
      【解决方案7】:

      你必须使用 fs.writeFileSync 否则可以在复制之前删除旧文件

      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!');
      });
      

      【讨论】:

        【解决方案8】:

        当您的临时文件夹位于不同的驱动器且节点代码位于不同的驱动器时,会出现此问题。

        它会抛出这个错误。

        解决方案在另一个 StackOverflow 问题中。

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

        这篇文章的解决方案:

        根据新的NodeJS,解决方案是不要移动,复制它

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

        我的 windows 11 在 SSD 中,我的代码在 HDD 中。上传的图像将下载到 Windows 驱动器中,我正在尝试将其移动到硬盘。

        【讨论】:

          【解决方案9】:

          在我的情况下,它在同一磁盘(驱动器)路径中工作意味着在 c:/ 中,如果新路径磁盘驱动器与临时路径磁盘驱动器不同,则会发生错误。

          【讨论】:

            【解决方案10】:

            是的,你可以解决这个问题。

            1. 通过命令安装mv

              npm install mv --save
              
            2. 在你的 nodejs 文件中添加 mv

              var mv = require('mv');
              
            3. 将文件移动为:

              mv('source_file', 'destination_file,' function(err) {
                  if (err) { throw err; }
              console.log('file moved successfully');
              };
              

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2017-08-29
              • 2021-02-09
              • 1970-01-01
              • 2014-01-31
              • 1970-01-01
              • 1970-01-01
              • 2014-08-12
              相关资源
              最近更新 更多