JavaScript使用js-car读取CAR文件报unexpected end of file错误
问题原因
你的代码存在两处明确错误,直接导致传入js-car的字节数据无效/不完整,触发unexpected end of the file报错:
- 字节读取写法存在变量引用错误:你已经通过
await files[0].arrayBuffer()拿到了文件对应的ArrayBuffer,构造Uint8Array时却传入了未定义的carFile变量,完全没有使用上一行读取到的arrayBuffer。此时生成的字节数组长度为0,自然会被判定为文件截断。
对应错误代码:let arrayBuffer = await files[0].arrayBuffer(); let bytes=new Uint8Array(carFile); // carFile未定义,未传入正确的arrayBuffer - 流读取写法传参类型不匹配:浏览器环境下
File.stream()返回的是Web标准ReadableStream,并非Node.jsfs.createReadStream那种默认实现了异步迭代接口的对象,直接传入fromIterable时库无法遍历读取完整字节内容,同样会触发文件意外结束的错误。
Node.js环境下代码能正常运行,已经说明你的CAR文件本身没有损坏,问题完全出在浏览器端的传参逻辑上。
修复方法
优先使用fromBytes方案(浏览器端兼容性最好,逻辑最简单)
修正Uint8Array构造时的入参,传入正确读取到的ArrayBuffer即可:
// 读取文件为ArrayBuffer const arrayBuffer = await files[0].arrayBuffer(); // 基于正确的ArrayBuffer构造字节数组 const bytes = new Uint8Array(arrayBuffer); // 传入完整字节数据初始化读取器 const reader = await CarReader.fromBytes(bytes); const indexer = await CarIndexer.fromBytes(bytes);
若需要使用流读取,先将Web Stream转换为异步可迭代对象
不要直接传入File.stream()的返回值,先做一层转换适配js-car的入参要求:
// Web ReadableStream转异步迭代器工具函数 async function* streamToAsyncIterable(stream) { const reader = stream.getReader(); try { while (true) { const { done, value } = await reader.read(); if (done) return; yield value; } } finally { reader.releaseLock(); } } // 转换后再传入fromIterable const fileIterable = streamToAsyncIterable(files[0].stream()); const reader = await CarReader.fromIterable(fileIterable);
校验方法
如果修正后仍报错,先打印校验读取到的字节长度和文件原始大小是否一致:
const arrayBuffer = await files[0].arrayBuffer(); // 两个值应该完全相等 console.log('文件原始大小:', files[0].size, '读取到的字节长度:', arrayBuffer.byteLength);
如果数值不相等,说明是文件选择、上传环节存在逻辑截断,和js-car库本身无关。
内容的提问来源于stack exchange,提问作者Majid Hojati
相关产品推荐
相关产品推荐

