ذخیره سازی با کارایی بالا برای برنامه شما: Storage Foundation API

پلتفرم وب به طور فزاینده ای ابزارهایی را به توسعه دهندگان ارائه می دهد که آنها برای ساخت برنامه های کاربردی با کارایی بالا با تنظیم دقیق برای وب نیاز دارند. مهمتر از همه، WebAssembly (Wasm) درها را به روی برنامه های کاربردی وب سریع و قدرتمند باز کرده است، در حالی که فناوری هایی مانند Emscripten اکنون به توسعه دهندگان اجازه می دهد تا از کدهای آزمایش شده و آزمایش شده در وب استفاده مجدد کنند. برای استفاده واقعی از این پتانسیل، توسعه‌دهندگان باید از همان قدرت و انعطاف‌پذیری در زمینه ذخیره‌سازی برخوردار باشند.

اینجاست که Storage Foundation وارد می‌شود. Storage Foundation API ذخیره‌سازی سریع و بدون نظر جدیدی است که موارد استفاده جدید و بسیار درخواستی را برای وب باز می‌کند، مانند پیاده‌سازی پایگاه‌های داده عملکردی و مدیریت دلپذیر فایل‌های موقت بزرگ. با این رابط جدید، توسعه‌دهندگان می‌توانند فضای ذخیره‌سازی خود را به وب بیاورند و شکاف ویژگی‌ها بین کدهای وب و پلتفرم خاص را کاهش دهند.

Storage Foundation API به گونه‌ای طراحی شده است که شبیه یک سیستم فایل بسیار ابتدایی باشد، بنابراین با ارائه اولیه‌های عمومی، ساده و عملکردی به توسعه‌دهندگان انعطاف‌پذیری می‌دهد تا بتوانند اجزای سطح بالاتری را بر اساس آن بسازند. برنامه ها می توانند از بهترین ابزار برای نیازهای خود استفاده کنند و تعادل مناسب بین قابلیت استفاده، عملکرد و قابلیت اطمینان را بیابند.

چرا وب به API ذخیره سازی دیگری نیاز دارد؟

پلتفرم وب تعدادی گزینه ذخیره سازی را برای توسعه دهندگان ارائه می دهد که هر کدام با موارد استفاده خاصی ساخته شده اند.

  • برخی از این گزینه‌ها به وضوح با این پیشنهاد همپوشانی ندارند، زیرا فقط به مقادیر بسیار کمی داده اجازه می‌دهند مانند کوکی‌ها یا Web Storage API متشکل از sessionStorage و مکانیزم‌های localStorage ذخیره شوند.
  • گزینه‌های دیگر به دلایل مختلف مانند File and Directory Entries API یا WebSQL منسوخ شده‌اند.
  • File System Access API یک سطح API مشابه دارد، اما استفاده از آن برای ارتباط با سیستم فایل مشتری و دسترسی به داده هایی است که ممکن است خارج از مالکیت مبدا یا حتی مرورگر باشد. این تمرکز متفاوت با ملاحظات امنیتی سخت‌گیرانه‌تر و هزینه‌های عملکرد بالاتر همراه است.
  • IndexedDB API را می توان به عنوان یک Backend برای برخی از موارد استفاده Storage Foundation API استفاده کرد. به عنوان مثال، Emscripten شامل IDBFS ، یک سیستم فایل پایدار مبتنی بر IndexedDB است. با این حال، از آنجایی که IndexedDB اساساً یک فروشگاه با ارزش کلیدی است، با محدودیت‌های عملکرد قابل توجهی همراه است. علاوه بر این، دسترسی مستقیم به بخش‌های فرعی یک فایل در IndexedDB حتی دشوارتر و کندتر است.
  • در نهایت، رابط CacheStorage به طور گسترده پشتیبانی می شود و برای ذخیره داده های با اندازه بزرگ مانند منابع برنامه وب تنظیم شده است، اما مقادیر تغییرناپذیر هستند.

Storage Foundation API تلاشی برای بستن تمام شکاف‌های گزینه‌های ذخیره‌سازی قبلی با اجازه دادن به ذخیره‌سازی کارآمد فایل‌های بزرگ قابل تغییر تعریف شده در مبدا برنامه است.

موارد استفاده پیشنهادی برای Storage Foundation API

