Library for "unpacking" and reading files inside rar archives as node Readable streams.
Note: Requires node version >= 18.0.0
Note: Decompression is not implemented at the moment
Below example shows how to unpack local rar files by piping the inner files to the file system.
import fs from "fs";
import path from "path";
import { RarFilesPackage, LocalFileMedia } from "rar-stream";
const CWD = process.cwd();
const localRarFiles = [
path.resolve(CWD, "./file.r00"),
path.resolve(CWD, "./file.r01"),
path.resolve(CWD, "./file.r02"),
path.resolve(CWD, "./file.rar"),
].map((p) => new LocalFileMedia(p));
const rarFilesPackage = new RarFilesPackage(localRarFiles);
async function writeInnerRarFilesToDisk() {
const innerFiles = await rarFilesPackage.parse();
for (const innerFile of innerFiles) {
const stream = await innerFile.createReadStream({ start: 0, end: innerFile.length - 1 })
stream.pipe(fs.createWriteStream(innerFile.name));
}
}
await writeInnerRarFilesToDisk();
See example/webtorrent.js for a more advanced example.
Install from npm repo with:
npm i rar-stream
Method | Description |
---|---|
constructor | Takes an array of local file paths as strings or instances that satifies the FileMedia interface mentioned below. |
parse | Parses all rar files and returns a Promise with InnerFile s. |
The RarFilesPackage.parse()
method accepts one optional parameter that should be an object of options.
As parsing is done sequencially, opts.filter
and opts.maxFiles
can be used to filter and limit results.
Here is an example:
{
filter: (fileName, fileIdx) => {
if (fileName.includes('Lorem Ipsum')) {
return true;
} else if (fileIdx === 9) {
return true;
}
return false;
},
maxFiles: 1
}
The filter function will be called on each file entry from within the RAR archive and it will always include the name of the file and the file index. The filter function is expected to return a boolean value, if the returned value is true
the file will be included in the parser's results.
The parser will stop processing the file list once it reaches the maxFiles
limit of returned files.
Event | Description |
---|---|
parsing-start | Emitted when the parsing is started, happens when you call parse . Event args are a bundle represntation of all the rar files passed to the constructor. |
file-parsed | Emitted each time a rar file is parsed. The event argument is the RarFile just parsed, i.e .rxx in the chain. |
parsing-complete | Emitted when the parsing is completed. The event argument is an array of all the parsed InnerFile s. |
const rarFilesPackage = new RarFilesPackage(localRarFiles);
rarFilesPackage.on('parsing-start', rarFiles => console.log(rarFiles))
rarFilesPackage.on('file-parsed', rarFile => console.log(rarFile.name))
rarFilesPackage.on('parsing-end', innerFiles => console.log(innerFiles))
const innerFiles = await rarFilesPackage.parse();
Implements the FileMedia
interface.
Method | Description |
---|---|
createReadStream({start: number, end: number}) | Returns a Promise with a Readable stream. The start and end interval is inclusive. |
readToEnd | Returns a Promise with a Buffer containing all the content of the file. |
Property | Description |
---|---|
name | The name of the file |
length | Returns the total number of bytes of the file |
const innerFiles = await rarStreamPackage.parse();
const innerFileStream = await innerFiles[0].createReadStream({ start: 0, end: 30});
This is loosely enforced interface that makes this module interoptable with other node modules such as torrent-stream
or webtorrent
.
Should have the following shape:
// FileMedia
{
createReadStream(interval: Interval): Promise<Readable>,
name: string,
length: number // Length or size of the file in bytes
}
// Interval
// start and end should be inclusive.
{
start: number,
end: number
}
Run tests with:
npm test
Post a new issue if you'd like to contribute in any way.
We use SemVer for versioning. For the versions available, see the tags on this repository.
This project is licensed under the MIT License - see the LICENSE.md file for details