Skip to main content
Version: next

read

Read file content on the device filesystem. If the file doesn't exist or can't be read, an error will be thrown.

Two APIs are provided:

  • read: returns a ReadableStream for simple and quick file content retrieval.
  • createReadable: returns a PullSession for advanced use cases, allowing live progress tracking and compression ratio calculation.

read

declare class AdbSync {
read(
path: string,
compression?: Compression.Format,
): ReadableStream<Uint8Array>;
}

Compression

The compression parameter specifies the compression format to use when transferring the file:

  • If compression is undefined, the best format supported by both the device and the current runtime is selected automatically.
  • If AdbSync.Compression.Format.None is specified, compression is disabled.
  • Otherwise the explicitly specified format is used. If the format is not supported by either the device or runtime, an error is thrown.

See Compression for more details.

Example

import type { Adb } from "@yume-chan/adb";
import type { ReadableStream } from "@yume-chan/stream-extra";

declare const adb: Adb;

const content: ReadableStream<Uint8Array> = adb.sync.read("/sdcard/Download/hello.txt");

for await (const chunk of content) {
console.log(chunk);
}
Equivalent ADB Command
adb pull /sdcard/Download/hello.txt

createReadable

For advanced use cases, createReadable returns a PullSession that allows manual control over the stream and progress tracking.

interface PullSession {
/**
* The readable stream to read the file content from.
*/
readonly readable: ReadableStream<Uint8Array>;
/**
* Gets the number of bytes read from `readable`.
*/
readonly bytesRead: number;
/**
* Gets the compression format used (might be `None`).
*/
readonly compression?: Compression.Format | undefined;
/**
* Gets the size of the compressed data received from the device.
*/
readonly bytesCompressed: number;
}

declare class AdbSync {
createReadable(path: string, compression?: Compression.Format): PullSession;
}

bytesRead and bytesCompressed are live getters. You can poll them while reading from the readable stream to calculate real-time compression ratios or show progress in a UI.

Compression

See compression section above for details.

Example

import type { Adb } from "@yume-chan/adb";

declare const adb: Adb;

const session = adb.sync.createReadable("/sdcard/large-file.bin");

const progressInterval = setInterval(() => {
const ratio = session.bytesCompressed / session.bytesRead;
console.log(`Progress: ${session.bytesRead} bytes, Ratio: ${ratio.toFixed(2)}`);
}, 1000);

try {
for await (const chunk of content) {
console.log(chunk);
}
} finally {
clearInterval(progressInterval);
}

Internal API

info

Note: This is an internal API that is usually not needed directly. Most users should use the public API (adb.sync.read) instead.

The read method uses AdbSync.Receive.pull() internally, which operates on a SocketPool:

import type { SocketPool } from "@yume-chan/adb";
import { AdbSync } from "@yume-chan/adb";

declare const pool: SocketPool;
declare const path: string;

const session = AdbSync.Receive.pull(2, pool, path);
const stream: ReadableStream<Uint8Array> = session.readable;

How it works

  1. Acquires a socket from the pool
  2. Sends a RECV (v1) or RCV2 (v2) request with the file path
  3. Reads DATA responses and enqueues them into the readable stream, until a DONE response is received
  4. Automatically releases the socket back to the pool

The socket is automatically released after the stream completes or errors. If a non-sync error occurs (like a network issue), the socket is discarded to prevent connection corruption.