You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么Node.js中fs.copyFileSync()复制文件得到空白文件?

根因分析

fs.createReadStream 是异步API,你绑定的readable事件回调会在事件循环的异步阶段执行,而你紧随其后写的fs.copyFileSync是同步API,会在当前同步执行栈立刻运行。
这时候流还没有完成读取,也没有把所有偏移后的ID写入FILE_PATH_TO_POST_SHIFT_IDENTIFIERS临时文件,你复制时源文件还是空的,自然得到空白的目标文件。
你交换源和目标路径后复制有内容,是因为目标路径对应的文件是你之前用fs.writeFileSync同步写完的,本身就有有效内容。

修复方法

  1. 首先每次处理前清空临时偏移ID文件,避免残留旧内容干扰
  2. 将文件复制、数据库更新、页面跳转逻辑全部放到可读流的end事件回调中,等流读取、写入完全完成后再执行后续操作

修复后的核心代码片段如下:

/* POST delete post */
router.post("/", function(req, res, next) {
    Post.findOneAndRemove({postId: sessionStorage.getItem("deleteIdentifier")}, function(err, post) {
        if (err) {
            console.log(err)
        } else {
            console.log("Removed post: " + post)
        }
    })

    // Get the file contents then find and replace identifier.
    var postIdentifiers = fileSystem.readFileSync(constantVariable.FILE_PATH_POST_IDENTIFIERS, {encoding: "utf-8"})
    var newValue = postIdentifiers.replace(sessionStorage.getItem("deleteIdentifier").toString(), "")

    // Write the replacement value to the file.
    fileSystem.writeFileSync(constantVariable.FILE_PATH_POST_IDENTIFIERS, newValue)

    // 每次先清空临时文件,避免旧内容残留
    fileSystem.writeFileSync(constantVariable.FILE_PATH_TO_POST_SHIFT_IDENTIFIERS, '')

    // Write all the contents from postIds.txt to postShiftIds.txt - 1.
    var readable = fileSystem.createReadStream(constantVariable.FILE_PATH_POST_IDENTIFIERS, {encoding: "utf-8"})

    readable.on("readable", function() {
        var id = ""
        var parsedId = 0
        var shiftedId = 0

        while ((id = readable.read(1)) !== null) {
            parsedId = parseInt(id)
            if (parsedId !== 0) {
                parsedId -= 1
                shiftedId = parsedId
            }
            // Write the shifted identifier to postShiftIds.txt - 1.
            fileSystem.appendFileSync(constantVariable.FILE_PATH_TO_POST_SHIFT_IDENTIFIERS, shiftedId.toString())
        }
    })

    // 等流读取写入完成后再执行后续逻辑
    readable.on('end', function() {
        // Copy the shifted identifiers to the original file.
        fileSystem.copyFileSync(constantVariable.FILE_PATH_TO_POST_SHIFT_IDENTIFIERS, constantVariable.FILE_PATH_POST_IDENTIFIERS)
        
        // Shift all the post identifiers down one.
        Post.find({}).exec(function(err, posts) {
            if (err) {
                console.log(err)
            } else {
                var package = {}
                posts.forEach((post) => {
                    // Dont subtract the first id.
                    if (post.postId === 0) {
                        package = {
                            postId: post.postId,
                            emailId: post.emailId,
                            postTitle: post.postTitle,
                            postMessage: post.postMessage
                        }
                    } else {
                            package = {
                            postId: post.postId - 1,
                            emailId: post.emailId,
                            postTitle: post.postTitle,
                            postMessage: post.postMessage
                        }
                    }
                    
                    Post.findOneAndUpdate({postId: post.postId}, package, {new: true}, function(err, post) {
                        if (err) {
                            console.log(err)
                        } else {
                            console.log("Shifted index: ", post)
                        }
                    })
                })
            }
        })
        
        res.redirect("allPosts")
    })
})

额外优化建议

你当前的ID读取逻辑是每次读取1个字符,仅支持个位数的postId,当postId超过9变成两位数及以上时,会把ID拆成单个字符处理导致逻辑错误。建议你将ID按行存储,读取时按换行符拆分处理,适配多位数ID的场景。

内容的提问来源于stack exchange,提问作者user15746554

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 02:45:04