نمونه هایی از سایت هایی که ممکن است از این API استفاده کنند عبارتند از:

  • برنامه های بهره وری یا خلاقیت که بر روی مقادیر زیادی داده های ویدئویی، صوتی یا تصویری کار می کنند. چنین برنامه‌هایی می‌توانند بخش‌هایی را به‌جای نگه‌داشتن در حافظه، روی دیسک بارگذاری کنند.
  • برنامه‌هایی که به یک سیستم فایل پایدار قابل دسترسی از Wasm متکی هستند و به عملکرد بیشتری نسبت به آنچه IDBFS می‌تواند تضمین کند نیاز دارند.

Storage Foundation API چیست؟

دو بخش اصلی برای API وجود دارد:

  • فراخوانی های سیستم فایل ، که عملکردهای اساسی را برای تعامل با فایل ها و مسیرهای فایل فراهم می کند.
  • دسته‌های فایل ، که دسترسی خواندن و نوشتن به فایل موجود را فراهم می‌کند.

تماس های سیستم فایل

Storage Foundation API یک شی جدید به storageFoundation را معرفی می کند که روی شی window زندگی می کند و شامل تعدادی توابع است:

  • storageFoundation.open(name) : فایل را در صورت وجود با نام داده شده باز می کند و در غیر این صورت یک فایل جدید ایجاد می کند. وعده ای را برمی گرداند که با فایل باز شده حل می شود.
  • storageFoundation.delete(name) : فایل با نام داده شده را حذف می کند. وعده ای را برمی گرداند که با حذف فایل برطرف می شود.
  • storageFoundation.rename(oldName, newName) : فایل را به صورت اتمی از نام قدیمی به نام جدید تغییر می دهد. وعده ای را برمی گرداند که با تغییر نام فایل برطرف می شود.
  • storageFoundation.getAll() : یک وعده را برمی گرداند که با آرایه ای از نام فایل های موجود حل می شود.
  • storageFoundation.requestCapacity(requestedCapacity) : ظرفیت جدید (بر حسب بایت) را برای استفاده در زمینه اجرای فعلی درخواست می کند. وعده ای را برمی گرداند که با مقدار باقیمانده ظرفیت موجود برطرف شد.
  • storageFoundation.releaseCapacity(toBeReleasedCapacity) : تعداد مشخصی از بایت ها را از زمینه اجرای فعلی آزاد می کند و وعده ای را برمی گرداند که با ظرفیت باقیمانده حل می شود.
  • storageFoundation.getRemainingCapacity() : وعده ای را برمی گرداند که با ظرفیت موجود برای زمینه اجرای فعلی حل می شود.

دسته های فایل

کار با فایل ها از طریق توابع زیر انجام می شود:

  • NativeIOFile.close() : یک فایل را می بندد و یک وعده را برمی گرداند که پس از اتمام عملیات برطرف می شود.
  • NativeIOFile.flush() : حالت حافظه یک فایل را با دستگاه ذخیره‌سازی همگام‌سازی می‌کند (یعنی فلاش می‌کند)، و وعده‌ای را برمی‌گرداند که پس از اتمام عملیات برطرف می‌شود.
  • NativeIOFile.getLength() : وعده ای را برمی گرداند که با طول فایل در بایت حل می شود.
  • NativeIOFile.setLength(length) : طول فایل را بر حسب بایت تنظیم می کند و وعده ای را برمی گرداند که پس از اتمام عملیات برطرف می شود. اگر طول جدید کوچکتر از طول فعلی باشد، بایت ها از انتهای فایل حذف می شوند. در غیر این صورت فایل با بایت های با ارزش صفر گسترش می یابد.
  • NativeIOFile.read(buffer, offset) : محتویات فایل را در افست داده شده از طریق بافری می خواند که نتیجه انتقال بافر داده شده است، که سپس جدا می شود. یک NativeIOReadResult را با بافر منتقل شده و تعداد بایت هایی که با موفقیت خوانده شده است برمی گرداند.

    یک NativeIOReadResult یک شی است که از دو ورودی تشکیل شده است:

    • buffer : یک ArrayBufferView ، که نتیجه انتقال بافر ارسال شده به read() است. از نوع و طول بافر منبع است.
    • readBytes : تعداد بایت هایی که با موفقیت در buffer خوانده شدند. اگر خطایی رخ دهد یا اگر محدوده خواندن فراتر از انتهای فایل باشد، ممکن است از اندازه بافر کمتر باشد. اگر محدوده خواندن فراتر از انتهای فایل باشد، روی صفر تنظیم می شود.
  • NativeIOFile.write(buffer, offset) : محتویات بافر داده شده را در فایل با افست داده شده می نویسد. بافر قبل از نوشته شدن هر داده ای منتقل می شود و بنابراین جدا می ماند. یک NativeIOWriteResult را با بافر منتقل شده و تعداد بایت هایی که با موفقیت نوشته شده است برمی گرداند. اگر دامنه نوشتن از طول آن بیشتر شود، فایل تمدید می شود.

    یک NativeIOWriteResult یک شی است که از دو ورودی تشکیل شده است:

    • buffer : یک ArrayBufferView که نتیجه انتقال بافر ارسال شده به write() است. از همان نوع و طول بافر منبع است.
    • writtenBytes : تعداد بایت هایی که با موفقیت در buffer نوشته شده اند. در صورت بروز خطا ممکن است این اندازه از اندازه بافر کمتر باشد.

