简体   繁体   English

无法流式传输到已取消链接的文件

[英]Unable to stream to file that was unlinked

I'm creating a system in which I need to cache a file in a short amount of time, and then delete it.我正在创建一个系统,我需要在短时间内缓存文件,然后将其删除。 I'm running into an error that if I try to cache the same deleted file after deletion, I get a permission error.我遇到了一个错误,如果我在删除后尝试缓存同一个已删除的文件,则会出现权限错误。

I have made a reproduction of my problem, and it looks like this:我已经复制了我的问题,它看起来像这样:

//@ts-check
const fs = require("fs")
const promisify = require("util").promisify
const unlink = promisify(fs.unlink)

const SOURCE = "a.txt"
const DESTINATION = "b.txt"

function init() {
  console.info("Running operation")

  const sourceStream = fs.createReadStream(SOURCE)
  const destinationStream = fs.createWriteStream(DESTINATION)

  sourceStream.on("close", async () => {
    await unlink(DESTINATION)
    init()
  })

  sourceStream.pipe(destinationStream)
}

init()

Upon running, this is what is logged to console:运行时,这是记录到控制台的内容:

Running operation
Running operation
Running operation
events.js:167
      throw er; // Unhandled 'error' event
      ^

Error: EPERM: operation not permitted, open 'D:\Projects\test\b.txt'
Emitted 'error' event at:
    at WriteStream.onerror (_stream_readable.js:690:12)
    at WriteStream.emit (events.js:182:13)
    at lazyFs.open (internal/fs/streams.js:273:12)
    at FSReqWrap.oncomplete (fs.js:141:20)

Even weirder, the amount of times it can run the same operation before throwing the error varies.更奇怪的是,在抛出错误之前它可以运行相同操作的次数各不相同。 Sometimes it'll fail after 3, sometimes after 5.有时它会在 3 后失败,有时会在 5 后失败。

So what's going on here?那么这里发生了什么?

You need to wait for the destinationStream to end before reading again.您需要等待 destinationStream 结束才能再次阅读。 Try doing this:尝试这样做:

 destinationStream.on("close", async () => {
      await unlink(DESTINATION)
      init()
 })

If I'm getting the problem right, perhaps you should look for finish event.如果我的问题是正确的,也许您应该寻找finish事件。

Change this:改变这个:

const sourceStream = fs.createReadStream(SOURCE)
const destinationStream = fs.createWriteStream(DESTINATION)

sourceStream.on("close", async () => {
  await unlink(DESTINATION)
  init()
})

sourceStream.pipe(destinationStream)

To this:对此:

const sourceStream = fs.createReadStream(SOURCE)
const destinationStream = fs.createWriteStream(DESTINATION)

sourceStream.pipe(destinationStream)
   .on('finish', async () => {
     await unlink(DESTINATION);
     console.log('Done');
     init()
   })

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM