如何在内存上创建Javascript WritableStream(如fs.creareWriteStream)

问题描述 投票:0回答:1

我尝试将一些 JS 库与 ServiceWorker 一起使用,而不访问 Node.JS 文件系统功能。原来的库导出结果也是一样的

Import * as fs from 'fs'
...
JsLib.export(result, fs.createWriteStream("res.pdf")) 

我需要相同的导出,但导出到字节数组,没有文件系统。我以同样的方式创建了数组

 const Out = (Array as any).create("byte", mysize)

如果我用测试数据手动填充这个字节数组,我的算法可以进一步正常工作。
但我不明白如何正确创建与 Node.JS 创建的相同的流,但在内存中,在我的“Out”数组中。
MDN 中有一些使用 WritableStream 的示例,但我不确定这些示例与此任务有何关系。也许有像

这样的廉价解决方案
JsLib.export(result, ...Out) 

或者这个解决方案没有模拟fs.createWriteStream?直接使用扩展语法是不可能的“扩展参数必须具有元组类型或传递给剩余参数”。但如何正确解决这个任务呢?

更新。这是对 @l3l_aze 的回答,进行了非常基本的测试,不幸的是,这个解决方案不起作用。

typescript memorystream bytebuffer
1个回答
0
投票

正如我上面所说,我不了解 TS,所以这只是 NodeJS/vanilla JS。强烈建议我花几个小时来研究这个问题,因为它可能无法正确关闭流,而且显然没有包含错误处理。

输出是 PNG 格式的红色方块。为了直观地确认测试,我复制了输出并使用 VSCode Hex Editor 扩展将其粘贴到现有的

file.png
中,并选择了 base64 选项。然后必须从我必须填充的先前数据中删除(Del,而不是 Backspace)剩余字节,以便十六进制编辑器允许粘贴。哈哈。

'use strict'

import * as PImage from 'pureimage'
import Stream from 'stream'

const width = 32
const height = 32
const img1 = PImage.make(width, height)

const ctx = img1.getContext('2d')

ctx.fillStyle = 'red'
ctx.fillRect(0, 0, width, height)

const pngData = []

const dest = new Stream()
dest.writable = true

dest.write = function (data) {
  for (let i = 0; i < data.length; i++) {
    dest.emit('data', data[i])
  }
}

// Act like a passThrough stream; in one ear and out the other.
dest.on('data', (chunk) => {
  pngData.push(chunk)
})

dest.on('end', () => {})

// For
// https://github.com/joshmarinacci/node-pureimage/blob/6775bc3dedfd4247c0ee11382e1aebdf2703ca45/src/image.ts#L57
dest.end = function () {
  dest.emit('finish')
}

dest.close = function () {
  dest.emit('close')
}

function assert (a, b) {
  if (a !== b) {
    throw new Error(`${a} !== ${b}`)
  } else {
    return true
  }
}

const buf = await PImage.encodePNGToStream(img1, dest).then(() => {
  return new Uint8Array(pngData)
})

if (assert(buf[0], 0x89) &&
    assert(buf[1], 0x50) &&
    assert(buf[2], 0x4e) &&
    assert(buf[3], 0x47)) {
  console.log('buffer contains png header')

  const ascii = Array.from(buf).map((b) => String.fromCharCode(b))
  const b64 = btoa(ascii.join(''))

  console.log(b64)
  // iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAklEQVR4AewaftIAAABBSURBVMXBAQEAAAiDMKR/5xuD7QYjJDGJSUxiEpOYxCQmMYlJTGISk5jEJCYxiUlMYhKTmMQkJjGJSUxiEpOYxB4w4wI+EhsQ6
AAAAABJRU5ErkJggg==
}
© www.soinside.com 2019 - 2024. All rights reserved.