نمونه های کامل

برای شفاف‌تر شدن مفاهیم معرفی‌شده در بالا، در اینجا دو مثال کامل وجود دارد که شما را در مراحل مختلف چرخه حیات فایل‌های Storage Foundation راهنمایی می‌کند.

باز کردن، نوشتن، خواندن، بسته شدن

// Open a file (creating it if needed).
const file = await storageFoundation.open('test_file');
try {
  // Request 100 bytes of capacity for this context.
  await storageFoundation.requestCapacity(100);

  const writeBuffer = new Uint8Array([64, 65, 66]);
  // Write the buffer at offset 0. After this operation, `result.buffer`
  // contains the transferred buffer and `result.writtenBytes` is 3,
  // the number of bytes written. `writeBuffer` is left detached.
  let result = await file.write(writeBuffer, 0);

  const readBuffer = new Uint8Array(3);
  // Read at offset 1. `result.buffer` contains the transferred buffer,
  // `result.readBytes` is 2, the number of bytes read. `readBuffer` is left
  // detached.
  result = await file.read(readBuffer, 1);
  // `Uint8Array(3) [65, 66, 0]`
  console.log(result.buffer);
} finally {
  file.close();
}

باز کردن، فهرست کردن، حذف کردن

// Open three different files (creating them if needed).
await storageFoundation.open('sunrise');
await storageFoundation.open('noon');
await storageFoundation.open('sunset');
// List all existing files.
// `["sunset", "sunrise", "noon"]`
await storageFoundation.getAll();
// Delete one of the three files.
await storageFoundation.delete('noon');
// List all remaining existing files.
// `["sunrise", "noon"]`
await storageFoundation.getAll();

نسخه ی نمایشی

می توانید با نسخه ی نمایشی Storage Foundation API در جاسازی زیر بازی کنید. فایل‌ها را ایجاد کنید، نام آن‌ها را تغییر دهید، بنویسید، و از آن‌ها بخوانید و ظرفیت موجودی را که درخواست به‌روزرسانی کرده‌اید مشاهده کنید. می توانید کد منبع نسخه ی نمایشی را در Glitch پیدا کنید.

امنیت و مجوزها

تیم Chromium با استفاده از اصول اصلی تعریف شده در کنترل دسترسی به ویژگی‌های قدرتمند پلتفرم وب ، از جمله کنترل کاربر، شفافیت و ارگونومی، Storage Foundation API را طراحی و اجرا کرد.

با پیروی از الگوی مشابه سایر APIهای ذخیره‌سازی مدرن در وب، دسترسی به API بنیاد ذخیره‌سازی محدود به مبدا است، به این معنی که یک مبدا فقط می‌تواند به داده‌های خود ساخته دسترسی داشته باشد. همچنین محدود به زمینه های امن است.

کنترل کاربر

سهمیه ذخیره سازی برای توزیع دسترسی به فضای دیسک و جلوگیری از سوء استفاده استفاده خواهد شد. ابتدا باید حافظه ای را که می خواهید اشغال کنید درخواست کنید. مانند سایر API های ذخیره سازی، کاربران می توانند فضای اشغال شده توسط Storage Foundation API را از طریق مرورگر خود پاک کنند.

لینک های مفید

قدردانی ها

Storage Foundation API توسط Emanuel Krivoy و Richard Stotz مشخص و اجرا شد. این مقاله توسط پیت لی پیج و جو مدلی بررسی شده است.

تصویر قهرمان از طریق Markus Spiske در Unsplash .