Uygulamanız için yüksek performanslı depolama: Storage Foundation API

Web platformu, geliştiricilere web için ince ayar yapılmış yüksek performanslı uygulamalar oluşturmak için ihtiyaç duydukları araçları gün geçtikçe daha fazla sunuyor. En önemlisi, WebAssembly (Wasm) hızlı ve güçlü web uygulamalarının kapısını araladı. Emscripten gibi teknolojiler ise artık geliştiricilerin denenmiş ve test edilmiş kodları web'de tekrar kullanmalarına olanak tanıyor. Bu potansiyelden tam anlamıyla yararlanmak için geliştiricilerin, depolama konusunda da aynı güce ve esnekliğe sahip olması gerekir.

Storage Foundation API burada devreye girer. Storage Foundation API, yüksek performanslı veritabanları uygulama ve büyük geçici dosyaları incelikle yönetme gibi web için yeni ve çok talep edilen kullanım alanlarını açığa çıkaran yeni, hızlı ve arama gerektirmeyen bir depolama API'sidir. Bu yeni arayüzle, geliştiriciler web'e "kendi depolama alanlarını taşıyarak" web ile platforma özel kod arasındaki özellik boşluğunu azaltabilir.

Storage Foundation API, çok temel bir dosya sistemine benzeyecek şekilde tasarlanmıştır. Bu nedenle, daha yüksek düzeyde bileşenler üzerinde çalışabilecekleri genel, basit ve yüksek performanslı temel öğeler sağlayarak geliştiricilere esneklik sağlar. Uygulamalar kendi ihtiyaçlarına en uygun araçtan yararlanarak kullanılabilirlik, performans ve güvenilirlik arasında doğru dengeyi sağlayabilir.

Web için neden başka bir depolama API'sı gerekiyor?

Web platformu, geliştiriciler için bir dizi depolama alanı seçeneği sunar. Bu seçeneklerin her biri, özel kullanım alanları göz önünde bulundurularak tasarlanmıştır.

  • Bu seçeneklerden bazıları, yalnızca çerezler veya sessionStorage ve localStorage mekanizmalarından oluşan Web Storage API gibi çok küçük miktarlarda verinin depolanmasına izin verdiği için teklifle açıkça çakışmaz.
  • Diğer seçenekler, File and Directory Entries API veya WebSQL gibi çeşitli nedenlerle zaten kullanımdan kaldırılmıştır.
  • File System Access API benzer bir API yüzeyine sahiptir ancak kullanımı, istemcinin dosya sistemiyle arayüz oluşturmak ve kaynağın ya da tarayıcının sahipliği dışındaki verilere erişim sunmak amacıyla kullanılır. Bu farklı odak noktası, güvenlikle ilgili daha sıkı değerlendirmeleri ve daha yüksek performans maliyetlerini beraberinde getirir.
  • IndexedDB API, Storage Foundation API'nin bazı kullanım alanları için arka uç olarak kullanılabilir. Örneğin, Emscripten, IndexedDB tabanlı kalıcı bir dosya sistemi olan IDBFS'yi içerir. Bununla birlikte, IndexedDB temel olarak bir anahtar/değer deposu olduğundan önemli performans sınırlamaları vardır. Ayrıca, IndexedDB'de bir dosyanın alt bölümlerine doğrudan erişmek daha da zor ve daha yavaştır.
  • Son olarak, CacheStorage arayüzü yaygın olarak desteklenir ve web uygulaması kaynakları gibi büyük boyutlu verilerin depolanması için ayarlanmıştır. Ancak değerler değiştirilemez.

Storage Foundation API, uygulamanın kaynağında tanımlanan değişken büyük dosyaların yüksek performanslı şekilde depolanmasına olanak tanıyarak önceki depolama seçeneklerindeki tüm boşlukları kapatma girişimidir.

Storage Foundation API için önerilen kullanım alanları

Bu API'yi kullanabilecek sitelere örnek olarak şunlar verilebilir:

  • Büyük miktarda video, ses veya görsel verisi üzerinde çalışan üretkenlik veya yaratıcılık uygulamaları. Bu tür uygulamalar, segmentleri bellekte tutmak yerine diske boşaltabilir.
  • Wasm'den erişilebilen kalıcı bir dosya sistemini kullanan ve IDBFS'nin garanti edebileceğinden daha fazla performansa ihtiyaç duyan uygulamalar.

Storage Foundation API nedir?

API'nin iki ana bölümü vardır:

  • Dosyalar ve dosya yollarıyla etkileşim kurmak için temel işlevleri sağlayan dosya sistemi çağrıları.
  • Dosya herkese açık kullanıcı adları: Mevcut bir dosyaya okuma ve yazma erişimi sağlar.

Dosya sistemi çağrıları

Storage Foundation API, window nesnesinde bulunan ve çeşitli işlevler içeren yeni bir nesne (storageFoundation) sunar:

  • storageFoundation.open(name): Dosya varsa belirtilen adla açılır, aksi takdirde yeni bir dosya oluşturur. Açılan dosyayla çözümlenen bir taahhüt döndürür.
  • storageFoundation.delete(name): Belirtilen ada sahip dosyayı kaldırır. Dosya silindiğinde çözüme ulaştırılacak bir söz döndürür.
  • storageFoundation.rename(oldName, newName): Dosyanın eski adını, atomik olarak yenisiyle yeniden adlandırır. Dosya yeniden adlandırıldığında çözülecek bir taahhüt döndürür.
  • storageFoundation.getAll(): Mevcut tüm dosya adlarından oluşan bir diziyle çözümlenen bir taahhüt döndürür.
  • storageFoundation.requestCapacity(requestedCapacity): Mevcut yürütme bağlamı tarafından kullanım için yeni kapasite (bayt cinsinden) ister. Kalan kapasite miktarıyla çözümlenen bir taahhüt döndürür.
  • storageFoundation.releaseCapacity(toBeReleasedCapacity): Geçerli yürütme bağlamından belirtilen sayıda baytı serbest bırakır ve kalan kapasiteyle çözümlenen bir taahhüt döndürür.
  • storageFoundation.getRemainingCapacity(): Mevcut yürütme bağlamı için mevcut kapasiteye göre çözümlenen bir taahhüt döndürür.

