使用 node.js 在 2 个目录之间匹配和写入数据

Posted

技术标签:

【中文标题】使用 node.js 在 2 个目录之间匹配和写入数据【英文标题】:Matching and writing data between 2 directories with node.js 【发布时间】:2016-10-12 01:08:17 【问题描述】:

所以我会尽量让这听起来尽可能简单,因为有时我什至不明白我在做什么。

基本上我有两个目录,为了这个例子,我们称它们为“a”和“b”。 'a' 是一个目录,里面有其他目录(里面是文件)。 'b' 本身就是一个目录,其中包含包含数据的文件。

我基本上需要匹配a和b的文件,将b的数据写入a。

这是我的示例代码,它不是最好的,因为我非常困惑,我试图让它尽可能简单阅读

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:除了移动文件,它只需要复制某些文件。目录 a 可以有文件 a、b、c。目录 b 可以有 a,b,d。 因此只有 a 和 b 被复制,文件 d 被单独留下。

【问题讨论】:

Copy folder recursively in node.js的可能重复 【参考方案1】:

如果这只是您想做的事情,a duplicate question in the comments 的 posit labs 建议可能是明智的。评分最高的答案建议使用 ncp 包。

假设你是来学习的,但是......

目标是一个函数

    获取源目录和目标目录 枚举内容 将文件从源复制到目标 在目标中创建所有源目录并在每个目录对上递归调用自身

注意:此解决方案非常只是一个演示,不应在生产中使用。如果文件系统非常深,递归的使用可能会受到影响,但代码都是同步的(*Sync)这一事实确实会减慢速度。

使用path module 代替字符串构建路径。它处理跨平台和奇怪的输入和边缘情况。

首先,两个辅助函数:确保目录存在于它们应该存在的位置,以及将文件从一个路径复制到另一个路径。最终,它们完成了镜像两个目录的两项实际任务。

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

然后是主要工作。确保目录存在并读取内容。

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

然后对于源目录中的每个元素

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

快速检查它是否已经存在(仅按名称。对于实际工作,您应该检查类型和校验和)

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

收集有关此目标的信息 (fs.Stats are detailed in the manual)

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

最后,根据类型执行正确的操作。复制文件,确保目录存在并递归调用,其他任何事情都会导致程序耸耸肩并继续前进。

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

完整的解决方案

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://***.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')
)

【讨论】:

以上是关于使用 node.js 在 2 个目录之间匹配和写入数据的主要内容,如果未能解决你的问题,请参考以下文章

在 Node.js 中写入文件时创建目录

Node 读取 + 写入 + 路径问题

使用 Redis 在 PHP 和 socket.io/node.js 之间进行通信

在 Node.js 和 Vue.js 之间共享 TypeScript 代码

Node.js——fs模块(文件系统),创建删除目录(文件),读取写入文件流

在macOS上写入Node.js中的〜/ Documents文件夹?