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 üzere ihtiyaç duydukları araçları giderek daha fazla sunuyor. En önemlisi, WebAssembly (Wasm) hızlı ve güçlü web uygulamalarının kapısını aralamıştır. Emscripten gibi teknolojiler ise artık geliştiricilerin denenmiş ve test edilmiş kodları web'de yeniden kullanmasına olanak tanımaktadır. Geliştiriciler bu potansiyelden gerçek anlamda yararlanmak için depolama söz konusu olduğunda aynı güce ve esnekliğe sahip olmalıdır.

Storage Foundation API bu noktada devreye girer. Storage Foundation API, web için yüksek performanslı veritabanlarını uygulamak ve büyük geçici dosyaları sorunsuzca yönetmek gibi yeni ve çok istenen kullanım alanlarının kilidini açan yeni, hızlı ve ücretsiz bir depolama API'sidir. Bu yeni arayüz sayesinde geliştiriciler, web'e "kendi depolama alanlarını getirip" web ile platforma özel kodlar arasındaki özellik boşluğunu azaltabilir.

Storage Foundation API, çok temel bir dosya sistemine benzeyecek şekilde tasarlanmıştır. Bu nedenle, üst düzey bileşenler derleyebilecekleri genel, basit ve performanslı temel öğeler sağlayarak geliştiricilere esneklik sağlar. Uygulamalar; kullanılabilirlik, performans ve güvenilirlik arasında doğru dengeyi bularak ihtiyaçlarına en uygun araçtan yararlanabilir.

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

Web platformu, geliştiricilere çeşitli depolama seçenekleri sunar. Bu seçeneklerin her biri, belirli kullanım alanları dikkate alınarak geliştirilmiştir.

  • Bu seçeneklerden bazıları, yalnızca çok küçük miktarlarda verinin (ör. çerezler veya sessionStorage ve localStorage mekanizmalarından oluşan Web Storage API) depolanmasına izin verdiğinden bu teklifle açıkça çakışmaz.
  • Dosya ve Dizin Girişleri API'si veya WebSQL gibi diğer seçenekler, çeşitli nedenlerle zaten kullanımdan kaldırılmıştır.
  • File System Access API de benzer bir API yüzeyine sahiptir ancak istemcinin dosya sistemiyle arayüz oluşturmak ve kaynağın veya tarayıcının sahipliği dışında olabilecek verilere erişim sağlamaktır. Bu farklı odak noktası, güvenlikle ilgili daha katı düşünceler ve daha yüksek performans maliyetleridir.
  • IndexedDB API, Storage Foundation API'nin bazı kullanım alanları için arka uç olarak kullanılabilir. Örneğin, Emscripten, IndexedDB tabanlı bir kalıcı dosya sistemi olan IDBFS'yi içerir. Ancak IndexedDB, temelde bir anahtar/değer deposu olduğundan önemli performans sınırlamalarına sahiptir. Ayrıca, bir dosyanın alt bölümlerine doğrudan erişmek IndexedDB'de daha da zor ve yavaştır.
  • Son olarak, CacheStorage arayüzü yaygın olarak desteklenir ve web uygulaması kaynakları gibi büyük boyutlu verileri depolamak için ayarlanmıştır. Ancak değerler sabittir.

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

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

Bu API'yi kullanabilecek sitelere örnek olarak aşağıdakiler verilebilir:

  • Büyük miktarda video, ses veya görüntü verisi üzerinde çalışan üretkenlik veya yaratıcılık uygulamaları. Bu tür uygulamalar, segmentleri bellekte tutmak yerine diske boşaltabilir.
  • Wasm'dan 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 iki ana bölümden oluşur:

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

Dosya sistemi çağrıları

