NOTE
واجهات Bun.file و Bun.write البرمجية الموثقة في هذه الصفحة محسنة بشدة وتمثل الطريقة الموصى بها لتنفيذ مهام نظام الملفات باستخدام Bun. للعمليات غير المتاحة بعد مع Bun.file، مثل mkdir أو readdir، يمكنك استخدام تنفيذ Bun شبه الكامل لوحدة node:fs.
قراءة الملفات (Bun.file())
Bun.file(path): BunFile
أنشئ مثيل BunFile باستخدام الدالة Bun.file(path). يمثل BunFile ملفًا يتم تحميله عند الحاجة؛ تهيئته لا تقرأ الملف فعليًا من القرص.
const foo = Bun.file("foo.txt"); // نسبة إلى cwd
foo.size; // عدد البايتات
foo.type; // نوع MIMEالمرجع يتوافق مع واجهة Blob، لذا يمكن قراءة المحتويات بتنسيقات مختلفة.
const foo = Bun.file("foo.txt");
await foo.text(); // المحتويات كسلسلة
await foo.json(); // المحتويات ككائن JSON
await foo.stream(); // المحتويات كـ ReadableStream
await foo.arrayBuffer(); // المحتويات كـ ArrayBuffer
await foo.bytes(); // المحتويات كـ Uint8Arrayيمكن أيضًا إنشاء مراجع الملفات باستخدام أوصاف الملفات الرقمية أو عناوين file://.
Bun.file(1234);
Bun.file(new URL(import.meta.url)); // مرجع إلى الملف الحالييمكن أن يشير BunFile إلى موقع على القرص حيث لا يوجد ملف.
const notreal = Bun.file("notreal.txt");
notreal.size; // 0
notreal.type; // "text/plain;charset=utf-8"
const exists = await notreal.exists(); // falseنوع MIME الافتراضي هو text/plain;charset=utf-8، ولكن يمكن تجاوزه بتمرير وسيطة ثانية إلى Bun.file.
const notreal = Bun.file("notreal.json", { type: "application/json" });
notreal.type; // => "application/json;charset=utf-8"للراحة، يعرض Bun stdin و stdout و stderr كأمثلة من BunFile.
Bun.stdin; // للقراءة فقط
Bun.stdout;
Bun.stderr;حذف الملفات (file.delete())
يمكنك حذف ملف باستدعاء الدالة .delete().
await Bun.file("logs.json").delete();كتابة الملفات (Bun.write())
Bun.write(destination, data): Promise<number>
دالة Bun.write هي أداة متعددة الأغراض لكتابة الحمولة بجميع أنواعها إلى القرص.
الوسيطة الأولى هي destination والتي يمكن أن تكون بأي من الأنواع التالية:
string: مسار إلى موقع على نظام الملفات. استخدم وحدة"path"للتلاعب بالمسارات.URL: وصفfile://.BunFile: مرجع ملف.
الوسيطة الثانية هي البيانات المراد كتابتها. يمكن أن تكون أيًا مما يلي:
stringBlob(بما في ذلكBunFile)ArrayBufferأوSharedArrayBufferTypedArray(Uint8Array، إلخ)Response
يتم التعامل مع جميع التباديل الممكنة باستخدام أسرع استدعاءات نظام متاحة على المنصة الحالية.
عرض استدعاءات النظام">
| المخرج | المدخل | استدعاء النظام | المنصة |
|---|---|---|---|
| file | file | copy_file_range | Linux |
| file | pipe | sendfile | Linux |
| pipe | pipe | splice | Linux |
| terminal | file | sendfile | Linux |
| terminal | terminal | sendfile | Linux |
| socket | file أو pipe | sendfile (إذا http، ليس https) | Linux |
| file (غير موجود) | file (مسار) | clonefile | macOS |
| file (موجود) | file | fcopyfile | macOS |
| file | Blob أو string | write | macOS |
| file | Blob أو string | write | Linux |
لكتابة سلسلة إلى القرص:
const data = `كان من أفضل الأوقات، كان من أسوأ الأوقات.`;
await Bun.write("output.txt", data);لنسخ ملف إلى موقع آخر على القرص:
const input = Bun.file("input.txt");
const output = Bun.file("output.txt"); // غير موجود بعد!
await Bun.write(output, input);لكتابة مصفوفة بايتات إلى القرص:
const encoder = new TextEncoder();
const data = encoder.encode("datadatadata"); // Uint8Array
await Bun.write("output.txt", data);لكتابة ملف إلى stdout:
const input = Bun.file("input.txt");
await Bun.write(Bun.stdout, input);لكتابة جسم استجابة HTTP إلى القرص:
const response = await fetch("https://bun.com");
await Bun.write("index.html", response);الكتابة التدريجية مع FileSink
يوفر Bun واجهة برمجة تطبيقات أصلية للكتابة التدريجية في الملفات تسمى FileSink. لاسترجاع مثيل FileSink من BunFile:
const file = Bun.file("output.txt");
const writer = file.writer();للكتابة تدريجيًا في الملف، استدعِ .write().
const file = Bun.file("output.txt");
const writer = file.writer();
writer.write("it was the best of times\n");
writer.write("it was the worst of times\n");سيتم تخزين هذه القطع داخليًا في مؤقت. لمسح المؤقت إلى القرص، استخدم .flush(). هذا يرجع عدد البايتات التي تم مسحها.
writer.flush(); // كتابة المؤقت إلى القرصسيتم أيضًا مسح المؤقت تلقائيًا عند الوصول إلى العلامة المائية العالية لـ FileSink؛ أي عندما يكون مؤقتها الداخلي ممتلئًا. يمكن تكوين هذه القيمة.
const file = Bun.file("output.txt");
const writer = file.writer({ highWaterMark: 1024 * 1024 }); // 1MBلمسح المؤقت وإغلاق الملف:
writer.end();لاحظ أنه، افتراضيًا، ستبقى عملية bun نشطة حتى يتم إغلاق FileSink صراحةً باستخدام .end(). لتعطيل هذا السلوك، يمكنك "إلغاء المرجع" للمثيل.
writer.unref();
// لـ "إعادة المرجع" لاحقًا
writer.ref();المجلدات
تنفيذ Bun لـ node:fs سريع، ولم نقم بعد بتنفيذ واجهة برمجة تطبيقات خاصة بـ Bun لقراءة المجلدات. حتى الآن، يجب استخدام node:fs للتعامل مع المجلدات في Bun.
قراءة المجلدات (readdir)
لقراءة مجلد في Bun، استخدم readdir من node:fs.
import { readdir } from "node:fs/promises";
// قراءة جميع الملفات في المجلد الحالي
const files = await readdir(import.meta.dir);قراءة المجلدات بشكل متكرر
لقراءة مجلد بشكل متكرر في Bun، استخدم readdir مع recursive: true.
import { readdir } from "node:fs/promises";
// قراءة جميع الملفات في المجلد الحالي، بشكل متكرر
const files = await readdir("../", { recursive: true });إنشاء المجلدات (mkdir)
لإنشاء مجلد بشكل متكرر، استخدم mkdir في node:fs:
import { mkdir } from "node:fs/promises";
await mkdir("path/to/dir", { recursive: true });المعايير
التالي هو تنفيذ من 3 أسطر لأمر Linux cat.
// الاستخدام
// bun ./cat.ts ./path-to-file
import { resolve } from "path";
const path = resolve(process.argv.at(-1));
await Bun.write(Bun.stdout, Bun.file(path));لتشغيل الملف:
bun ./cat.ts ./path-to-fileيعمل بسرعة ضعف سرعة GNU cat للملفات الكبيرة على Linux.
المرجع
interface Bun {
stdin: BunFile;
stdout: BunFile;
stderr: BunFile;
file(path: string | number | URL, options?: { type?: string }): BunFile;
write(
destination: string | number | BunFile | URL,
input: string | Blob | ArrayBuffer | SharedArrayBuffer | TypedArray | Response,
): Promise<number>;
}
interface BunFile {
readonly size: number;
readonly type: string;
text(): Promise<string>;
stream(): ReadableStream;
arrayBuffer(): Promise<ArrayBuffer>;
json(): Promise<any>;
writer(params: { highWaterMark?: number }): FileSink;
exists(): Promise<boolean>;
}
export interface FileSink {
write(chunk: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer): number;
flush(): number | Promise<number>;
end(error?: Error): number | Promise<number>;
start(options?: { highWaterMark?: number }): void;
ref(): void;
unref(): void;
}