在Nodejs中读取文件内容过长导致的ERR_STRING_TOO_LONG问题

最近想把QQ的聊天记录导出来看一下,PC QQ导出来的是MHT格式的单文件网页,聊天记录一大根本无法正常打开浏览。
于是想找个工具解决,在Github上面找到了几个脚本,但是都需要额外安装我不需要的开发环境,于是决定自己写个脚本,把MHT中的图片资源从MHT提取出来,分离为HTML和静态资源文件。这样就能解决文件太大无法打开预览的问题。
用Java写感觉有点不方便,于是选择用Nodejs来读取文件和解析。
大体思路就是先匹配文件的分隔线,然后按分隔线分割每一块,并读取每一块的头部标识,按照头部标识类型的不同进行处理。是图片类型就保存为图片文件,是HTML则保存为HTML。
写完脚本后发现使用fs.readFileSyncfse.readFileSync读取大于512M的文本文件内容并处理时,都会抛出ERR_STRING_TOO_LONG异常。

Error: Cannot create a string longer than 0x1fffffe8 characters
    at Buffer.toString (node:buffer:830:17)
    at file:///xxxxx.js:4:13
    at ModuleJob.run (node:internal/modules/esm/module_job:195:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:337:24)
    at async loadESM (node:internal/process/esm_loader:34:7)
    at async handleMainPromise (node:internal/modules/run_main:106:12) {
  code: 'ERR_STRING_TOO_LONG'
}

原因是Nodejs使用的引擎的内部限制,字符串创建时不能超过一定长度。这个值由buffer.constants.MAX_STRING_LENGTH决定。
并且在不同引擎、不同位数的操作系统下是不同的,一般就两个值0x0ffffff0(32位系统)和0x1fffffe8(64位系统) 。我在64位系统下的node v18.20.2使用fs.readFileSync读取超过512MB大小的文件就会抛出异常。

这个值是没法通过配置参数修改的

这种情况基本上出现在读取文件内容时,因此解决办法是:如果读取的文件可能比较大,使用流式读取(ReadStream)逐渐读取并解析,而不是一次性全部读取。
不使用第三方库的情况下ReadStream:

const fs = require('fs')
// 默认缓冲块highWaterMark的大小进行读取,可以在配置参数修改
const readStream = fs.createReadStream(path, { encoding: 'utf-8' })

readStream.on('data', (chunk) => {
  // 处理每次读取的数据块
  console.log(chunk.toString())
})

readStream.on('end', () => {
  console.log('文件读取完毕')
})

readStream.on('error', (err) => {
  console.error('读取文件时出错:', err)
})

如果想要按行来读取,一次读取文件的一行,需要用readline包装一下readStream

const fs = require('fs')
const readline = require('readline')

const readStream = fs.createReadStream(filePath, { encoding: 'utf8' })

const rl = readline.createInterface({
    input: readStream,
    crlfDelay: Infinity
})

// 注意 这里监听的事件是line 而不是on
readStream.on('line', (line) => {
  // 处理每次读取一行
  console.log(line)
})

// 这里的事件是close
readStream.on('close', () => {
  console.log('文件流读取关闭')
})

readStream.on('error', (err) => {
  console.error('读取文件时出错:', err)
})
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