Dosya tanıtıcıları

Dosyalarla çalışma, aşağıdaki işlevler aracılığıyla gerçekleştirilir:

  • NativeIOFile.close(): Bir dosyayı kapatır ve işlem tamamlandığında sonuçlanacak bir söz döndürür.
  • NativeIOFile.flush(): Bir dosyanın bellek içi durumunu depolama cihazıyla senkronize eder (yani boşaltır) ve işlem tamamlandığında sonuç veren bir söz döndürür.
  • NativeIOFile.getLength(): Dosyanın bayt cinsinden uzunluğuna karşılık gelen bir taahhüt döndürür.
  • NativeIOFile.setLength(length): Dosyanın uzunluğunu bayt cinsinden ayarlar ve işlem tamamlandığında sonuçlanacak bir taahhüt döndürür. Yeni uzunluk mevcut uzunluktan küçükse baytlar dosyanın sonundan itibaren kaldırılır. Aksi takdirde, dosya sıfır değerli baytlarla genişletilir.
  • NativeIOFile.read(buffer, offset): Verilen arabelleğin aktarılması sonucunda ortaya çıkan bir arabellek üzerinden, verilen uzaklıktaki dosyanın içeriğini okur ve bu arabellek ayrılmış olarak bırakılır. Aktarılan arabelleği ve başarıyla okunan bayt sayısını içeren bir NativeIOReadResult döndürür.

    NativeIOReadResult, iki girişten oluşan bir nesnedir:

    • buffer: read() öğesine iletilen arabelleğin aktarılması sonucunda elde edilen ArrayBufferView. Kaynak arabellek ile aynı tür ve uzunluktadır.
    • readBytes: buffer için başarıyla okunan bayt sayısı. Bu değer, bir hata oluşursa veya okuma aralığı dosyanın sonunu kapsıyorsa arabellek boyutundan küçük olabilir. Okuma aralığı dosya sonundan sonraysa sıfır olarak ayarlanır.
  • NativeIOFile.write(buffer, offset): Belirtilen arabelleğin içeriğini, verilen uzaklıktaki dosyaya yazar. Arabellek, herhangi bir veri yazılmadan önce aktarılır ve bu nedenle ayrılır. Aktarılan arabelleği ve başarıyla yazılan bayt sayısını içeren bir NativeIOWriteResult döndürür. Yazma aralığı uzunluğunu aşarsa dosya genişletilir.

    NativeIOWriteResult, iki girişten oluşan bir nesnedir:

    • buffer: write() öğesine iletilen arabelleğin aktarılması sonucunda elde edilen ArrayBufferView. Kaynak arabellek ile aynı tür ve uzunluktadır.
    • writtenBytes: buffer içine başarıyla yazılan bayt sayısı. Bir hata oluşursa bu boyut, arabellek boyutundan küçük olabilir.

Eksiksiz örnekler

Yukarıda açıklanan kavramları daha anlaşılır hale getirmek için Storage Foundation dosyalarının yaşam döngüsündeki farklı aşamalarda size yol gösterecek iki eksiksiz örnek aşağıda verilmiştir.

Açma, yazma, okuma, kapatma

// 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();
}

Açma, listeleme, silme

// 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();

Demo

Aşağıdaki yerleştirmede Storage Foundation API demosunu oynayabilirsiniz. Dosya oluşturun, yeniden adlandırın, yazın ve dosyalardan okuyun. Değişiklik yaparken güncellemek istediğiniz kullanılabilir kapasiteyi görün. Demonun kaynak kodunu Glitch'te bulabilirsiniz.

Güvenlik ve izinler

Chromium ekibi, kullanıcı kontrolü, şeffaflık ve ergonomi dahil olmak üzere Güçlü Web Platformu Özelliklerine Erişimi Kontrol Etme bölümünde tanımlanan temel ilkeleri kullanarak Storage Foundation API'yi tasarlamış ve uygulamıştır.

Web'deki diğer modern depolama API'leriyle aynı şekilde, Storage Foundation API'ye erişim kaynak bağlantılıdır. Diğer bir deyişle, bir kaynak yalnızca kendi oluşturduğu verilere erişebilir. Ayrıca güvenli bağlamlarla da sınırlıdır.

Kullanıcı denetimi

Depolama kotası, disk alanına erişimi dağıtmak ve kötüye kullanımı önlemek için kullanılır. Kullanmak istediğiniz belleğin öncelikle istenmesi gerekir. Diğer depolama API'leri gibi kullanıcılar da Storage Foundation API'nin kapladığı alanı tarayıcıları üzerinden temizleyebilir.

Faydalı bağlantılar

Teşekkür

Storage Foundation API, Emanuel Krivoy ve Richard Stotz tarafından belirtilmiş ve uygulanmıştır. Bu makale Pete LePage ve Joe Medley tarafından incelenmiştir.

Unsplash'teki Markus Spiske'ten hero resim.