Storage Foundation API, window nesnesinde bulunan ve birkaç işlev içeren yeni bir nesne (storageFoundation) kullanıma sunar:

  • storageFoundation.open(name): Dosya mevcutsa verilen adla açılır, aksi takdirde yeni bir dosya oluşturulur. Açılan dosyayla çözümlenen bir söz döndürür.
  • storageFoundation.delete(name): Belirtilen ada sahip dosyayı kaldırır. Dosya silindiğinde çözülen bir söz döndürür.
  • storageFoundation.rename(oldName, newName): Dosyayı eski adını ana makineyle yeni adla yeniden adlandırır. Dosya yeniden adlandırıldığında çözümlenen bir söz döndürür.
  • storageFoundation.getAll(): Mevcut tüm dosya adları dizisiyle çözümlenen bir söz döndürür.
  • storageFoundation.requestCapacity(requestedCapacity): Mevcut yürütme bağlamına göre kullanım için yeni kapasite (bayt cinsinden) ister. Mevcut kalan kapasite miktarında çözümlenen bir söz 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 söz döndürür.
  • storageFoundation.getRemainingCapacity(): Mevcut yürütme bağlamı için mevcut kapasiteyle çözümlenen bir söz döndürür.

Dosya tanıtıcıları

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

  • NativeIOFile.close(): Bir dosyayı kapatır ve işlem tamamlandığında çözümlenen bir söz döndürür.
  • NativeIOFile.flush(): Dosyanın bellek içi durumunu depolama cihazıyla senkronize eder (yani boşaltır) ve işlem tamamlandığında çözümlenen bir söz döndürür.
  • NativeIOFile.getLength(): Dosyanın bayt cinsinden uzunluğuyla çözümlenen bir söz döndürür.
  • NativeIOFile.setLength(length): Dosyanın uzunluğunu bayt cinsinden ayarlar ve işlem tamamlandığında çözümlenen bir söz döndürür. Yeni uzunluk mevcut uzunluktan kısaysa baytlar dosyanın sonundan itibaren kaldırılır. Aksi takdirde, dosya sıfır değerli baytlarla genişletilir.
  • NativeIOFile.read(buffer, offset): Belirli bir arabellek aktarıldıktan sonra kalan ve daha sonra çıkarılan bir arabellek aracılığıyla belirtilen ofsetteki dosya içeriğini okur. 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 arabellek aktarımının sonucu olan ArrayBufferView. Kaynak tampon ile aynı türde ve uzunluktadır.
    • readBytes: buffer olarak başarıyla okunan bayt sayısı. Bir hata oluşursa veya okuma aralığı dosyanın sonunu aşacaksa arabellek boyutundan küçük olabilir. Okuma aralığı, dosyanın sonundan sonraysa değer sıfır olarak ayarlanır.
  • NativeIOFile.write(buffer, offset): Belirli bir arabelleğin içeriğini, dosyaya belirtilen ofsette yazar. Arabellek, herhangi bir veri yazılmadan önce aktarılır ve bu nedenle ayrılmış olarak bırakı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 uzatılır.

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

    • buffer: write()'e iletilen arabelleği aktarmanın sonucu olan bir ArrayBufferView. Kaynak tamponla aynı türde ve uzunluktadır.
    • writtenBytes: buffer içine başarıyla yazılan bayt sayısı. Hata oluşursa bu değer, arabellek boyutundan az olabilir.

Eksiksiz örnekler

Yukarıda açıklanan kavramları daha net hale getirmek için Storage Foundation dosyalarının yaşam döngüsündeki farklı aşamalarda size yol gösterecek iki eksiksiz örneği aşağıda bulabilirsiniz.

Açma, yazma, okuma, kapanış

// 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ştirilmiş bölümde Storage Foundation API demosunu inceleyebilirsiniz. Dosya oluşturun, yeniden adlandırın, dosyalara yazın ve dosyalardan okuma yapın. Ayrıca, değişiklik yaparken güncelleme istediğiniz kullanılabilir kapasiteyi görün. Demonun kaynak kodunu Glitch'te bulabilirsiniz.

Güvenlik ve izinler

Chromium ekibi; kullanıcı denetimi, ş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 tasarladı ve uyguladı.

Web'deki diğer modern depolama API'leriyle aynı kalıbı takip ederek Storage Foundation API'ye erişim kaynağa bağ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 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. İlk olarak, işgal etmek istediğiniz belleğin istenmesi gerekir. Diğer depolama API'lerinde olduğu gibi kullanıcılar, 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 belirlenmiş ve uygulanmıştır. Bu makale Pete LePage ve Joe Medley tarafından incelendi.

Unsplash'te Markus Spiske aracılığıyla hero resim.