将存储在内存中的string传递给pdftotext,antiword,catdoc等

是否有可能调用CLI工具,如pdftotext,antiword,catdoc(文本提取脚本)传递string而不是文件?

目前,我阅读PDF文件与child_process.spawn调用pdftotext。 我产生一个新的进程,并将结果存储在一个新的variables。 一切工作正常。

我想从fs.readFile而不是文件本身传递binary文件:

 fs.readFile('./my.pdf', (error, binary) => { // Call pdftotext with child_process.spawn passing the binary. let event = child_process.spawn('pdftotext', [ // Args here! ]); }); 

我怎样才能做到这一点?

如果命令可以处理pipe道input,这是绝对有可能的。

spawn返回一个ChildProcess对象,你可以通过写入它的stdin把内存中的string(或二进制)传递给它。 应该先将string转换为ReadableStream ,然后通过pipe将string写入CLI的stdin

createReadStream从文件创build一个ReadableStream 。

下面的例子下载一个pdf文件,并将内容传送到pdftotext ,然后显示结果的前几个字节。

 const source = 'http://static.googleusercontent.com/media/research.google.com/en//archive/gfs-sosp2003.pdf' const http = require('http') const spawn = require('child_process').spawn download(source).then(pdftotext) .then(result => console.log(result.slice(0, 77))) function download(url) { return new Promise(resolve => http.get(url, resolve)) } function pdftotext(binaryStream) { //read input from stdin and write to stdout const command = spawn('pdftotext', ['-', '-']) binaryStream.pipe(command.stdin) return new Promise(resolve => { const result = [] command.stdout.on('data', chunk => result.push(chunk.toString())) command.stdout.on('end', () => resolve(result.join(''))) }) } 

对于CLI没有select从stdin读取,您可以使用命名pipe道 。

编辑:使用命名pipe道添加另一个示例。

一旦创build了命名pipe道,您可以像使用文件一样使用它们。 以下示例创build临时命名pipe道来发送input并获取输出,并显示结果的前几个字节。

 const fs = require('fs') const spawn = require('child_process').spawn pipeCommand({ name: 'wvText', input: fs.createReadStream('document.doc'), }).then(result => console.log(result.slice(0, 77))) function createPipe(name) { return new Promise(resolve => spawn('mkfifo', [name]).on('exit', () => resolve())) } function pipeCommand({name, input}) { const inpipe = 'input.pipe' const outpipe = 'output.pipe' return Promise.all([inpipe, outpipe].map(createPipe)).then(() => { const result = [] fs.createReadStream(outpipe) .on('data', chunk => result.push(chunk.toString())) .on('error', console.log) const command = spawn(name, [inpipe, outpipe]).on('error', console.log) input.pipe(fs.createWriteStream(inpipe).on('error', console.log)) return new Promise(resolve => command.on('exit', () => { [inpipe, outpipe].forEach(name => fs.unlink(name)) resolve(result.join('')) })) }) }