or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

buffer-writing.mdindex.mdindexed-reading.mdindexing.mditeration.mdreading.mdwriting.md
tile.json

reading.mddocs/

0

# CAR Reading

1

2

Core functionality for reading CAR archives with full in-memory access to blocks and metadata. CarReader loads the entire archive into memory for random access, making it suitable for smaller CAR files or when frequent block lookups are needed.

3

4

## Capabilities

5

6

### CarReader Class

7

8

Provides blockstore-like access to a CAR archive with full random access capabilities.

9

10

```typescript { .api }

11

/**

12

* Provides blockstore-like access to a CAR archive

13

* Loads entire archive into memory for random access

14

*/

15

class CarReader {

16

/** CAR version number (1 or 2) */

17

readonly version: number;

18

19

/** Get the list of root CIDs defined in the CAR header */

20

getRoots(): Promise<CID[]>;

21

22

/** Check whether a given CID exists within the CAR */

23

has(key: CID): Promise<boolean>;

24

25

/** Fetch a Block from the CAR by CID, returns undefined if not found */

26

get(key: CID): Promise<Block | undefined>;

27

28

/** Returns async iterator over all Blocks in the CAR */

29

blocks(): AsyncGenerator<Block>;

30

31

/** Returns async iterator over all CIDs in the CAR */

32

cids(): AsyncGenerator<CID>;

33

34

/** Create CarReader from Uint8Array, decodes entire CAR into memory */

35

static fromBytes(bytes: Uint8Array): Promise<CarReader>;

36

37

/** Create CarReader from async iterable stream, decodes entire CAR into memory */

38

static fromIterable(asyncIterable: AsyncIterable<Uint8Array>): Promise<CarReader>;

39

}

40

```

41

42

**Usage Examples:**

43

44

```typescript

45

import { CarReader } from "@ipld/car/reader";

46

import fs from 'fs';

47

48

// From bytes

49

const carBytes = fs.readFileSync('archive.car');

50

const reader = await CarReader.fromBytes(carBytes);

51

52

// From stream

53

const stream = fs.createReadStream('archive.car');

54

const reader2 = await CarReader.fromIterable(stream);

55

56

// Access data

57

const roots = await reader.getRoots();

58

console.log(`CAR has ${roots.length} roots`);

59

60

// Check if CID exists

61

const exists = await reader.has(roots[0]);

62

if (exists) {

63

const block = await reader.get(roots[0]);

64

console.log(`Block size: ${block.bytes.length}`);

65

}

66

67

// Iterate through all blocks

68

for await (const block of reader.blocks()) {

69

console.log(`Block CID: ${block.cid}, Size: ${block.bytes.length}`);

70

}

71

72

// Iterate through CIDs only (more efficient if you don't need block data)

73

for await (const cid of reader.cids()) {

74

console.log(`CID: ${cid}`);

75

}

76

```

77

78

### Raw Block Reading (Node.js Only)

79

80

Direct file-based block reading using file descriptors for efficient access to indexed blocks.

81

82

```typescript { .api }

83

/**

84

* Read a block directly from a file descriptor (Node.js only)

85

* Used with CarIndexer to read blocks by their index information

86

* @param fd - File descriptor (number or FileHandle)

87

* @param blockIndex - Index information pointing to block location

88

* @returns Block data

89

*/

90

static readRaw(

91

fd: fs.promises.FileHandle | number,

92

blockIndex: BlockIndex

93

): Promise<Block>;

94

```

95

96

**Usage Example:**

97

98

```typescript

99

import fs from 'fs';

100

import { CarReader } from "@ipld/car/reader";

101

import { CarIndexer } from "@ipld/car/indexer";

102

103

// Open file and create indexer

104

const fd = await fs.promises.open('large-archive.car', 'r');

105

const stream = fs.createReadStream('large-archive.car');

106

const indexer = await CarIndexer.fromIterable(stream);

107

108

// Read specific blocks using raw access

109

for await (const blockIndex of indexer) {

110

const block = await CarReader.readRaw(fd, blockIndex);

111

console.log(`Block ${block.cid}: ${block.bytes.length} bytes`);

112

113

// Process only specific blocks

114

if (someCondition(block.cid)) {

115

processBlock(block);

116

}

117

}

118

119

await fd.close();

120

```

121

122

### Error Handling

123

124

Common errors when reading CAR files:

125

126

- **TypeError**: Thrown when invalid input types are provided

127

- **Error**: Thrown for malformed CAR data, invalid headers, or unexpected end of data

128

- **Unsupported CAR versions**: Only versions 1 and 2 are supported

129

130

```typescript

131

try {

132

const reader = await CarReader.fromBytes(invalidBytes);

133

} catch (error) {

134

if (error.message.includes('Invalid CAR')) {

135

console.log('Malformed CAR file');

136

} else if (error.message.includes('version')) {

137

console.log('Unsupported CAR version');

138

}

139

}

140

```

141

142

## Platform Differences

143

144

### Browser Environment

145

- Uses `CarReader` from `lib/reader-browser.js`

146

- Memory-based operations only

147

- No file descriptor support

148

149

### Node.js Environment

150

- Uses `CarReader` from `lib/reader.js` (extends browser version)

151

- Adds `readRaw()` static method for file descriptor access

152

- Supports both memory and file-based operations