|
1 | | -import { readFileSync, writeFileSync, mkdirSync, readdirSync, statSync, rmSync, mkdtempSync } from "node:fs"; |
| 1 | +import { readFileSync, mkdirSync, readdirSync, statSync, rmSync, mkdtempSync } from "node:fs"; |
2 | 2 | import { tmpdir } from "node:os"; |
3 | 3 | import path from "node:path"; |
| 4 | +import { Readable } from "node:stream"; |
| 5 | +import { pipeline } from "node:stream/promises"; |
| 6 | +import { extract as tarExtract } from "tar"; |
4 | 7 | import { interfaces, LocalHandler, DtypesManager, Inputs, Outputs, DynamicAttributes, applyPatches } from "@fnnx-ai/common"; |
5 | | -import { TarExtractor } from "./tar.js"; |
6 | 8 | import { ONNXOpV1 } from "./ops.js"; |
7 | 9 |
|
8 | 10 | const MANIFEST_PATCH_PATTERN = /^manifest-[^/]+\.patch\.json$/; |
@@ -44,16 +46,14 @@ export class Model { |
44 | 46 | return new Model(modelPath, false); |
45 | 47 | } |
46 | 48 | const tempDir = mkdtempSync(path.join(tmpdir(), 'fnnx-')); |
47 | | - const fileBuffer = readFileSync(modelPath); |
48 | | - const arrayBuffer = toArrayBuffer(fileBuffer); |
49 | | - extractToDir(arrayBuffer, tempDir); |
| 49 | + await tarExtract({ file: modelPath, C: tempDir }); |
50 | 50 | return new Model(tempDir, true); |
51 | 51 | } |
52 | 52 |
|
53 | 53 | static async fromBuffer(modelData: ArrayBuffer | Buffer): Promise<Model> { |
54 | 54 | const tempDir = mkdtempSync(path.join(tmpdir(), 'fnnx-')); |
55 | | - const arrayBuffer = Buffer.isBuffer(modelData) ? toArrayBuffer(modelData) : modelData; |
56 | | - extractToDir(arrayBuffer, tempDir); |
| 55 | + const buf = Buffer.isBuffer(modelData) ? modelData : Buffer.from(modelData); |
| 56 | + await extractToDir(buf, tempDir); |
57 | 57 | return new Model(tempDir, true); |
58 | 58 | } |
59 | 59 |
|
@@ -135,25 +135,9 @@ export class Model { |
135 | 135 | } |
136 | 136 | } |
137 | 137 |
|
138 | | -function toArrayBuffer(buf: Buffer): ArrayBuffer { |
139 | | - return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); |
140 | | -} |
141 | | - |
142 | | -function extractToDir(tarBuffer: ArrayBuffer, targetDir: string): void { |
143 | | - const extractor = new TarExtractor(tarBuffer); |
144 | | - const files = extractor.extract(); |
145 | | - |
146 | | - for (const file of files) { |
147 | | - const targetPath = path.join(targetDir, file.relpath); |
148 | | - if (file.type === 'directory') { |
149 | | - mkdirSync(targetPath, { recursive: true }); |
150 | | - } else { |
151 | | - mkdirSync(path.dirname(targetPath), { recursive: true }); |
152 | | - if (file.content) { |
153 | | - writeFileSync(targetPath, file.content); |
154 | | - } |
155 | | - } |
156 | | - } |
| 138 | +async function extractToDir(tarBuffer: Buffer, targetDir: string): Promise<void> { |
| 139 | + const readable = Readable.from(tarBuffer); |
| 140 | + await pipeline(readable, tarExtract({ C: targetDir })); |
157 | 141 | } |
158 | 142 |
|
159 | 143 | function listModelFiles(dir: string): interfaces.TarFileContent[] { |
|
0 commit comments