1

So i'll try and make this sound as simple as possible, because sometimes i don't even understand what im doing.

Basically i have two directories, for the sake of this example we will call them 'a' and 'b'. 'a' is a directory with other directories inside of it(inside those are files). 'b' is a directory by itself, with files in it, that contain data.

I basically need to match the files from a and b, and write the data from b into a.

This is my example code, its not the best because im extremely confused, I tried to make this as simple as possible too read

var id = []
function match(){
    var a = fs.readdirSync(__dirname+"/x/")
    var b = fs.readdirSync(__dirname+"/y/")
    id.push(a)
    for(o in id){
        fs.readdirSync(__dirname+"/x/"+id[o])
        // this is where i got really confused, but heres an example
        if(file names in id[o] match b){
            write data from b, into id[o]
        }
    }
}
match()

edit: aside from moving files, it would only need to copy certain files. directory a could have files a,b,c. and directory b could have a,b,d. thus only a and b being copied, and file d being left alone.

Furdew
  • 63
  • 2
  • 7
  • Possible duplicate of [Copy folder recursively in node.js](http://stackoverflow.com/questions/13786160/copy-folder-recursively-in-node-js) – posit labs Jun 11 '16 at 01:55

1 Answers1

0

posit labs suggestion of a duplicate question in the comments is probably wise if this is just something you want done. The top rated answer suggests the package ncp.

Assuming you're in this to learn, however...

The objective is a function that

  1. Takes a source directory and target directory
  2. Enumerates the contents
  3. Copies files from source to target
  4. Makes all source directories in target and recursively calls itself on each directory pair

Be aware: this solution is very much a demo and should not be used in production. The use of recursion could bite if the file system is very deep, but the fact that the code is all synchronous (*Sync) can really slow this down.

Instead of string building your paths, use the path module. It handles cross platform and strange inputs and edge cases.

First, two helper functions: ensuring directories exist where they should and copying a file from one path to another. Ultimately, these do the 2 real tasks in mirroring two directories.

var ensureDirectoryExists = function(path) {
    if (fs.existsSync(path)) return;
    fs.mkdirSync(path);
}

var copyFile = function(sourceFile, targetFile) {
    if (fs.existsSync(targetFile)) return;
    fs.writeFileSync(targetFile, fs.readFileSync(sourceFile));
}

Then the main work. Ensure the directories exist and read the contents.

ensureDirectoryExists(source);
ensureDirectoryExists(target);
var sourceList = fs.readdirSync(source);
var targetList = fs.readdirSync(target);

Then for every element in the source directory

sourceList.forEach(function(sourceFile) { /* code */ })

Quickly check if it already exists (just by name. For real work, you should check types and a checksum)

if (targetList.indexOf(sourceFile) > -1) return;

Gather information on this target (fs.Stats are detailed in the manual)

var fullSourcePath = path.join(source, sourceFile);
var fullTargetPath = path.join(target, sourceFile);
var fileStats = fs.statSync(fullSourcePath);

Last, perform the correct action based on the type. Files are copied, directories are ensured to exist and the recursively called, and anything else causes the program to shrug and keep going.

if (fileStats.isFile()) {
    copyFile(fullSourcePath, fullTargetPath);
} else if (fileStats.isDirectory()) {
    copyDirectories(fullSourcePath, fullTargetPath);
} else {
    // there can be other things in the list. See https://nodejs.org/api/fs.html#fs_class_fs_stats
    console.log(`Not sure what ${sourceFile} is. Ignoring.`);
}

Complete solution

var fs = require('fs');
var path = require('path');

var ensureDirectoryExists = function(path) {
    if (fs.existsSync(path)) return;
    fs.mkdirSync(path);
}

var copyFile = function(sourceFile, targetFile) {
    // console.log(`copying from ${sourceFile} to ${targetFile}`);
    if (fs.existsSync(targetFile)) return;
    fs.writeFileSync(targetFile, fs.readFileSync(sourceFile));

    // or with streams. Note this ignores errors. Read more here: https://stackoverflow.com/questions/11293857/fastest-way-to-copy-file-in-node-js
    // fs.createReadStream(sourceFile).pipe(fs.createWriteStream(targetFile));
}

var copyDirectories = function(source, target) {
    // console.log(`copying from ${source} to ${target}`);

    // ensure the directories exist
    ensureDirectoryExists(source);
    ensureDirectoryExists(target);
    var sourceList = fs.readdirSync(source);
    var targetList = fs.readdirSync(target);

    //sourceList has the contents of the directories
    sourceList.forEach(function(sourceFile) {
        // omit this file it it already exists
        // Note that this is quite naive, but will work for demo purposes
        if (targetList.indexOf(sourceFile) > -1) return;

        var fullSourcePath = path.join(source, sourceFile);
        var fullTargetPath = path.join(target, sourceFile);
        var fileStats = fs.statSync(fullSourcePath);
        // console.log(`${sourceFile} is a ${fileStats.isFile() ? 'file' : (fileStats.isDirectory() ? 'directory' : '??')}.`);

        if (fileStats.isFile()) {
            copyFile(fullSourcePath, fullTargetPath);
        } else if (fileStats.isDirectory()) {
            copyDirectories(fullSourcePath, fullTargetPath);
        } else {
            // there can be other things in the list. See https://nodejs.org/api/fs.html#fs_class_fs_stats
            console.log(`Not sure what ${sourceFile} is. Ignoring.`);
        }
    });
}

copyDirectories(
    path.join(__dirname, 'source'),
    path.join(__dirname, 'target')
)
Community
  • 1
  • 1
user01
  • 831
  • 7
  • 13