Reputation: 13216
I am trying to go through a directory (and all it's subdirectories) and rename (move) every image if it is a .jpg
file. I think my code is correct. I am using asynchronous renaming and an incrementing counter to increase the filenames. For some reason though, in my tests with four or so subfolders only half of the images get renamed. I am not sure why this is, as I am only incrementing when the callback files (once the image has successfully been renamed) and checking the console lists every file that rename
is being called on.
var fs = require('fs');
var filePrefix = 'new_Images';
var folderName = 'changed';
var counter = 0;
function examine (path) {
fs.readdir(path, function (err, files) {
files.forEach(function (file) {
var oldPath = path + file;
fs.stat(oldPath, function (err, stats) {
if (stats.isDirectory()) {
examine(oldPath + '/');
} else {
var suffix = oldPath.substr(oldPath.length - 3);
if (suffix === 'jpg') {
fs.rename(oldPath, './' + folderName + '/' + filePrefix + counter + '.jpg', function (e) {
if (e) throw new Error('something bad happened');
console.log('Renamed a .jpg file');
console.log(oldPath);
console.log(counter);
counter++;
});
} else if (suffix === 'png') {
fs.rename(oldPath, './' + folderName + './' + filePrefix + counter + '.png', function (e) {
if (e) throw new Error('something bad happened');
console.log('Renamed a .png file');
console.log(oldPath);
console.log(counter);
counter++;
});
}
}
});
});
});
}
examine('./');
This code will log that every file was renamed, and all of the files will be removed, but only half of them are actually moved (renamed) to the new folder
Upvotes: 1
Views: 2201
Reputation: 1
This program fulfills all requirements
var fs = require('fs'),
path = require('path');
var oldPath = 'G:\\oldPath\\oldPath';
var newPath = 'G:\\newPath\\newPath\\';
var ext = 'jpg';
var newPrefix = 'newPrefix';
var myFun = function(mypath) {
fs.readdir(mypath, function(error, files) {
if (error)
console.log('error ' + error.code + ' : ' + error.message);
else {
files.map(function(file) {
return path.join(mypath, file)
}).filter(function(file) {
if(fs.statSync(file).isFile())
return file;
else
return myFun(file);
}).forEach(function(file){
var path_file = file.split('\\');
var extension = path_file[path_file.length - 1].split('.');
if (extension[1] === ext) {
var source = fs.createReadStream(file);
var target = fs.createWriteStream(newPath + newPrefix + path_file[path_file.length - 1]);
source.pipe(target);
fs.unlink(file);
}
})
}
})
}
Upvotes: 0
Reputation: 1547
I'm guessing that the files are being over written.
Since asynchronous calls are made while renaming you should increment counter
before making asynchronous call rather than after successful renaming. Since there is no order in asynchronous calls, chances are half of the calls are made before any successful rename operation with the same name.
You can verify this by logging the file name:
if (suffix === 'jpg') {
console.log('renaming with file name ' + filePrefix + counter + '.jpg');
fs.rename(oldPath, './' + folderName + '/' + filePrefix + counter + '.jpg', function (e) {
...
});
} else if (suffix === 'png') {
console.log('renaming with file name ' + filePrefix + counter + '.png');
fs.rename(oldPath, './' + folderName + './' + filePrefix + counter + '.png', function (e) {
...
});
}
Upvotes: 3