File System Access API, web uygulamalarının doğrudan kullanıcının cihazındaki dosya ve klasörlerde yapılan değişiklikleri okumasına veya kaydetmesine olanak tanır.
File System Access API nedir?
File System Access API (önceki adıyla Native File System API ve ondan önce Writeable Files API olarak adlandırılıyordu). Geliştiricilerin, kullanıcının yerel cihazındaki IDE'ler, fotoğraf ve video düzenleyiciler, metin düzenleyiciler gibi dosyalarla etkileşime giren güçlü web uygulamaları geliştirmesine olanak tanır. Kullanıcı bir web uygulamasına erişim izni verdikten sonra bu API, kullanıcının cihazındaki dosyalarda ve klasörlerde yapılan değişiklikleri doğrudan okumasına veya kaydetmesine olanak tanır. File System Access API dosya okuma ve yazmanın yanı sıra bir dizin açıp içeriğini numaralandırma özelliği de sunar.
Daha önce dosya okuma ve yazma konusunda çalıştıysanız, paylaşacaklarımın çoğu size tanıdık gelecektir. Tüm sistemler aynı olmadığından yine de okumanızı öneririm.
File System Access API şu anda Windows, macOS, ChromeOS ve Linux'taki çoğu Chromium tarayıcısında desteklenmektedir. Şu anda yalnızca bir bayrak arkasında kullanıma sunulduğu önemli bir istisna olan Brave'dir. Android, Chromium 109 tarihinden itibaren API'nin kaynak özel dosya sistemi kısmını desteklemektedir. Şu anda seçici yöntemleriyle ilgili herhangi bir plan yoktur, ancak crbug.com/1011535 adresine yıldız ekleyerek potansiyel ilerleme durumunu takip edebilirsiniz.
File System Access API'yi kullanma
File System Access API'nin gücünü ve faydasını göstermek için tek bir dosya metin düzenleyici yazdım. Bir metin dosyasını açmanıza, bu dosyayı düzenlemenize, değişiklikleri diske geri kaydetmenize veya yeni bir dosya başlatmanıza ve değişiklikleri diske kaydetmenize olanak tanır. Çok özel bir bilgi olmamasına rağmen kavramları anlamanıza yardımcı olacak kadar yararlı bilgiler sağlar.
Tarayıcı desteği
Deneyin
Metin düzenleyici demosunda File System Access API'yi çalışırken görün.
Yerel dosya sisteminden dosya okuma
Yapmak istediğim ilk kullanım alanı, kullanıcıdan bir dosya seçmesini ve sonra dosyayı açıp diskten okumasını istemek.
Kullanıcıdan okuyacak bir dosya seçmesini isteyin
File System Access API'nin giriş noktası window.showOpenFilePicker()
şeklindedir. Çağrı yapıldığında bir dosya seçici iletişim kutusu
gösterilir ve kullanıcıdan dosya seçmesi istenir. Kullanıcı bir dosya seçtikten sonra API, bir dizi dosya işleyicisi döndürür. İsteğe bağlı options
parametresi, örneğin kullanıcının birden fazla dosya, dizin ya da farklı dosya türü seçmesine izin vererek dosya seçicinin davranışını etkilemenize olanak tanır.
Herhangi bir seçenek belirtilmedikçe, dosya seçici kullanıcının tek bir dosya seçmesine olanak tanır. Bu, metin düzenleyiciler için mükemmeldir.
Diğer birçok güçlü API gibi showOpenFilePicker()
çağrısı da güvenli bağlamda yapılmalı ve bir kullanıcı hareketi içinden çağrılmalıdır.
let fileHandle;
butOpenFile.addEventListener('click', async () => {
// Destructure the one-element array.
[fileHandle] = await window.showOpenFilePicker();
// Do something with the file handle.
});
Kullanıcı bir dosya seçtiğinde, showOpenFilePicker()
bir herkese açık kullanıcı adı dizisi döndürür. Bu örnekte, dosyayla etkileşim kurmak için gereken özellikleri ve yöntemleri içeren bir FileSystemFileHandle
içeren tek öğeli bir dizidir.
Daha sonra kullanılabilmesi için dosya tanıtıcısına bir referans tutmanız yararlı olur. Dosyadaki değişikliklerin kaydedilmesi veya diğer dosya işlemlerinin gerçekleştirilmesi gerekir.
Dosya sisteminden dosya okuma
Artık bir dosyaya yönelik tanıtıcınız olduğuna göre dosyanın özelliklerini alabilir veya dosyanın kendisine erişebilirsiniz.
Şimdilik içeriğini okuyacağım. handle.getFile()
çağrısı, blob içeren bir File
nesnesi döndürür. Blobdan veri almak için yöntemlerinden birini (slice()
, stream()
, text()
veya arrayBuffer()
) çağırın.
const file = await fileHandle.getFile();
const contents = await file.text();
FileSystemFileHandle.getFile()
tarafından döndürülen File
nesnesi, yalnızca diskteki temel dosya değişmediği sürece okunabilir. Diskteki dosyada değişiklik yapılırsa File
nesnesi okunamaz hale gelir ve değiştirilen verileri okuyacak yeni bir File
nesnesi almak için getFile()
öğesini yeniden çağırmanız gerekir.
Özet
Kullanıcılar Aç düğmesini tıkladığında tarayıcıda bir dosya seçici gösterilir. Kullanıcı bir dosya seçtikten sonra, uygulama içeriği okur ve <textarea>
içine yerleştirir.
let fileHandle;
butOpenFile.addEventListener('click', async () => {
[fileHandle] = await window.showOpenFilePicker();
const file = await fileHandle.getFile();
const contents = await file.text();
textArea.value = contents;
});
Dosyayı yerel dosya sistemine yazma
Metin düzenleyicide bir dosyayı kaydetmenin iki yolu vardır: Kaydet ve Farklı Kaydet. Kaydet seçeneği, daha önce alınan dosya tanıtıcısını kullanarak değişiklikleri orijinal dosyaya geri yazar. Ancak Farklı Kaydet yeni bir dosya oluşturur ve bu nedenle yeni bir dosya tanıtıcısı gerektirir.
Yeni dosya oluşturma
Bir dosyayı kaydetmek için showSaveFilePicker()
yöntemini çağırın. Bu çağrı, dosya seçiciyi "kaydet" modunda gösterir ve kullanıcının kaydetmek için kullanmak istediği yeni bir dosyayı seçmesine olanak tanır. Ayrıca metin düzenleyici için .txt
uzantısının otomatik olarak eklenmesini istedim. Bu yüzden bazı ek parametreler sağladım.
async function getNewFileHandle() {
const options = {
types: [
{
description: 'Text Files',
accept: {
'text/plain': ['.txt'],
},
},
],
};
const handle = await window.showSaveFilePicker(options);
return handle;
}
Değişiklikleri diske kaydet
Bir dosyada yapılan değişiklikleri kaydetmek için gereken tüm kodları GitHub'daki metin düzenleyici demomuzda bulabilirsiniz. Temel dosya sistemi etkileşimleri fs-helpers.js
içindedir. İşlem en basit şekilde aşağıdaki koda benzemektedir.
Her bir adımı tek tek açıklayacağım.
// fileHandle is an instance of FileSystemFileHandle..
async function writeFile(fileHandle, contents) {
// Create a FileSystemWritableFileStream to write to.
const writable = await fileHandle.createWritable();
// Write the contents of the file to the stream.
await writable.write(contents);
// Close the file and write the contents to disk.
await writable.close();
}
Diske veri yazılırken WritableStream
alt sınıfı olan FileSystemWritableFileStream
nesnesi kullanılır. Dosya işleyici nesnesinde createWritable()
yöntemini çağırarak akışı oluşturun. createWritable()
çağrıldığında, tarayıcı ilk olarak kullanıcının dosyaya yazma izni verip vermediğini kontrol eder. Yazma izni verilmediyse tarayıcı kullanıcıdan izin ister. İzin verilmezse createWritable()
bir DOMException
gönderir ve uygulama dosyaya yazamaz. Metin düzenleyicide, DOMException
nesneleri saveFile()
yöntemiyle işlenir.
write()
yöntemi, metin düzenleyici için gerekli olan bir dize alır. Ancak bir BufferSource veya Blob da alabilir. Örneğin, bir akışı doğrudan ona aktarabilirsiniz:
async function writeURLToFile(fileHandle, url) {
// Create a FileSystemWritableFileStream to write to.
const writable = await fileHandle.createWritable();
// Make an HTTP request for the contents.
const response = await fetch(url);
// Stream the response into the file.
await response.body.pipeTo(writable);
// pipeTo() closes the destination pipe by default, no need to close it.
}
Ayrıca, dosyayı belirli bir konumdaki güncellemek ya da yeniden boyutlandırmak için akış içinde seek()
veya truncate()
aracını kullanabilirsiniz.
Önerilen bir dosya adı ve başlangıç dizini belirtme
Çoğu durumda, uygulamanızın varsayılan bir dosya adı veya konumu önermesini isteyebilirsiniz. Örneğin, bir metin düzenleyici, Untitled
yerine varsayılan dosya adını Untitled Text.txt
önermek isteyebilir. Bunu, showSaveFilePicker
seçeneklerinin parçası olarak bir suggestedName
özelliği ileterek yapabilirsiniz.
const fileHandle = await self.showSaveFilePicker({
suggestedName: 'Untitled Text.txt',
types: [{
description: 'Text documents',
accept: {
'text/plain': ['.txt'],
},
}],
});
Varsayılan başlangıç dizini için de aynı durum söz konusudur. Bir metin düzenleyici oluşturuyorsanız dosya kaydetme veya dosya açma iletişim kutusunu varsayılan documents
klasöründe, resim düzenleyicide ise varsayılan pictures
klasöründe başlatmak isteyebilirsiniz. showSaveFilePicker
, showDirectoryPicker()
veya showOpenFilePicker
yöntemlerine bir startIn
özelliği ileterek varsayılan bir başlangıç dizini önerebilirsiniz.
const fileHandle = await self.showOpenFilePicker({
startIn: 'pictures'
});
İyi bilinen sistem dizinlerinin listesi şöyledir:
desktop
: Kullanıcının masaüstü dizini (varsa).documents
: Kullanıcı tarafından oluşturulan dokümanların genellikle depolanacağı dizin.downloads
: İndirilen dosyaların genellikle depolandığı dizin.music
: Ses dosyalarının genellikle depolandığı dizin.pictures
: Fotoğrafların ve diğer sabit resimlerin genellikle depolandığı dizin.videos
: Videoların/filmlerin genellikle depolandığı dizin.
İyi bilinen sistem dizinlerinin dışında, mevcut bir dosya veya dizin tanıtıcısını da startIn
değeri olarak iletebilirsiniz. Bunu yaptığınızda iletişim kutusu aynı dizinde açılır.
// Assume `directoryHandle` is a handle to a previously opened directory.
const fileHandle = await self.showOpenFilePicker({
startIn: directoryHandle
});
Farklı dosya seçicilerin amacını belirtme
Bazen uygulamalarda farklı amaçlar için farklı seçiciler kullanılabilir. Örneğin, bir zengin metin düzenleyicisi, kullanıcının metin dosyalarını açmasına ve aynı zamanda resimleri içe aktarmasına da olanak tanıyabilir. Varsayılan olarak, her dosya seçici
en son hatırlanan konumda açılır. Her seçici türü için id
değerlerini depolayarak bu durumu atlatabilirsiniz. Bir id
belirtilirse dosya seçici uygulaması, bu id
için son kullanılan ayrı bir dizini hatırlar.
const fileHandle1 = await self.showSaveFilePicker({
id: 'openText',
});
const fileHandle2 = await self.showSaveFilePicker({
id: 'importImage',
});
IndexedDB'deki dosya tanıtıcılarını veya dizin tanıtıcılarını depolama
Dosya tanıtıcıları ve dizin tanıtıcıları serileştirilebilir. Diğer bir deyişle, bir dosyayı veya dizin tanıtıcısını IndexedDB'ye kaydedebilir ya da bunları aynı üst düzey kaynak arasında göndermek için postMessage()
yöntemini çağırabilirsiniz.
Dosya veya dizin tanıtıcılarını IndexedDB'ye kaydetmek, durumu depolayabileceğiniz veya bir kullanıcının hangi dosyalar ya da dizinler üzerinde çalıştığını hatırlayabileceğiniz anlamına gelir. Bu, son açılan veya düzenlenen dosyaların listesini saklamayı, uygulama açıldığında son dosyayı yeniden açmayı teklif etmeyi, önceki çalışma dizinini geri yüklemeyi ve daha fazlasını mümkün kılar. Metin düzenleyicide, kullanıcının açtığı en son beş dosyanın listesini depoluyorum. Böylece, bu dosyalara tekrar erişim kolaylaşıyor.
Aşağıdaki kod örneğinde bir dosya tanıtıcısının ve dizin tutma yerinin saklanması ve alınması gösterilmektedir. Glitch'te uygulamayı görebilirsiniz. (Kısa olması için idb-keyval kitaplığını kullanıyorum.)
import { get, set } from 'https://unpkg.com/idb-keyval@5.0.2/dist/esm/index.js';
const pre1 = document.querySelector('pre.file');
const pre2 = document.querySelector('pre.directory');
const button1 = document.querySelector('button.file');
const button2 = document.querySelector('button.directory');
// File handle
button1.addEventListener('click', async () => {
try {
const fileHandleOrUndefined = await get('file');
if (fileHandleOrUndefined) {
pre1.textContent = `Retrieved file handle "${fileHandleOrUndefined.name}" from IndexedDB.`;
return;
}
const [fileHandle] = await window.showOpenFilePicker();
await set('file', fileHandle);
pre1.textContent = `Stored file handle for "${fileHandle.name}" in IndexedDB.`;
} catch (error) {
alert(error.name, error.message);
}
});
// Directory handle
button2.addEventListener('click', async () => {
try {
const directoryHandleOrUndefined = await get('directory');
if (directoryHandleOrUndefined) {
pre2.textContent = `Retrieved directroy handle "${directoryHandleOrUndefined.name}" from IndexedDB.`;
return;
}
const directoryHandle = await window.showDirectoryPicker();
await set('directory', directoryHandle);
pre2.textContent = `Stored directory handle for "${directoryHandle.name}" in IndexedDB.`;
} catch (error) {
alert(error.name, error.message);
}
});
Depolanan dosya veya dizin tanıtıcıları ve izinleri
İzinler şu anda oturumlar arasında kalıcı olmadığından, kullanıcının queryPermission()
kullanarak dosyaya veya dizine izin verip vermediğini doğrulamanız gerekir. Henüz göndermediyse requestPermission()
adlı iş ortağını arayarak (yeniden) istekte bulunun. Bu işlem dosya ve dizin işleyicilerinde de aynı şekilde çalışır. Sırasıyla fileOrDirectoryHandle.requestPermission(descriptor)
veya fileOrDirectoryHandle.queryPermission(descriptor)
çalıştırmanız gerekir.
Metin düzenleyicide, kullanıcının zaten izin verip vermediğini ve gerekirse istekte bulunup bulunmadığını kontrol eden bir verifyPermission()
yöntemi oluşturdum.
async function verifyPermission(fileHandle, readWrite) {
const options = {};
if (readWrite) {
options.mode = 'readwrite';
}
// Check if permission was already granted. If so, return true.
if ((await fileHandle.queryPermission(options)) === 'granted') {
return true;
}
// Request permission. If the user grants permission, return true.
if ((await fileHandle.requestPermission(options)) === 'granted') {
return true;
}
// The user didn't grant permission, so return false.
return false;
}
Okuma isteğiyle yazma izni isteyerek izin istemlerinin sayısını azalttım. Kullanıcı dosyayı açarken bir istem görüyor ve hem okuma hem de yazma izni veriyor.
Bir dizini açma ve içeriğini numaralandırma
Bir dizindeki tüm dosyaları numaralandırmak için showDirectoryPicker()
çağrısı yapın. Kullanıcı, seçicide bir dizin seçer. Bu dizinden sonra, dizin dosyalarını numaralandırmanıza ve bunlara erişmenize olanak tanıyan bir FileSystemDirectoryHandle
döndürülür. Varsayılan olarak dizindeki dosyalara okuma erişiminiz olur, ancak yazma erişimine ihtiyacınız varsa { mode: 'readwrite' }
öğesini bu yönteme iletebilirsiniz.
const butDir = document.getElementById('butDirectory');
butDir.addEventListener('click', async () => {
const dirHandle = await window.showDirectoryPicker();
for await (const entry of dirHandle.values()) {
console.log(entry.kind, entry.name);
}
});
Ek olarak, örneğin tek tek dosya boyutlarını elde etmek için her bir dosyaya getFile()
aracılığıyla erişmeniz gerekirse await
her sonuç için sırayla kullanmayın. Bunun yerine, tüm dosyaları paralel olarak (ör. Promise.all()
) işleyin.
const butDir = document.getElementById('butDirectory');
butDir.addEventListener('click', async () => {
const dirHandle = await window.showDirectoryPicker();
const promises = [];
for await (const entry of dirHandle.values()) {
if (entry.kind !== 'file') {
continue;
}
promises.push(entry.getFile().then((file) => `${file.name} (${file.size})`));
}
console.log(await Promise.all(promises));
});
Bir dizinde dosya ve klasör oluşturma veya klasörlere erişme
Bir dizinde, getFileHandle()
veya sırasıyla getDirectoryHandle()
yöntemini kullanarak dosya ve klasör oluşturabilir ya da dosyalara erişebilirsiniz. Anahtarı create
ve boole değeri true
ya da false
olan isteğe bağlı bir options
nesnesini geçirerek yeni bir dosya veya klasörün yoksa oluşturulup oluşturulmayacağını belirleyebilirsiniz.
// In an existing directory, create a new directory named "My Documents".
const newDirectoryHandle = await existingDirectoryHandle.getDirectoryHandle('My Documents', {
create: true,
});
// In this new directory, create a file named "My Notes.txt".
const newFileHandle = await newDirectoryHandle.getFileHandle('My Notes.txt', { create: true });
Dizindeki bir öğenin yolunu çözümleme
Bir dizindeki dosyalar veya klasörlerle çalışırken, söz konusu öğenin yolunun çözülmesi yararlı olabilir. Bu işlem, uygun bir şekilde adlandırılmış resolve()
yöntemiyle yapılabilir. Çözüm için, öğe dizinin doğrudan veya dolaylı bir alt öğesi olabilir.
// Resolve the path of the previously created file called "My Notes.txt".
const path = await newDirectoryHandle.resolve(newFileHandle);
// `path` is now ["My Documents", "My Notes.txt"]
Bir dizindeki dosya ve klasörleri silme
Bir dizine erişim elde ettiyseniz içerilen dosya ve klasörleri removeEntry()
yöntemini kullanarak silebilirsiniz. Klasörlerde silme işlemi isteğe bağlı olarak yinelemeli olabilir ve tüm alt klasörler ile içindeki dosyaları da içerebilir.
// Delete a file.
await directoryHandle.removeEntry('Abandoned Projects.txt');
// Recursively delete a folder.
await directoryHandle.removeEntry('Old Stuff', { recursive: true });
Bir dosyayı veya klasörü doğrudan silme
Bir dosyaya veya dizin işleyiciye erişiminiz varsa kaldırmak için FileSystemFileHandle
veya FileSystemDirectoryHandle
üzerinde remove()
numarasını arayın.
// Delete a file.
await fileHandle.remove();
// Delete a directory.
await directoryHandle.remove();
Dosya ve klasörleri yeniden adlandırma ve taşıma
Dosya ve klasörler, FileSystemHandle
arayüzünden move()
çağrısı yapılarak yeniden adlandırılabilir veya yeni bir konuma taşınabilir. FileSystemHandle
, FileSystemFileHandle
ve
FileSystemDirectoryHandle
alt arayüzlerine sahiptir. move()
yöntemi bir veya iki parametre alır. Birincisi, yeni ada sahip bir dize veya hedef klasör için bir FileSystemDirectoryHandle
olabilir. İkinci örnekte isteğe bağlı ikinci parametre, yeni ada sahip bir dizedir. Bu nedenle, taşıma ve yeniden adlandırma tek bir adımda gerçekleştirilebilir.
// Rename the file.
await file.move('new_name');
// Move the file to a new directory.
await file.move(directory);
// Move the file to a new directory and rename it.
await file.move(directory, 'newer_name');
Sürükle ve bırak özelliği
HTML Sürükle ve Bırak arayüzleri,
web uygulamalarının bir web sayfasındaki sürüklenip bırakılan dosyaları kabul etmesini sağlar. Sürükle ve bırak işlemi sırasında, sürüklenen dosya ve dizin öğeleri sırasıyla dosya girişleri ve dizin girişleriyle ilişkilendirilir. DataTransferItem.getAsFileSystemHandle()
yöntemi, sürüklenen öğe bir dosyaysa FileSystemFileHandle
nesnesiyle sözü ve sürüklenen öğe bir dizinse FileSystemDirectoryHandle
nesnesi içeren bir söz döndürür. Aşağıdaki girişte bu uygulama gösterilmektedir. Sürükle ve Bırak arayüzünün DataTransferItem.kind
hem dosyalar hem de dizinler için "file"
, File System Access API'nin FileSystemHandle.kind
ise dosyalar için "file"
, dizinler için "directory"
değerindedir.
elem.addEventListener('dragover', (e) => {
// Prevent navigation.
e.preventDefault();
});
elem.addEventListener('drop', async (e) => {
e.preventDefault();
const fileHandlesPromises = [...e.dataTransfer.items]
.filter((item) => item.kind === 'file')
.map((item) => item.getAsFileSystemHandle());
for await (const handle of fileHandlesPromises) {
if (handle.kind === 'directory') {
console.log(`Directory: ${handle.name}`);
} else {
console.log(`File: ${handle.name}`);
}
}
});
Kaynak özel dosya sistemine erişme
Kaynak özel dosya sistemi, adından da anlaşılacağı gibi sayfa kaynağına özel olan bir depolama uç noktasıdır. Tarayıcılar genellikle bu kaynak özel dosya sisteminin içeriğini bir yerde diske tutarak bu uygulamayı uygulasa da, içeriklerin kullanıcı tarafından kolayca erişilebilir olması gerekmez. Benzer şekilde, kaynak özel dosya sisteminin alt adlarıyla eşleşen adlara sahip dosya veya dizinlerin olması gerekmez. Tarayıcı, kaynak özel bir dosya sistemi olduğu için dahili olarak dosyalar varmış gibi görünse de, tarayıcı bu "dosyaları" bir veritabanında veya başka herhangi bir veri yapısında depolayabilir. Esas olarak, bu API'yi kullanıyorsanız oluşturulan dosyaların sabit diskin bir yerinde bire bir eşleştirilmiş dosyaları bulmayı beklemeyin. Kök FileSystemDirectoryHandle
öğesine erişim elde ettikten sonra kaynak özel dosya sisteminde her zamanki gibi çalışabilirsiniz.
const root = await navigator.storage.getDirectory();
// Create a new file handle.
const fileHandle = await root.getFileHandle('Untitled.txt', { create: true });
// Create a new directory handle.
const dirHandle = await root.getDirectoryHandle('New Folder', { create: true });
// Recursively remove a directory.
await root.removeEntry('Old Stuff', { recursive: true });
Kaynak özel dosya sisteminden performans için optimize edilmiş dosyalara erişme
Kaynak özel dosya sistemi, örneğin bir dosya içeriğine yerinde ve özel yazma erişimi sunarak, örneğin performans için yüksek oranda optimize edilmiş özel bir dosya türüne isteğe bağlı erişim sağlar. Chromium 102 ve sonraki sürümlerde, kaynak özel dosya sisteminde dosya erişimini basitleştirmek için ek bir yöntem mevcuttur: createSyncAccessHandle()
(eşzamanlı okuma ve yazma işlemleri için).
FileSystemFileHandle
üzerinde yalnızca Web Çalışanları için sunulmaktadır.
// (Read and write operations are synchronous,
// but obtaining the handle is asynchronous.)
// Synchronous access exclusively in Worker contexts.
const accessHandle = await fileHandle.createSyncAccessHandle();
const writtenBytes = accessHandle.write(buffer);
const readBytes = accessHandle.read(buffer, { at: 1 });
Çoklu dolgu
File System Access API yöntemlerinin tümünü çoklu doldurmak mümkün değildir.
showOpenFilePicker()
yöntemi, bir<input type="file">
öğesiyle yaklaştırılabilir.showSaveFilePicker()
yöntemi, bir<a download="file_name">
öğesiyle simüle edilebilir. Bununla birlikte, bu yöntem programatik indirme işlemini tetikler ve mevcut dosyaların üzerine yazılmasına izin vermez.showDirectoryPicker()
yöntemi, standart olmayan<input type="file" webkitdirectory>
öğesiyle bir şekilde emüle edilebilir.
Mümkün olan her yerde File System Access API'yi kullanan ve diğer her durumda bir sonraki en iyi seçenekleri kullanan browser-fs-access adında bir kitaplık geliştirdik.
Güvenlik ve izinler
Chrome ekibi, File System Access API'yi, kullanıcı denetimi, şeffaflık ve kullanıcı ergonomisi de dahil olmak üzere Güçlü Web Platformu Özelliklerine Erişimi Kontrol Etme bölümünde tanımlanan temel ilkeleri kullanarak tasarlamış ve uygulamıştır.
Dosya açma veya yeni bir dosya kaydetme
Kullanıcı bir dosyayı açarken dosya seçici aracılığıyla bir dosyayı veya dizini okuma izni verir.
Açık dosya seçici yalnızca güvenli bir bağlamdan sunulduğunda bir kullanıcı hareketiyle gösterilebilir. Kullanıcılar fikirlerini değiştirirse dosya seçicideki seçimi iptal edebilir ve site hiçbir şeye erişemez. Bu, <input type="file">
öğesinin davranışıyla aynıdır.
Benzer şekilde, bir web uygulaması yeni bir dosya kaydetmek istediğinde tarayıcı dosya kaydetme seçiciyi gösterir. Bu, kullanıcının yeni dosyanın adını ve konumunu belirtmesine olanak tanır. Cihaza yeni bir dosya kaydettiğinden (mevcut bir dosyanın üzerine yazılmasına karşın) dosya seçici, uygulamaya dosyaya yazma izni verir.
Kısıtlanmış klasörler
Kullanıcıların ve verilerinin korunmasına yardımcı olmak için tarayıcı, kullanıcının Windows gibi temel işletim sistemi klasörleri, macOS Kitaplık klasörleri gibi belirli klasörlere kaydetme özelliğini sınırlandırabilir. Bu durumda, tarayıcı bir istem görüntüler ve kullanıcıdan farklı bir klasör seçmesini ister.
Mevcut bir dosyayı veya dizini değiştirme
Bir web uygulaması, kullanıcıdan açık izin almadan diskteki bir dosyayı değiştiremez.
İzin istemi
Bir kişi daha önce okuma erişimi verdiği bir dosyada yapılan değişiklikleri kaydetmek isterse tarayıcı, sitenin diske değişiklik yazması için izin isteyen bir izin istemi görüntüler. İzin isteği yalnızca bir kullanıcı hareketiyle (örneğin, Kaydet düğmesinin tıklanması) tetiklenebilir.
Alternatif olarak, IDE gibi birden çok dosyayı düzenleyen bir web uygulaması da açılış sırasında değişiklikleri kaydetme izni isteyebilir.
Kullanıcı İptal'i seçer ve yazma erişimi vermezse web uygulaması, değişiklikleri yerel dosyaya kaydedemez. Kullanıcının verilerini kaydetmesi için alternatif bir yöntem sağlamalıdır (örneğin, dosyayı"indirme", verileri buluta kaydetme gibi bir yöntem sağlamalıdır.
Şeffaflık
Bir kullanıcı yerel bir dosyayı kaydetmesi için bir web uygulamasına izin verdiğinde, tarayıcı URL çubuğunda bir simge gösterir. Simgeyi tıkladığınızda, kullanıcının erişim izni verdiği dosyaların listesini gösteren bir pop-up açılır. Kullanıcı isterse bu erişimi kolayca iptal edebilir.
İzin kalıcılığı
Web uygulaması, kaynağının tüm sekmeleri kapatılana kadar sormadan dosyada yapılan değişiklikleri kaydetmeye devam edebilir. Bir sekme kapatıldığında site tüm erişimi kaybeder. Kullanıcının web uygulamasını tekrar kullandığında dosyalara erişmesi tekrar istenir.
Geri bildirim
File System Access API ile ilgili deneyimlerinizi öğrenmek isteriz.
Bize API tasarımı hakkında bilgi verin
API'de beklediğiniz gibi çalışmayan bir durum mu var? Fikrinizi uygulamak için gereken yöntem veya özellikler eksik mi? Güvenlik modeliyle ilgili bir sorunuz veya yorumunuz mu var?
- WICG Dosya Sistemi Erişimi GitHub deposunda spesifikasyon hatası bildiriminde bulunun veya mevcut bir soruna düşüncelerinizi ekleyin.
Uygulamayla ilgili bir sorun mu var?
Chrome'un uygulamasında bir hata buldunuz mu? Yoksa uygulama, spesifikasyondan farklı mı?
- https://new.crbug.com adresinden hata bildiriminde bulunun. Mümkün olduğunca fazla ayrıntı eklediğinizden, yeniden oluşturma için basit talimatları eklediğinizden ve Bileşenler'i
Blink>Storage>FileSystem
olarak ayarladığınızdan emin olun. Glitch, hızlı ve kolay yeniden oluşturmalar paylaşmak için idealdir.
API'yi kullanmayı mı planlıyorsunuz?
Sitenizde File System Access API'yi kullanmayı mı planlıyorsunuz? Herkese açık desteğiniz, özellikleri önceliklendirmemize yardımcı olur ve diğer tarayıcı satıcılarına onları desteklemenin ne kadar kritik olduğunu gösterir.
- Bu bilgiyi nasıl kullanmayı planladığınızı WICG Discourse ileti dizisinde paylaşın.
#FileSystemAccess
hashtag'ini kullanarak @ChromiumDev adresine tweet gönderip bu tweet'i nerede ve nasıl kullandığınızı bize bildirin.
Faydalı bağlantılar
- Herkese açık açıklayıcı
- Dosya Sistemi Erişim spesifikasyonu ve Dosya spesifikasyonu
- İzleme hatası
- ChromeStatus.com girişi
- TypeScript tanımları
- File System Access API - Chromium Güvenlik Modeli
- Yanıp Sönen Bileşen:
Blink>Storage>FileSystem
Teşekkür
File System Access API spesifikasyonu Marijn Kruisselbrink tarafından yazılmıştır.