Прерывистая ошибка EPERM в папке переименования - PullRequest
1 голос
/ 18 апреля 2019

Я использую Multer для загрузки изображений в моем фс.Multer не позволяет вам динамически устанавливать позицию в fs, поэтому я всегда загружаю в одну и ту же папку, а затем меняю имя папки с помощью fs.renamesynch.Я использую синхронизирующую версию, потому что думаю, что мне нужно дождаться окончания задачи, в противном случае у меня будут проблемы в следующей задаче, которые требуют синхронизации с функцией переименования.Однако, у меня периодически возникают ошибки, и я не знаю, как их решить.Вот мой код:

router.post("/changeprofile", ensureAuthenticated, (req, res) => {
  upload(req, res, err => {
    if (err) {
      res.render("changeprofile", { msg: err });
    } else {
      if (req.file == undefined) {
        res.render("changeprofile", { msg: "Error: No file Selected!" });
      } else {
        res.render("changeprofile", {
          msg: "File Uploaded!",
          file: `uploads/${req.file.filename}`
        });
        fsextra.removeSync("./public/profile" + id);
        if (err) console.log(err);
        else console.log("Deleted old folder");
        glob("./public/uploads/profile.*", (err, matches) => {
          if (err) console.log(err);
          else {
            console.log("renaming folder...");
            fs.renameSync("./public/uploads", "./public/profile/" + id);
            if (err) console.log(err);
            else {
              fs.mkdir("./public/uploads", err => {
                if (err) console.log(err);
                else
                  console.log(
                    "------------------FOLDER RECREATED---------------------------"
                  );
              });
            }
          }
        });
      }
    }
  });
});



Вот ошибка, которую я получаю:Ошибка: EPERM: операция не разрешена, переименуйте «./public/uploads» -> «./public/profile/21» в Object.renameSync (fs.js: 593: 3) в glob (C: \ Users \ Andrea \Рабочий стол \ LinkedinLikeSocialNetwork \ rout \ users.js: 558: 19) в f (C: \ Users \ Andrea \ Desktop \ LinkedinLikeSocialNetwork \ node_modules \ once \ once.js: 25: 25) в Glob.(C: \ Users \ Andrea \ Desktop \ LinkedinLikeSocialNetwork \ node_modules \ glob \ glob.js: 151: 7) на Glob.emit (events.js: 189: 13) на Glob._finish (C: \ Users \ Andrea \ Desktop\ LinkedinLikeSocialNetwork \ node_modules \ glob \ glob.js: 197: 8) at done (C: \ Users \ Andrea \ Desktop \ LinkedinLikeSocialNetwork \ node_modules \ glob \ glob.js: 182: 14) в Glob._processReaddir2 (C: \ Users)\ Andrea \ Desktop \ LinkedinLikeSocialNetwork \ node_modules \ glob \ glob.js: 434: 12) в C: \ Users \ Andrea \ Desktop \ LinkedinLikeSocialNetwork \ node_modules \ glob \ glob.js: 371: 17 в RES (C: \ Users \Andrea \ Desktop \ LinkedinLikeSocialNetwork \ node_modules \ inflight \ inflight.js: 31: 16) по адресу f (C: \ Users \ Andrea \ Desktop \ LinkedinLikeSocialNetwork \ node_modules \ once \ once.js: 25: 25) в Glob._readdirEntries (C: \ Users \ Andrea \ Desktop \ LinkedinLikeSocialNetwork \ node_modules \ glob \ glob.js: 578: 10) в C: \ Users \ Andrea \ Desktop \ LinkedinLikeSocialNetwork \ node_modules \ glob \ glob.js: 555: 12 на ходу $ readdir $cb (C: \ Users \ Andrea \ Desktop \ LinkedinLikeSocialNetwork \ node_modules \ graceful-fs \ graceful-fs.js: 162:14) на FSReqWrap.args [как незавершенное] (fs.js: 140: 20)

1 Ответ

0 голосов
/ 18 апреля 2019

Даже если я не получил ответа, я думаю, что пришел к решению: Я думаю, что проблема заключается в этом. Когда вы используете метод синхронизации, вы, вероятно, думаете, что узел будет синхронизироваться также с операционной системой при удалении и переименовании вашей папки в файловой системе. Но похоже, что это не так: он будет вызывать операционную систему с некоторой функцией ядра, но тогда управление fs осуществляется с помощью os, и узел не ожидает возврата функции, даже если вы используете синхронный Режим. Например, может случиться так, что все операции ввода-вывода будут буферизованы, а затем выполнены все вместе, чтобы улучшить производительность операционной системы. Правильно было бы очистить кэши os после того, как вы выполнили операцию fs. Однако, используя fs-extra и graceful-fs, я думаю, что теперь он работает:




var fs = require("graceful-fs");
const fsextra = require("fs-extra");
fs.gracefulify(realfs);

router.post("/changeprofile", ensureAuthenticated, (req, res) => {
  upload(req, res, err => {
    if (err) {
      res.render("changeprofile", { msg: err });
    } else {
      if (req.file == undefined) {
        res.render("changeprofile", { msg: "Error: No file Selected!" });
      } else {
        res.render("changeprofile", {
          msg: "File Uploaded!",
          file: `uploads/${req.file.filename}`
        });
        var path = "./public/profile/" + id;
        if (fsextra.existsSync(path)){
          fsextra.removeSync(path);
        }
        if (err) console.log(err);
        else console.log("Deleted old folder");
        glob("./public/uploads/profile.*", (err, matches) => {
          if (err) console.log(err);
          else {
            console.log("renaming folder...");
            fs.renameSync("./public/uploads", "./public/profile/" + id);
            if (err) console.log(err);
            else {
              fs.mkdir("./public/uploads", err => {
                if (err) console.log(err);
                else
                  console.log(
                    "------------------FOLDER RECREATED---------------------------"
                  );
              });
            }
          }
        });
      }
    }
  });
});














...