0

我正在使用 JavaScript 文件系统访问 API 将可读流的输出流式传输到FileSystemWritableFileStream. 我创建了一个可写流包装器来使用该writeStream.pipeTo(readStream)方法,但是在使用手动读取ReadableStream和写入FileSystemWritableFileStream. 我跳过使用的标头,seek因为它包含文件大小,然后开始写入数据。这是代码:

function fileWritableStreamToWritableStream(fileStream, headerWriteMethod, headerLengthBytes) {
  let writer = fileStream;
  let bytesWritten = 0;
  const writableStream = new WritableStream({
    // Implement the sink
    async start(controller) {
      if(headerLengthBytes) {
        // returns a promise that resolves when the writer is ready for another operation
        return writer.seek(headerLengthBytes);
      }
    },
    async write(chunk) {
      bytesWritten += chunk.length;
      // returns a promise that resolves when the writer is ready for another operation
      return writer.write({ type: 'write', data: chunk });
    },
    async close() {
      let promise = Promise.resolve();
      if(headerWriteMethod) {
          let headerBuffer = new ArrayBuffer(headerLengthBytes);
          let view = new DataView(headerBuffer);
          let headerBytes = headerWriteMethod(view, bytesWritten);
          promise = writer.seek(0)
            .then(() => writer.write({type: 'write', data: headerBytes.buffer }));
      }
      return promise.then(() => writer.close());
    }
  });
  return writableStream;
}

这在其他地方使用,如下所示:

audioStream.pipeTo(writableStream);

一旦我开始写作,我就会在控制台中收到以下错误:

Errors: Uncaught (in promise) TypeError: Failed to execute 'write' on
'UnderlyingSinkBase': required member type is undefined.
        wav-recording.service.js:262 Uncaught TypeError: Failed to execute 'enqueue' on 'ReadableStreamDefaultController': Cannot enqueue a chunk into a closed readable stream
            at MessagePort.port.onmessage
4

1 回答 1

1

事实证明,由于错误而关闭了流:文件系统访问 API 当前不支持超出文件末尾的查找。解决方案是用来truncate调整文件大小:

async start(controller) {
  if(headerLengthBytes) {
    //this call will resize the file to headerLengthBytes so that seek doesn't go past the end of the file.
    await writer.truncate(headerLengthBytes);
    return writer.seek(headerLengthBytes);
  }
}

我会注意到开发人员已经意识到了这个问题,并计划在未来解决这个问题。但是,我认为这篇文章对于由于此处特定原因以外的原因而遇到相同控制台错误的任何人都有用。

于 2021-01-22T17:34:45.647 回答