javascriptfileuint8array

read CAR file using js-car


I have a CAR file object in javascript and want to read it using js-car github. But I keep getting unexpected end of the file error. Here is my code I am trying

let arrayBuffer = await files[0].arrayBuffer();
let bytes=new Uint8Array(carFile); 
const reader = await CarReader.fromBytes(bytes) //throws error here
const indexer = await CarIndexer.fromBytes(bytes) //throws error here

I also tired this

let str = await files[0].stream() 
const reader = await CarReader.fromIterable(files[0].stream()) //throws error here

and none of them work. However with the same file this code works

const inStream = fs.createReadStream('test.car')
const reader = await CarReader.fromIterable(inStream)

I checked and I know that CarReader.fromBytes needs a Unit8Arrey and I am sure files[0] is not null. Does anyone knows what I am missing here?


Solution

  • for the people might face similar issue in future this is my solution: I used res.body directly and converted it to an async stream and read it using fromIterable

    async function* streamAsyncIterator(stream) {
      // Get a lock on the stream
      const reader = stream.getReader();
    
      try {
        while (true) {
          // Read from the stream
          const { done, value } = await reader.read();
          // Exit if we're done
          if (done) return;
          // Else yield the chunk
          yield value;
        }
      }
      finally {
        reader.releaseLock();
      }
    }
    
    const info = await w3StorageClient.status(response)
    
        if (info) {
          // Fetch and verify files from web3.storage
          const res = await w3StorageClient.get(response);
          const reader = await CarReader.fromIterable(streamAsyncIterator(res.body))
          // read the list of roots from the header
          const roots = await reader.getRoots()
          // retrieve a block, as a { cid:CID, bytes:UInt8Array } pair from the archive
          const got = await reader.get(roots[0])
          // also possible: for await (const { cid, bytes } of CarIterator.fromIterable(inStream)) { ... }
          let decoded = cbor.decode(got.bytes)
          console.log('Retrieved [%s] from example.car with CID [%s]',
          decoded,
            roots[0].toString())
        }