如何与 node.js 流中的这个 <File> 对象交互?

Posted

技术标签:

【中文标题】如何与 node.js 流中的这个 <File> 对象交互?【英文标题】:How do I interact with this <File> object in a node.js stream? 【发布时间】:2014-04-12 18:33:18 【问题描述】:

我正在使用 gulp 构建一个 glob 匹配文件流,并将它们全部以嵌套结构移动到新位置。为此,我首先想构建一个简单的“直通”流,以查看如果我从 gulp.src() 通过管道传递给它,我会得到什么。

这是我的测试 gulpfile.js:

var through = require("through");
var fs = require("fs");

function write(file) 
  console.log(file);
  console.log(file.toString());


gulp.task("move", function () 

  return gulp.src("./**")
    .pipe(through(write));

);

如果我在命令行上运行 gulp 'move' 任务,我会得到如下输出:

<File "some/path">
[object Object]
<File "some/path/file.js" <Buffer 2f 2a 0a 0a 4f 72 67 69 6e 61 6c 20 53 74 79 6c 65 20 66 72 6f 6d 20 65 74 68 61 6e 73 63 68 6f 6f 6e 6f 76 65 72 2e 63 6f 6d 2f 73 6f 6c 61 72 69 7a 65 ...>>
[object Object]

那些对象是什么?我如何与他们互动?

【问题讨论】:

【参考方案1】:

那些是vinyl 对象。它们是通过 gulp 流传递的核心数据类型。包含有关文件的信息(例如路径信息和作为​​缓冲区或流的内容)。您可以使用gulp-debug 更好地查看数据。

如果你想移动一堆文件,同时保留它们的相对路径,你可以执行以下操作之一,无需自己挖掘代码:

gulp.src('/a/single/src/path/**/*.foo').pipe(gulp.dest('/a/single/dest/path'));

或者,如果你有一堆不同的 glob:

gulp.src(['/a/src/path/foo/**/*.foo', '/a/src/path/bar/**/*.bar'], base: '/a/src/path/')
    .pipe(gulp.dest('/a/dest/path/'));

大多数情况下,您将使用gulp plugins 来操作文件,然后将结果传递给gulp.dest(),而不是自己操作它们。

如果您需要来操作文件,有一些插件可以提供帮助:

gulp-tap 允许您在流中达到峰值,并可选择修改文件或缓冲区。 vinyl-map 让你轻松修改文件内容 如果 globbing 不起作用,gulp-filter 可以帮助您过滤流。

【讨论】:

谢谢,@OverZealous,这是正确的。出于某种原因,我从未意识到 gulp.src(glob).pipe(gulp.dest(new)) 会保留所有嵌套结构,但我今天早些时候得到了它。作为一般规则,在我了解它们的工作原理之前,我不喜欢使用插件,但这甚至不需要插件。感谢您的提示!【参考方案2】:

可以使用这个js查看文件属性:

var propValue;
for(var propName in file) 
    propValue = file[propName];
    console.log('name:' + propName, ', value:<<<',propValue,'>>>');


Sample Output
    name:history ,     value:"C:\Temp\test.txt"
    name:cwd ,         value:"C:\Temp"
    name:base ,        value:"C:\Temp"
    name:_contents ,   value: full file contents
    name:isBuffer ,    value:"function () 
    name:isStream ,    value:"function () 
    name:isNull ,      value:"function () 
    name:isDirectory , value:"function () 
    name:clone ,       value:"function (opt) 
    name:pipe ,        value:"function (stream, opt) 
    name:inspect ,     value:"function () 
    name:stat , value:<<<  dev: 0,
      mode: 33206,
      nlink: 1,
      uid: 0,
      gid: 0,
      rdev: 0,
      ino: 0,
      size: 874,
      atime: Sat Sep 19 2015 14:34:51 GMT+1000 (AUS Eastern Standard Time),
      mtime: Sat Sep 19 2015 14:34:51 GMT+1000 (AUS Eastern Standard Time),
      ctime: Sat Sep 12 2015 14:59:40 GMT+1000 (AUS Eastern Standard Time)  >>>

Usage:
console.log('file name:', file.relative);
console.log('file current working directory:', file.cwd);
console.log('file isDirectory:', file.isDirectory());

【讨论】:

【参考方案3】:

对于那些也偶然发现并不想使用 gulp 的人,我是这样做的:

假设files 是vinyl 对象的数组 -

        const outputPath = ... // some directory path

        files.forEach(file => 
            const filePath = path.join(outputPath, file.relative);
            // if its a directory then create the directory if not already present
            if (file.isDirectory()) 
              if (!fs.existsSync(filePath)) 
                fs.mkdirSync(filePath,  recursive: true );
              
             else 
              // if its a file then save the contents of the file
              fs.writeFileSync(filePath, file.contents);
            
          );

【讨论】:

以上是关于如何与 node.js 流中的这个 <File> 对象交互?的主要内容,如果未能解决你的问题,请参考以下文章

如何将二进制缓冲区解码为 node.js 中的图像?

如何在 node.js 中搜索字符串的流?

如何有效地计算文档流中的文档之间的相似性

如何在一个流中合成多个图像

Node.js中的代码AWS Lambda Package不会调用putRecord()来将数据添加到AWS Kinesis Firehose Stream中

如何将 Node.js 中的 net 模块与 browserify 一起使用?