File System Access API, web uygulamalarının değişiklikleri doğrudan kullanıcının cihazındaki dosya ve klasörlere okumasına veya kaydetmesine olanak tanır.
File System Access API nedir?
Dosya Sistemi Erişimi API'si, geliştiricilerin kullanıcının yerel cihazındaki dosyalarla etkileşime geçen güçlü web uygulamaları (ör. IDE'ler, fotoğraf ve video düzenleyiciler, metin düzenleyiciler vb.) oluşturmasını sağlar. Bir kullanıcı bir web uygulamasına erişim izni verdikten sonra bu API, kullanıcının değişiklikleri doğrudan cihazındaki dosyalara ve klasörlere okumasına veya kaydetmesine olanak tanır. File System Access API, dosya okuma ve yazmanın yanı sıra bir dizini açma ve içeriğini listeleme olanağı da sunar.
Daha önce dosya okuma ve yazmayla çalıştıysanız paylaşacağım bilgilerin çoğu size tanıdık gelecektir. Tüm sistemler birbirinin aynısı olmadığından bu dokümanı okumanızı öneririz.
Dosya Sistemi Erişimi API'si, Windows, macOS, ChromeOS ve Linux'taki çoğu Chromium tarayıcıda desteklenir. Bununla birlikte, Brave'da bu özellik şu anda yalnızca bir bayrak aracılığıyla kullanılabilir. Android desteği için crbug.com/1011535 kapsamında çalışmalar devam etmektedir.
File System Access API'yi kullanma
File System Access API'nin gücünü ve kullanışlılığını göstermek için tek dosyadan oluşan bir metin düzenleyici yazdım. Bir metin dosyasını açmanıza, düzenlemenize, değişiklikleri diske kaydetmenize veya yeni bir dosya başlatıp değişiklikleri diske kaydetmenize olanak tanır. Çok ayrıntılı olmasa da kavramları anlamanıza yardımcı olacak kadar bilgi sağlar.
Tarayıcı desteği
Özellik algılama
File System Access API'nin desteklenip desteklenmediğini öğrenmek için ilgilendiğiniz seçici yöntemin olup olmadığını kontrol edin.
if ('showOpenFilePicker' in self) {
// The `showOpenFilePicker()` method of the File System Access API is supported.
}
Dene
File System Access API'nin metin düzenleyici demosunda nasıl kullanıldığını görün.
Yerel dosya sisteminden dosya okuma
Ele almak istediğim ilk kullanım alanı, kullanıcıdan bir dosya seçmesini istemek, ardından bu dosyayı diskten açıp okumaktır.
Kullanıcıdan okunacak bir dosya seçmesini isteme
File System Access API'nin giriş noktası window.showOpenFilePicker()
. Çağrıldığında bir dosya seçici iletişim kutusu gösterir ve kullanıcıdan bir dosya seçmesini ister. Kullanıcı bir dosya seçtikten sonra API, bir dosya adı dizisi döndürür. İsteğe bağlı options
parametresi, dosya seçicinin davranışını etkilemenize olanak tanır. Örneğin, kullanıcının birden fazla dosya, dizin veya farklı dosya türü seçmesine izin vererek bu parametreyi kullanabilirsiniz.
Dosya seçici, herhangi bir seçenek belirtilmeden kullanıcının tek bir dosya seçmesine olanak tanır. Bu, metin düzenleyiciler için mükemmel bir seçenektir.
Diğer birçok güçlü API gibi showOpenFilePicker()
çağrısı da güvenli bir bağlamda yapılmalı ve 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çtikten sonra showOpenFilePicker()
, bir tutamaç dizisi döndürür. Bu durumda, dosyayla etkileşim kurmak için gereken özellikleri ve yöntemleri içeren bir FileSystemFileHandle
içeren tek bir öğe dizisi döndürülür.
Daha sonra kullanılabilmesi için dosya tutamacına referans tutmak yararlı olur. Dosyadaki değişiklikleri kaydetmek veya başka dosya işlemleri yapmak için oturum açmanız gerekir.
Dosya sisteminden dosya okuma
Dosyanın bir tutamacına sahip olduğunuza göre dosyanın özelliklerini alabilir veya dosyanın kendisine erişebilirsiniz.
Şimdilik içeriğini okuyacağım. handle.getFile()
çağrısı, bir blob içeren bir File
nesnesi döndürür. Blob'daki verileri 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 dosya değiştirilirse File
nesnesi okunamaz hale gelir ve değiştirilen verileri okumak için yeni bir File
nesnesi almak üzere getFile()
işlevini tekrar çağırmanız gerekir.
Tüm unsurların birleşimi
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 dosyaları kaydetmenin iki yolu vardır: Kaydet ve Farklı Kaydet. Kaydet, daha önce alınan dosya adını kullanarak değişiklikleri orijinal dosyaya geri yazar. Ancak Olarak Kaydet yeni bir dosya oluşturduğundan yeni bir dosya tutamaç gerektirir.
Yeni dosya oluşturma
Dosya kaydetmek için showSaveFilePicker()
öğesini çağırın. Bu işlem, dosya seçiciyi "kaydet" modunda gösterir ve kullanıcının kaydetmek için kullanmak istediği yeni bir dosya seçmesine olanak tanır. Metin düzenleyicinin otomatik olarak bir .txt
uzantısı eklemesini de istediğim için 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 kaydetme
Değişiklikleri bir dosyaya kaydetmeyle ilgili tüm kodları GitHub'daki metin düzenleyici demomda bulabilirsiniz. Temel dosya sistemi etkileşimleri fs-helpers.js
içindedir. En basit haliyle bu süreç aşağıdaki koda benzer.
Her adımı adım adım 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 yazma işleminde, WritableStream
alt sınıfı olan bir FileSystemWritableFileStream
nesnesi kullanılır. Dosya tutamaç nesnesinde createWritable()
çağrısı yaparak akışı oluşturun. createWritable()
çağrıldığında tarayıcı önce 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
atar ve uygulama dosyaya yazamaz. Metin düzenleyicide DOMException
nesneleri saveFile()
yönteminde işlenir.
write()
yöntemi, metin düzenleyici için gereken bir dize alır. Ancak BufferSource veya Blob da alabilir. Örneğin, bir akışı doğrudan bu akışa 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 konumda güncellemek veya yeniden boyutlandırmak için akışta seek()
ya da truncate()
düğmesini de kullanabilirsiniz.
Önerilen bir dosya adı ve başlangıç dizini belirtme
Çoğu durumda uygulamanızın varsayılan bir dosya adı veya konum önermesini isteyebilirsiniz. Örneğin, bir metin düzenleyici Untitled
yerine Untitled Text.txt
dosya adını önerebilir. Bunu, showSaveFilePicker
seçenekleri kapsamında bir suggestedName
mülkü ile 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 geçerlidir. Metin düzenleyici oluşturuyorsanız dosya kaydetme veya dosya açma iletişim kutusunu varsayılan documents
klasöründe başlatmak isteyebilirsiniz. Resim düzenleyici oluşturuyorsanız varsayılan pictures
klasöründe başlatmak isteyebilirsiniz. showSaveFilePicker
, showDirectoryPicker()
veya showOpenFilePicker
yöntemlerine bir startIn
mülkü ileterek varsayılan bir başlangıç dizini önerebilirsiniz.
const fileHandle = await self.showOpenFilePicker({
startIn: 'pictures'
});
Bilinen sistem dizinlerinin listesi:
desktop
: Kullanıcının masaüstü dizini (varsa).documents
: Kullanıcı tarafından oluşturulan dokümanların genellikle depolandığı dizin.downloads
: İndirilen dosyaların genellikle depolandığı dizin.music
: Ses dosyalarının genellikle depolandığı dizin.pictures
: Fotoğrafların ve diğer hareketsiz resimlerin genellikle depolandığı dizin.videos
: Videoların veya filmlerin genellikle depolandığı dizin.
Bilinen sistem dizinlerinin yanı sıra, mevcut bir dosya veya dizin adını startIn
için bir değer olarak da iletebilirsiniz. İletiş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çicilerinin amacını belirtme
Bazen uygulamalarda farklı amaçlar için farklı seçicilere yer verilir. Örneğin, zengin metin düzenleyiciler kullanıcıların metin dosyalarını açmasına ve resimleri içe aktarmasına 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ğerleri saklayarak bu sorunun üstesinden gelebilirsiniz. Bir id
belirtilirse dosya seçici uygulaması, söz konusu id
için ayrı bir son kullanılan dizini hatırlar.
const fileHandle1 = await self.showSaveFilePicker({
id: 'openText',
});
const fileHandle2 = await self.showSaveFilePicker({
id: 'importImage',
});
Dosya veya dizin tutamaçlarını IndexedDB'de depolama
Dosya ve dizin kalemleri serileştirilebilir. Bu, bir dosya veya dizin kalemini IndexedDB'e kaydedebileceğiniz ya da aynı üst düzey kaynak arasında göndermek için postMessage()
işlevini çağırabileceğiniz anlamına gelir.
Dosya veya dizin tutamaçlarını IndexedDB'e kaydetmek, durumu depolayabileceğiniz veya kullanıcının üzerinde çalıştığı dosya ya da dizinleri hatırlayabileceğiniz anlamına gelir. Bu sayede, son açılan veya düzenlenen dosyaların listesini tutabilir, uygulama açıldığında son dosyayı yeniden açma seçeneği sunabilir, önceki çalışma dizinlerini geri yükleyebilir ve daha pek çok işlem yapabilirsiniz. Metin düzenleyicide, kullanıcının açtığı en son beş dosyanın listesini depolarız. Böylece kullanıcı bu dosyalara tekrar erişebilir.
Aşağıdaki kod örneğinde, bir dosya tutamaç ve dizin tutamaç depolama ve alma işlemleri gösterilmektedir. Bu özelliğin işleyiş şeklini Glitch'te görebilirsiniz. (Kısaltmak 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);
}
});
Kayıtlı dosya veya dizin herkese açık adları ve izinleri
İzinler oturumlar arasında her zaman korunmadığından kullanıcının queryPermission()
kullanarak dosyaya veya dizine izin verip vermediğini doğrulamanız gerekir. Bu bilgiler gönderilmediyse requestPermission()
numaralı telefondan (yeniden) isteyebilirsiniz. Bu durum, dosya ve dizin imleçleri için de geçerlidir. Sırasıyla fileOrDirectoryHandle.requestPermission(descriptor)
veya fileOrDirectoryHandle.queryPermission(descriptor)
çalıştırmanız gerekir.
Metin düzenleyicide, kullanıcının izin verip vermediğini kontrol eden ve gerekirse isteği gönderen 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 birlikte yazma izni isteyerek izin istemlerinin sayısını azalttım. Kullanıcı, dosyayı açarken bir istem görür ve hem okuma hem de yazma izni verir.
Bir dizini açma ve içeriğini numaralandırma
Bir dizindeki tüm dosyaları numaralandırmak için showDirectoryPicker()
işlevini çağırın. Kullanıcı, seçicide bir dizin seçtikten sonra dizinin dosyalarını saymanı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 yönteme { mode: 'readwrite' }
değerini iletebilirsiniz.
butDir.addEventListener('click', async () => {
const dirHandle = await window.showDirectoryPicker();
for await (const entry of dirHandle.values()) {
console.log(entry.kind, entry.name);
}
});
Örneğin, her bir dosya boyutunu elde etmek için her dosyaya getFile()
kullanarak erişmeniz gerekiyorsa her sonuçta await
'ü sırayla kullanmayın. Bunun yerine, tüm dosyaları paralel olarak işleyin (örneğin, Promise.all()
kullanarak).
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 bu dosyalara ve klasörlere erişme
Bir dizinden getFileHandle()
veya sırasıyla getDirectoryHandle()
yöntemini kullanarak dosya ve klasör oluşturabilir ya da bunlara erişebilirsiniz. create
anahtarına ve true
veya false
boole değerine sahip isteğe bağlı bir options
nesnesi göndererek, mevcut değilse yeni bir dosya veya klasör 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 });
Bir dizindeki öğenin yolunu çözümleme
Bir dizindeki dosya veya klasörlerle çalışırken söz konusu öğenin yolunu çözmek yararlı olabilir. Bu işlem, uygun ş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 removeEntry()
yöntemini kullanarak içindeki dosya ve klasörleri silebilirsiniz. Klasörler için silme işlemi isteğe bağlı olarak yinelemeli olabilir ve tüm alt klasörleri ve bu klasörlerdeki dosyaları içerebilir.
// Delete a file.
await directoryHandle.removeEntry('Abandoned Projects.txt');
// Recursively delete a folder.
await directoryHandle.removeEntry('Old Stuff', { recursive: true });
Dosya veya klasörleri doğrudan silme
Bir dosya veya dizin tutamacına erişiminiz varsa FileSystemFileHandle
veya FileSystemDirectoryHandle
üzerinde remove()
'ü çağırarak tutamacıyı kaldırabilirsiniz.
// Delete a file.
await fileHandle.remove();
// Delete a directory.
await directoryHandle.remove();
Dosyaları ve klasörleri yeniden adlandırma ve taşıma
Dosya ve klasörler, FileSystemHandle
arayüzünde move()
çağrı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. İlki, yeni adı içeren bir dize veya hedef klasöre giden bir FileSystemDirectoryHandle
olabilir. İkinci durumda, isteğe bağlı ikinci parametre yeni adı içeren bir dizedir. Bu nedenle, taşıma ve yeniden adlandırma işlemi tek adımda yapılabilir.
// 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 entegrasyonu
HTML sürükle ve bırak arayüzleri, web uygulamalarının bir web sayfasında sürüklenen ve 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şleriyle ve dizin girişleriyle ilişkilendirilir. DataTransferItem.getAsFileSystemHandle()
yöntemi, sürüklenen öğe bir dosyaysa FileSystemFileHandle
nesnesi içeren bir promise, sürüklenen öğe bir dizinse FileSystemDirectoryHandle
nesnesi içeren bir promise döndürür. Aşağıdaki girişte bu durum gösterilmektedir. Sürükle ve bırak arayüzünün DataTransferItem.kind
değerinin hem dosyalar hem de dizinler için "file"
olduğunu, File System Access API'nin FileSystemHandle.kind
değerinin ise dosyalar için "file"
, dizinler için "directory"
olduğunu unutmayın.
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 sayfanın kaynağına özel bir depolama uç noktasıdır. Tarayıcılar bunu genellikle bu orijinal özel dosya sisteminin içeriğini bir diske kaydederek uygulasa da içeriğin kullanıcı tarafından erişilebilir olması amaçlanmaz. Benzer şekilde, kaynak özel dosya sisteminin alt öğelerinin adlarıyla eşleşen adlara sahip dosya veya dizinlerin bulunması beklenmez. Tarayıcı, orijinal özel dosya sistemi olduğu için dosya varmış gibi görünse de bu "dosyaları" bir veritabanında veya başka bir veri yapısında saklayabilir. Bu API'yi kullanırsanız oluşturulan dosyaların sabit diskte bire bir eşleştiğini beklemeyin. Kök FileSystemDirectoryHandle
erişiminiz olduğunda, kaynak özel dosya sisteminde her zamanki gibi işlem yapabilirsiniz.
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 });
Performans için optimize edilmiş dosyalara kaynak gizli dosya sisteminden erişme
Kaynak özel dosya sistemi, performans için yüksek düzeyde optimize edilmiş özel bir dosya türüne isteğe bağlı erişim sağlar. Örneğin, bir dosyanın içeriğine yerinde ve özel yazma erişimi sunar. Chromium 102 ve sonraki sürümlerde, kaynak özel dosya sisteminde dosya erişimini basitleştirmek için ek bir yöntem bulunur: createSyncAccessHandle()
(eşzamanlı okuma ve yazma işlemleri için).
FileSystemFileHandle
üzerinde ancak yalnızca Web Çalışanlarında gösterilir.
// (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öntemlerini tamamen polyfill olarak doldurmak mümkün değildir.
showOpenFilePicker()
yöntemi,<input type="file">
öğesiyle yaklaşık olarak bulunabilir.showSaveFilePicker()
yöntemi,<a download="file_name">
öğesiyle simüle edilebilir. Ancak bu, programatik bir indirme tetikler ve mevcut dosyaların üzerine yazılmasına izin vermez.showDirectoryPicker()
yöntemi, standart olmayan<input type="file" webkitdirectory>
öğesiyle bir dereceye kadar taklit edilebilir.
Mümkün olduğunda File System Access API'yi kullanan ve diğer tüm durumlarda en iyi ikinci seçeneklere başvuran browser-fs-access adlı bir kitaplık geliştirdik.
Güvenlik ve izinler
Chrome ekibi, dosya sistemi erişim API'sini tasarlarken ve uygularken kullanıcı denetimi, şeffaflık ve kullanıcı ergonomisi gibi Güçlü Web Platformu Özelliklerine Erişimi Kontrol Etme başlıklı makalede tanımlanan temel ilkeleri temel almıştır.
Dosya açma veya yeni dosya kaydetme
Kullanıcı, dosya seçiciyi kullanarak bir dosyayı veya dizini okuma izni verir.
Açık dosya seçici, yalnızca güvenli bir bağlamda sunulurken kullanıcı hareketi kullanılarak gösterilebilir. Kullanıcılar fikrini değiştirirse dosya seçicideki seçimi iptal edebilir. Bu durumda site hiçbir şeye erişemez. Bu, <input type="file">
öğesiyle aynı davranıştır.
Benzer şekilde, bir web uygulaması yeni bir dosya kaydetmek istediğinde tarayıcı, dosya kaydediciyi gösterir. Bu sayede kullanıcı yeni dosyanın adını ve konumunu belirtebilir. Kullanıcı cihaza yeni bir dosya kaydettiğinde (mevcut bir dosyanın üzerine yazmadığında) dosya seçici, uygulamaya dosyaya yazma izni verir.
Kısıtlanmış klasörler
Tarayıcı, kullanıcıların ve verilerinin korunmasına yardımcı olmak için kullanıcının belirli klasörlere (ör. Windows gibi temel işletim sistemi klasörleri, macOS Kitaplık klasörleri) kaydetme özelliğini sınırlayabilir. Bu durumda tarayıcı bir istem gösterir ve kullanıcıdan farklı bir klasör seçmesini ister.
Mevcut bir dosyayı veya dizini değiştirme
Web uygulamaları, kullanıcıdan açık izin almadan diskteki bir dosyayı değiştiremez.
İzin istemi
Bir kullanıcı daha önce okuma erişimi verdiği bir dosyaya yaptığı değişiklikleri kaydetmek isterse tarayıcı, sitenin değişiklikleri diske yazması için izin isteyen bir izin istemi gösterir. İzin isteği yalnızca kullanıcı hareketiyle (ör. Kaydet düğmesini tıklayarak) tetiklenebilir.
Alternatif olarak, IDE gibi birden fazla dosyayı düzenleyen bir web uygulaması, açılma sırasında değişiklikleri kaydetme izni de isteyebilir.
Kullanıcı İptal'i seçip yazma erişimi vermezse web uygulaması, değişiklikleri yerel dosyaya kaydedemez. Örneğin, "dosyayı indirme" veya verileri buluta kaydetme gibi bir yöntem sunarak kullanıcının verilerini kaydetmesi için alternatif bir yöntem sağlamalıdır.
Şeffaflık
Kullanıcı bir web uygulamasına yerel dosya kaydetme izni verdiğinde tarayıcı, adres ç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ı dilediğinde bu erişimi iptal edebilir.
İzin kalıcılığı
Web uygulaması, kaynağına ait tüm sekmeler kapatılana kadar dosyaya yapılan değişiklikleri istemsiz olarak kaydetmeye devam edebilir. Bir sekme kapatıldığında site tüm erişimini kaybeder. Kullanıcı web uygulamasını bir sonraki sefer kullandığında, dosyalara erişim için tekrar istenir.
Geri bildirim
File System Access API ile ilgili deneyimlerinizi öğrenmek isteriz.
API tasarımı hakkında bilgi verin
API ile ilgili olarak beklediğiniz gibi çalışmayan bir şey var mı? Yoksa fikrinizi uygulamak için ihtiyaç duyduğunuz yöntemler veya özellikler eksik mi? Güvenlik modeliyle ilgili sorunuz veya yorumunuz mu var?
- WICG Dosya Sistemi Erişimi GitHub deposunda özellik sorunu gönderin veya mevcut bir soruna düşüncelerinizi ekleyin.
Uygulamayla ilgili sorun mu yaşıyorsunuz?
Chrome'un uygulamasında bir hata mı buldunuz? Yoksa uygulama, spesifikasyondan farklı mı?
- https://new.crbug.com adresinden hata bildirin. Mümkün olduğunca fazla ayrıntı ve yeniden oluşturma talimatları eklediğinizden emin olun ve Bileşenler'i
Blink>Storage>FileSystem
olarak ayarlayın. Glitch, hızlı yeniden oluşturma işlemlerini paylaşmak için mükemmel bir araçtır.
API'yi kullanmayı planlıyor musunuz?
Sitenizde File System Access API'yi kullanmayı planlıyor musunuz? Herkese açık desteğiniz, özelliklere öncelik vermemize yardımcı olur ve diğer tarayıcı tedarikçi firmalarına bu özellikleri desteklemenin ne kadar önemli olduğunu gösterir.
- WICG Discourse mesaj dizisinde bu özelliği nasıl kullanmayı planladığınızı paylaşın.
#FileSystemAccess
hashtag'ini kullanarak @ChromiumDev hesabına tweet gönderin ve bu özelliği nerede ve nasıl kullandığınızı bize bildirin.
Faydalı bağlantılar
- Herkese açık açıklama
- Dosya Sistemi Erişimi spesifikasyonu ve Dosya spesifikasyonu
- İzleme hatası
- ChromeStatus.com girişi
- TypeScript tanımları
- File System Access API - Chromium Güvenlik Modeli
- Blink Bileşeni:
Blink>Storage>FileSystem
Teşekkür ederiz
File System Access API spesifikasyonu Marijn Kruisselbrink tarafından yazılmıştır.