1

I have a JSON object having a key of file names and an attribute of its corresponding new name. I need to recursively search a directory to check if the file exist and then rename it using the new name attribute.

I tried following the guide here: node.js fs.readdir recursive directory search.

let newNames = {"file.txt":{"oldName":"file.txt","newName":"PREFIX_file.txt"}};
var walk = function(dir, done) {
    var results = [];
    fs.readdir(dir, function(err, list) {
      if (err) return done(err);
      var pending = list.length;
      if (!pending) return done(null, results);
      list.forEach(function(file) {
        file = path.resolve(dir, file);
        fs.stat(file, function(err, stat) {
          if (stat && stat.isDirectory()) {
            walk(file, function(err, res) {
              results = results.concat(res);
              if (!--pending) done(null, results);
            });
          } else {
            results.push(file);
            if (!--pending) done(null, results);
          }
        });
      });
    });
};

let folderPath = 'C:\\Users\\ericute';

walk(folderPath, function(err, results) {
  if (err) throw err;
  results.forEach(file => {

      let filePath = path.dirname(file);
      let newName = filesForRenaming[path.basename(file)].newName;
      fs.rename(path.resolve(file), path.resolve(filePath, newName), (err) => {
        if (err) console.log(err);
      });      
  })        
});

Executing the code above, I keep getting this error:

{[Error: ENOENT: no such file or directory, rename 'C:\Users\ericute\file.txt' -> 'C:\Users\ericute\PREFIX_file.txt']
errno: -4058,
code: 'ENOENT',
syscall: 'rename',
path: 'C:\\Users\\ericute\\file.txt',
dest: 'C:\\Users\\ericute\\PREFIX_file.txt'}

I'm absolutely sure that all files are there and since it goes through the fs.lstatSync, I am assuming that it can see the file. What am I doing wrong here?

ericute
  • 144
  • 1
  • 2
  • 15
  • Looking at the error path only you can see that your script behave strangely `path: C:\\Users\\ericute\\file.txt` (the double backslashes) – BJRINT May 30 '19 at 10:23
  • @BJPRINT, I intentionally did that to escape the backslash. I tried both escaped and unescaped ones, they produce the same error. – ericute May 30 '19 at 11:21
  • I cannot reproduce the error locally, can you provide a snippet of your "JSON Object" (the infamous `csvFilePath`) ? Though it won't solve your error you'd better use [path.format](https://nodejs.org/dist/latest-v10.x/docs/api/path.html#path_path_format_pathobject) instead of a substring to get filenames and path. Obviously working with system specific delimiter is a source of trouble and you should let node handle that, with the [path](https://nodejs.org/dist/latest-v10.x/docs/api/path.html) module (such as the `join` and `resolve` method) – BJRINT May 31 '19 at 07:58
  • @BJPRINT, the JSON object I am passing looks like `{"file.txt":"oldName":"file.txt","newName":"PREFIX_file.txt"}`. Looks like I got my question wrong. It seems that fs.rename is trying to check if PREFIX_file.txt exists in the directory and that's when the error happens. I am sure the path exists because that's where the file is to be renamed. – ericute May 31 '19 at 08:49
  • @BJPRINT, I found the reason why I kept getting an error. There were special characters in the newName! I totally dismissed that scenario which I revisited when you mentioned it. Thanks a lot, man! – ericute May 31 '19 at 12:08

1 Answers1

0

As @BJPRINT pointed out in his comment, the problem was with the names I'm using to replace the current name. The error being thrown out is misleading. Instead of telling me that there are special characters in the new filename, it was throwing ENOENT: no such file or directory error which was a pain.

ericute
  • 144
  • 1
  • 2
  • 15