ऑरिजिन निजी फ़ाइल सिस्टम

फ़ाइल सिस्टम स्टैंडर्ड में, ऑरिजिन प्राइवेट फ़ाइल सिस्टम (ओपीएफ़एस) को स्टोरेज एंडपॉइंट के तौर पर शामिल किया गया है. यह ऑरिजिन के लिए निजी है और उपयोगकर्ता को नहीं दिखता. यह एक खास तरह की फ़ाइल का ऐक्सेस देता है, जो परफ़ॉर्मेंस के लिए काफ़ी ऑप्टिमाइज़ की गई है.

ब्राउज़र समर्थन

ओरिजिनल निजी फ़ाइल सिस्टम, आधुनिक ब्राउज़र पर काम करता है. साथ ही, इसे वेब हाइपरटेक्स्ट ऐप्लिकेशन टेक्नोलॉजी वर्किंग ग्रुप (WHATWG) ने फ़ाइल सिस्टम लिविंग स्टैंडर्ड में स्टैंडर्ड के तौर पर शामिल किया है.

ब्राउज़र के इस्तेमाल से जुड़ी सहायता

  • Chrome: 86.
  • Edge: 86.
  • Firefox: 111.
  • Safari: 15.2.

सोर्स

वजह

जब आपके कंप्यूटर पर फ़ाइलों के बारे में सोचा जाता है, तो शायद आपको फ़ाइल के क्रम के बारे में पता चलता है: फ़ाइलों को फ़ोल्डर में व्यवस्थित किया जाता है, जिन्हें आपके ऑपरेटिंग सिस्टम के फ़ाइल एक्सप्लोरर से एक्सप्लोर किया जा सकता है. उदाहरण के लिए, Windows पर, 'क्या-क्या करें' सूची, टॉम नाम के उपयोगकर्ता के लिए C:\Users\Tom\Documents\ToDo.txt में हो सकती है. इस उदाहरण में, ToDo.txt फ़ाइल का नाम है और Users, Tom, और Documents फ़ोल्डर के नाम हैं. Windows पर `C:`, ड्राइव की रूट डायरेक्ट्री को दिखाता है.

वेब पर फ़ाइलों के साथ काम करने का पारंपरिक तरीका

वेब ऐप्लिकेशन में 'क्या-क्या करें' सूची में बदलाव करने के लिए, यह सामान्य तरीका अपनाएं:

  1. उपयोगकर्ता, फ़ाइल को सर्वर पर अपलोड करता है या <input type="file"> की मदद से, क्लाइंट पर खोलता है.
  2. उपयोगकर्ता अपने बदलाव करता है और फिर इंजेक्ट की गई <a download="ToDo.txt> वाली फ़ाइल को डाउनलोड करता है. इस फ़ाइल को JavaScript की मदद से प्रोग्राम के हिसाब से click() किया जाता है.
  3. फ़ोल्डर खोलने के लिए, <input type="file" webkitdirectory> में एक खास एट्रिब्यूट का इस्तेमाल किया जाता है. इस एट्रिब्यूट का नाम मालिकाना है, लेकिन यह सभी ब्राउज़र पर काम करता है.

वेब पर फ़ाइलों के साथ काम करने का आधुनिक तरीका

इस फ़्लो से यह पता नहीं चलता कि उपयोगकर्ता फ़ाइलों में बदलाव कैसे करते हैं. इसका मतलब है कि उपयोगकर्ताओं के पास अपनी इनपुट फ़ाइलों की डाउनलोड की गई कॉपी होती हैं. इसलिए, File System Access API ने तीन पिकर तरीके पेश किए हैं—showOpenFilePicker(), showSaveFilePicker(), और showDirectoryPicker(). इनका नाम उनके काम के हिसाब से रखा गया है. वे इस तरह फ़्लो को चालू करते हैं:

  1. showOpenFilePicker() से ToDo.txt खोलें और FileSystemFileHandle ऑब्जेक्ट पाएं.
  2. FileSystemFileHandle ऑब्जेक्ट से, फ़ाइल हैंडल के getFile() तरीके को कॉल करके File पाएं.
  3. फ़ाइल में बदलाव करें. इसके बाद, हैंडल पर requestPermission({mode: 'readwrite'}) को कॉल करें.
  4. अगर उपयोगकर्ता अनुमति का अनुरोध स्वीकार करता है, तो बदलावों को ओरिजनल फ़ाइल में सेव करें.
  5. इसके अलावा, showSaveFilePicker() को कॉल करके, उपयोगकर्ता को कोई नई फ़ाइल चुनने दें. (अगर उपयोगकर्ता पहले खोली गई फ़ाइल चुनता है, तो उसका कॉन्टेंट ओवरराइट हो जाएगा.) फ़ाइल को बार-बार सेव करने के लिए, फ़ाइल हैंडल को सेव किया जा सकता है. इससे, आपको फ़ाइल सेव करने का डायलॉग बॉक्स फिर से नहीं दिखाना पड़ेगा.

वेब पर फ़ाइलों के साथ काम करने से जुड़ी पाबंदियां

इन तरीकों से ऐक्सेस की जा सकने वाली फ़ाइलें और फ़ोल्डर, उपयोगकर्ता को दिखने वाले फ़ाइल सिस्टम में मौजूद होते हैं. वेब से सेव की गई फ़ाइलों और खास तौर पर, एक्ज़ीक्यूटेबल फ़ाइलों को वेब का निशान लगाकर मार्क किया जाता है. इससे, ऑपरेटिंग सिस्टम किसी खतरनाक फ़ाइल को एक्ज़ीक्यूट करने से पहले, एक और चेतावनी दिखा सकता है. सुरक्षा से जुड़ी एक और सुविधा के तौर पर, वेब से ली गई फ़ाइलों को सुरक्षित ब्राउज़िंग की मदद से भी सुरक्षित रखा जाता है. इसे आसानी से समझने के लिए, इस लेख में इसे क्लाउड पर आधारित वायरस स्कैन के तौर पर समझा जा सकता है. File System Access API का इस्तेमाल करके किसी फ़ाइल में डेटा लिखने पर, डेटा को फ़ाइल में नहीं लिखा जाता. इसके बजाय, डेटा को किसी अस्थायी फ़ाइल में लिखा जाता है. फ़ाइल में तब तक कोई बदलाव नहीं किया जाता, जब तक वह सुरक्षा से जुड़ी इन सभी जांचों को पास नहीं कर लेती. जैसा कि आपने सोचा होगा, इस काम की वजह से फ़ाइलों के काम करने की प्रोसेस धीमी हो जाती है. हालांकि, जहां भी हो सके वहां सुधार किए गए हैं. उदाहरण के लिए, macOS पर. हालांकि, हर write() कॉल अपने-आप काम करता है. इसलिए, यह फ़ाइल खोलता है, दिए गए ऑफ़सेट पर जाता है, और आखिर में डेटा लिखता है.

प्रोसेसिंग के आधार के तौर पर फ़ाइलें

साथ ही, फ़ाइलें डेटा रिकॉर्ड करने का एक बेहतरीन तरीका हैं. उदाहरण के लिए, SQLite पूरे डेटाबेस को एक ही फ़ाइल में सेव करता है. इमेज प्रोसेसिंग में इस्तेमाल होने वाले mipmaps एक और उदाहरण हैं. मिपमैप, पहले से तय किए गए और ऑप्टिमाइज़ किए गए इमेज के क्रम होते हैं. इनमें से हर इमेज, पिछली इमेज के मुकाबले कम रिज़ॉल्यूशन में होती है. इससे ज़ूम करने जैसे कई काम तेज़ी से किए जा सकते हैं. तो वेब ऐप्लिकेशन, फ़ाइलों के फ़ायदे कैसे पा सकते हैं, लेकिन वेब-आधारित फ़ाइल प्रोसेसिंग की परफ़ॉर्मेंस की लागत के बिना? जवाब है, ओरिजिन निजी फ़ाइल सिस्टम.

उपयोगकर्ता को दिखने वाला बनाम ओरिजिन का निजी फ़ाइल सिस्टम

ऑपरेटिंग सिस्टम के फ़ाइल एक्सप्लोरर का इस्तेमाल करके ब्राउज़ किए जाने वाले, उपयोगकर्ता को दिखने वाले फ़ाइल सिस्टम के उलट, ओरिजिनल निजी फ़ाइल सिस्टम को उपयोगकर्ता नहीं देख सकते. इस सिस्टम में मौजूद फ़ाइलों और फ़ोल्डर को पढ़ा, लिखा, ट्रांसफ़र किया, और उनका नाम बदला जा सकता है. ऑरिजिन के निजी फ़ाइल सिस्टम में मौजूद फ़ाइलें और फ़ोल्डर निजी होती हैं. ज़्यादा सटीक तौर पर, ये किसी साइट के ऑरिजिन के लिए निजी होती हैं. DevTools कंसोल में location.origin टाइप करके, किसी पेज का ऑरिजिन देखें. उदाहरण के लिए, पेज https://developer.chrome.com/articles/ का ऑरिजिन https://developer.chrome.com है. इसका मतलब है कि /articles हिस्सा, ऑरिजिन का नहीं है. ऑरिजिन के सिद्धांत के बारे में ज़्यादा जानने के लिए, "same-site" और "same-origin" को समझना लेख पढ़ें. एक ही ऑरिजिन शेयर करने वाले सभी पेजों को, एक ही ऑरिजिन का निजी फ़ाइल सिस्टम डेटा दिख सकता है. इसलिए, https://developer.chrome.com/docs/extensions/mv3/getstarted/extensions-101/ को पिछले उदाहरण जैसी ही जानकारी दिख सकती है. हर ऑरिजिन का अपना निजी फ़ाइल सिस्टम होता है. इसका मतलब है कि https://developer.chrome.com का निजी फ़ाइल सिस्टम, https://web.dev के निजी फ़ाइल सिस्टम से पूरी तरह अलग होता है. Windows पर, उपयोगकर्ता को दिखने वाले फ़ाइल सिस्टम की रूट डायरेक्ट्री C:\\ होती है. ओरिजिन के निजी फ़ाइल सिस्टम के बराबर, हर ओरिजिन के लिए एक रूट डायरेक्ट्री होती है. इसे ऐसिंक्रोनस तरीके navigator.storage.getDirectory() को कॉल करके ऐक्सेस किया जाता है. उपयोगकर्ता को दिखने वाले फ़ाइल सिस्टम और ओरिजनल निजी फ़ाइल सिस्टम की तुलना करने के लिए, नीचे दिया गया डायग्राम देखें. इस डायग्राम से पता चलता है कि रूट डायरेक्ट्री के अलावा, बाकी सब कुछ एक जैसा है. इसमें फ़ाइलों और फ़ोल्डर की हैरारकी होती है, ताकि आपके डेटा और स्टोरेज की ज़रूरतों के हिसाब से उन्हें व्यवस्थित किया जा सके.

उपयोगकर्ता को दिखने वाले फ़ाइल सिस्टम और ओरिजिन के निजी फ़ाइल सिस्टम का डायग्राम. इसमें, फ़ाइल के लेआउट की दो उदाहरण के तौर पर दी गई हैरारकी दिखाई गई है. उपयोगकर्ता को दिखने वाले फ़ाइल सिस्टम का एंट्री पॉइंट, एक सिंबल हार्डडिस्क है. ऑरिजिन के निजी फ़ाइल सिस्टम का एंट्री पॉइंट, &#39;navigator.storage.getDirectory&#39; मेथड को कॉल करना है.

ओरिजिन के निजी फ़ाइल सिस्टम की खास जानकारी

ब्राउज़र में मौजूद अन्य स्टोरेज सिस्टम (जैसे, localStorage या IndexedDB) की तरह ही, ऑरिजिन प्राइवेट फ़ाइल सिस्टम पर भी ब्राउज़र के कोटा से जुड़ी पाबंदियां लागू होती हैं. जब कोई उपयोगकर्ता ब्राउज़िंग का पूरा डेटा मिटाता है या साइट का पूरा डेटा मिटाता है, तो ऑरिजिन निजी फ़ाइल सिस्टम भी मिट जाएगा. navigator.storage.estimate() को कॉल करें और रिस्पॉन्स ऑब्जेक्ट में usage एंट्री देखें. इससे आपको पता चलेगा कि आपका ऐप्लिकेशन पहले से कितना स्टोरेज इस्तेमाल कर रहा है. इसे usageDetails ऑब्जेक्ट में स्टोरेज के तरीके के हिसाब से बांटा गया है. यहां आपको खास तौर पर fileSystem एंट्री देखनी होगी. उपयोगकर्ता को ओरिजिन का निजी फ़ाइल सिस्टम नहीं दिखता है. इसलिए, अनुमतियों के लिए कोई प्रॉम्प्ट नहीं दिखता और सुरक्षित ब्राउज़िंग की जांच भी नहीं की जाती.

रूट डायरेक्ट्री का ऐक्सेस पाना

रूट डायरेक्ट्री का ऐक्सेस पाने के लिए, यह कमांड चलाएं. आपको खाली डायरेक्ट्री हैंडल मिलता है, खास तौर पर FileSystemDirectoryHandle.

const opfsRoot = await navigator.storage.getDirectory();
// A FileSystemDirectoryHandle whose type is "directory"
// and whose name is "".
console.log(opfsRoot);

मुख्य थ्रेड या वेब वर्कर

ऑरिजिन के निजी फ़ाइल सिस्टम का इस्तेमाल करने के दो तरीके हैं: मुख्य थ्रेड पर या वेब वर्कर्स में. वेब वर्कर्स, मुख्य थ्रेड को ब्लॉक नहीं कर सकते. इसका मतलब है कि इस संदर्भ में एपीआई सिंक्रोनस हो सकते हैं. आम तौर पर, मुख्य थ्रेड पर सिंक्रोनस पैटर्न का इस्तेमाल नहीं किया जा सकता. सिंक्रोनस एपीआई ज़्यादा तेज़ हो सकते हैं, क्योंकि उन्हें प्रॉमिस से निपटने की ज़रूरत नहीं होती. साथ ही, C जैसी भाषाओं में फ़ाइल ऑपरेशन आम तौर पर सिंक्रोनस होते हैं, जिन्हें WebAssembly में कंपाइल किया जा सकता है.

// This is synchronous C code.
FILE *f;
f = fopen("example.txt", "w+");
fputs("Some text\n", f);
fclose(f);

अगर आपको फ़ाइलों पर तेज़ी से काम करने की ज़रूरत है या आपको WebAssembly का इस्तेमाल करना है, तो वेब वर्कर्स में ऑरिजिन के निजी फ़ाइल सिस्टम का इस्तेमाल करना पर जाएं. इसके अलावा, आगे पढ़ना जारी रखा जा सकता है.

मुख्य थ्रेड पर ऑरिजिन के निजी फ़ाइल सिस्टम का इस्तेमाल करना

नई फ़ाइलें और फ़ोल्डर बनाना

रूट फ़ोल्डर बनाने के बाद, getFileHandle() और getDirectoryHandle() तरीकों का इस्तेमाल करके फ़ाइलें और फ़ोल्डर बनाएं. {create: true} को पास करने पर, फ़ाइल या फ़ोल्डर मौजूद न होने पर उसे बनाया जाएगा. नई बनाई गई डायरेक्ट्री को शुरुआती पॉइंट के तौर पर इस्तेमाल करके, इन फ़ंक्शन को कॉल करके फ़ाइलों की हैरारकी बनाएं.

const fileHandle = await opfsRoot
    .getFileHandle('my first file', {create: true});
const directoryHandle = await opfsRoot
    .getDirectoryHandle('my first folder', {create: true});
const nestedFileHandle = await directoryHandle
    .getFileHandle('my first nested file', {create: true});
const nestedDirectoryHandle = await directoryHandle
    .getDirectoryHandle('my first nested folder', {create: true});

पिछले कोड सैंपल से मिली फ़ाइल हैरारकी.

मौजूदा फ़ाइलें और फ़ोल्डर ऐक्सेस करना

अगर आपको उनका नाम पता है, तो getFileHandle() या getDirectoryHandle() तरीकों को कॉल करके, पहले से बनाई गई फ़ाइलों और फ़ोल्डर को ऐक्सेस करें. इसके लिए, फ़ाइल या फ़ोल्डर का नाम डालें.

const existingFileHandle = await opfsRoot.getFileHandle('my first file');
const existingDirectoryHandle = await opfsRoot
    .getDirectoryHandle('my first folder');

पढ़ने के लिए, फ़ाइल हैंडल से जुड़ी फ़ाइल पाना

FileSystemFileHandle, फ़ाइल सिस्टम में मौजूद किसी फ़ाइल को दिखाता है. इससे जुड़ा File पाने के लिए, getFile() तरीके का इस्तेमाल करें. File ऑब्जेक्ट, Blob का एक खास टाइप है. इसका इस्तेमाल उसी तरह से किया जा सकता है जिस तरह Blob का किया जा सकता है. खास तौर पर, FileReader, URL.createObjectURL(), createImageBitmap(), और XMLHttpRequest.send(), Blobs और Files, दोनों को स्वीकार करते हैं. अगर आप चाहें, तो FileSystemFileHandle से File पाने पर डेटा "मुक्त" हो जाता है, ताकि आप उसे ऐक्सेस कर सकें और उपयोगकर्ता को दिखने वाले फ़ाइल सिस्टम के लिए उपलब्ध कर सकें.

const file = await fileHandle.getFile();
console.log(await file.text());

स्ट्रीम करके किसी फ़ाइल में लिखना

createWritable() को कॉल करके, डेटा को फ़ाइल में स्ट्रीम करें. इससे FileSystemWritableFileStream बनता है, जिसमें कॉन्टेंट को write() किया जाता है. आखिर में, आपको स्ट्रीम close() करनी होगी.

const contents = 'Some text';
// Get a writable stream.
const writable = await fileHandle.createWritable();
// Write the contents of the file to the stream.
await writable.write(contents);
// Close the stream, which persists the contents.
await writable.close();

फ़ाइलें और फ़ोल्डर मिटाना

फ़ाइलों और फ़ोल्डर को मिटाने के लिए, उनकी फ़ाइल या डायरेक्ट्री हैंडल के खास remove() तरीके को कॉल करें. किसी फ़ोल्डर और उसमें मौजूद सभी सब-फ़ोल्डर को मिटाने के लिए, {recursive: true} विकल्प पास करें.

await fileHandle.remove();
await directoryHandle.remove({recursive: true});

इसके अलावा, अगर आपको किसी डायरेक्ट्री में मौजूद उस फ़ाइल या फ़ोल्डर का नाम पता है जिसे मिटाना है, तो removeEntry() तरीके का इस्तेमाल करें.

directoryHandle.removeEntry('my first nested file');

फ़ाइलों और फ़ोल्डर को एक जगह से दूसरी जगह ले जाना और उनका नाम बदलना

move() तरीके का इस्तेमाल करके, फ़ाइलों और फ़ोल्डर के नाम बदलें और उन्हें एक से दूसरी जगह ले जाएं. फ़ाइल को एक से दूसरी जगह ले जाने और उसका नाम बदलने की प्रोसेस को एक साथ या अलग-अलग किया जा सकता है.

// Rename a file.
await fileHandle.move('my first renamed file');
// Move a file to another directory.
await fileHandle.move(nestedDirectoryHandle);
// Move a file to another directory and rename it.
await fileHandle
    .move(nestedDirectoryHandle, 'my first renamed and now nested file');

किसी फ़ाइल या फ़ोल्डर का पाथ हल करना

किसी फ़ाइल या फ़ोल्डर के रेफ़रंस डायरेक्ट्री में मौजूद होने की जगह जानने के लिए, resolve() तरीके का इस्तेमाल करें. इसके लिए, उसे आर्ग्युमेंट के तौर पर FileSystemHandle दें. ओरिजनल निजी फ़ाइल सिस्टम में किसी फ़ाइल या फ़ोल्डर का पूरा पाथ पाने के लिए, navigator.storage.getDirectory() से मिली रेफ़रंस डायरेक्ट्री के तौर पर रूट डायरेक्ट्री का इस्तेमाल करें.

const relativePath = await opfsRoot.resolve(nestedDirectoryHandle);
// `relativePath` is `['my first folder', 'my first nested folder']`.

यह देखना कि दो फ़ाइल या फ़ोल्डर हैंडल, एक ही फ़ाइल या फ़ोल्डर पर ले जाते हैं या नहीं

कभी-कभी आपके पास दो हैंडल होते हैं और आपको नहीं पता कि वे एक ही फ़ाइल या फ़ोल्डर पर ले जाते हैं या नहीं. क्या वाकई यही समस्या है, यह पता लगाने के लिए isSameEntry() तरीके का इस्तेमाल करें.

fileHandle.isSameEntry(nestedFileHandle);
// Returns `false`.

किसी फ़ोल्डर के कॉन्टेंट की सूची बनाना

FileSystemDirectoryHandle एक असाइनोक्रोनस इटरेट है. इसे for await…of लूप की मदद से, बार-बार दोहराया जाता है. यह एक असाइनोक्रोनस (एक साथ कई काम करने वाला) आइटरर है. यह entries(), values(), और keys() तरीकों के साथ भी काम करता है. इनमें से आपको अपनी ज़रूरत के हिसाब से कोई भी तरीका चुनना होगा:

for await (let [name, handle] of directoryHandle) {}
for await (let [name, handle] of directoryHandle.entries()) {}
for await (let handle of directoryHandle.values()) {}
for await (let name of directoryHandle.keys()) {}

किसी फ़ोल्डर और उसके सभी सब-फ़ोल्डर के कॉन्टेंट की सूची बार-बार बनाना

बार-बार दोहराए जाने वाले फ़ंक्शन के साथ काम करने वाले एसिंक्रोनस लूप और फ़ंक्शन को समझना आसान नहीं है. नीचे दिया गया फ़ंक्शन, किसी फ़ोल्डर और उसके सभी सब-फ़ोल्डर के कॉन्टेंट की सूची बनाने के लिए शुरुआती बिंदु के तौर पर काम कर सकता है. इसमें सभी फ़ाइलें और उनके साइज़ भी शामिल हैं. अगर आपको फ़ाइल के साइज़ की जानकारी की ज़रूरत नहीं है, तो फ़ंक्शन को आसान बनाया जा सकता है. इसके लिए, directoryEntryPromises.push के बजाय handle.getFile() के प्रॉमिस को न डालें और सीधे handle डालें.

  const getDirectoryEntriesRecursive = async (
    directoryHandle,
    relativePath = '.',
  ) => {
    const fileHandles = [];
    const directoryHandles = [];
    const entries = {};
    // Get an iterator of the files and folders in the directory.
    const directoryIterator = directoryHandle.values();
    const directoryEntryPromises = [];
    for await (const handle of directoryIterator) {
      const nestedPath = `${relativePath}/${handle.name}`;
      if (handle.kind === 'file') {
        fileHandles.push({ handle, nestedPath });
        directoryEntryPromises.push(
          handle.getFile().then((file) => {
            return {
              name: handle.name,
              kind: handle.kind,
              size: file.size,
              type: file.type,
              lastModified: file.lastModified,
              relativePath: nestedPath,
              handle
            };
          }),
        );
      } else if (handle.kind === 'directory') {
        directoryHandles.push({ handle, nestedPath });
        directoryEntryPromises.push(
          (async () => {
            return {
              name: handle.name,
              kind: handle.kind,
              relativePath: nestedPath,
              entries:
                  await getDirectoryEntriesRecursive(handle, nestedPath),
              handle,
            };
          })(),
        );
      }
    }
    const directoryEntries = await Promise.all(directoryEntryPromises);
    directoryEntries.forEach((directoryEntry) => {
      entries[directoryEntry.name] = directoryEntry;
    });
    return entries;
  };

वेब वर्कर्स में ऑरिजिन के निजी फ़ाइल सिस्टम का इस्तेमाल करना

जैसा कि पहले बताया गया है, वेब वर्कर्स मुख्य थ्रेड को ब्लॉक नहीं कर सकते. इसलिए, इस संदर्भ में सिंक्रोनस तरीकों की अनुमति है.

सिंक्रोनस ऐक्सेस हैंडल पाना

फ़ाइल से जुड़े सबसे तेज़ ऑपरेशन का एंट्री पॉइंट FileSystemSyncAccessHandle है. इसे createSyncAccessHandle() को कॉल करके, सामान्य FileSystemFileHandle से पाया जाता है.

const fileHandle = await opfsRoot
    .getFileHandle('my highspeed file.txt', {create: true});
const syncAccessHandle = await fileHandle.createSyncAccessHandle();

फ़ाइल को सिंक्रोनस तरीके से बदलने के तरीके

सिंक्रोनस ऐक्सेस हैंडल मिलने के बाद, आपको फ़ाइल में बदलाव करने के तेज़ तरीकों का ऐक्सेस मिलता है. ये सभी तरीके सिंक्रोनस होते हैं.

  • getSize(): यह फ़ाइल का साइज़ बाइट में दिखाता है.
  • write(): यह फ़ंक्शन, बफ़र के कॉन्टेंट को फ़ाइल में लिखता है. इसके लिए, किसी दिए गए ऑफ़सेट का इस्तेमाल किया जा सकता है. साथ ही, यह लिखे गए बाइट की संख्या दिखाता है. लिखे गए बाइट की संख्या की जांच करने से, कॉलर को गड़बड़ियों और कुछ हिस्से को लिखने की समस्या का पता लगाने और उसे मैनेज करने में मदद मिलती है.
  • read(): यह फ़ाइल के कॉन्टेंट को बफ़र में पढ़ता है. इसके लिए, किसी दिए गए ऑफ़सेट का इस्तेमाल किया जा सकता है.
  • truncate(): यह विकल्प चुनने पर, फ़ाइल का साइज़ तय किए गए साइज़ में बदल जाता है.
  • flush(): यह पक्का करता है कि फ़ाइल के कॉन्टेंट में, write() की मदद से किए गए सभी बदलाव शामिल हैं.
  • close(): ऐक्सेस हैंडल को बंद करता है.

यहां एक उदाहरण दिया गया है, जिसमें ऊपर बताए गए सभी तरीकों का इस्तेमाल किया गया है.

const opfsRoot = await navigator.storage.getDirectory();
const fileHandle = await opfsRoot.getFileHandle('fast', {create: true});
const accessHandle = await fileHandle.createSyncAccessHandle();

const textEncoder = new TextEncoder();
const textDecoder = new TextDecoder();

// Initialize this variable for the size of the file.
let size;
// The current size of the file, initially `0`.
size = accessHandle.getSize();
// Encode content to write to the file.
const content = textEncoder.encode('Some text');
// Write the content at the beginning of the file.
accessHandle.write(content, {at: size});
// Flush the changes.
accessHandle.flush();
// The current size of the file, now `9` (the length of "Some text").
size = accessHandle.getSize();

// Encode more content to write to the file.
const moreContent = textEncoder.encode('More content');
// Write the content at the end of the file.
accessHandle.write(moreContent, {at: size});
// Flush the changes.
accessHandle.flush();
// The current size of the file, now `21` (the length of
// "Some textMore content").
size = accessHandle.getSize();

// Prepare a data view of the length of the file.
const dataView = new DataView(new ArrayBuffer(size));

// Read the entire file into the data view.
accessHandle.read(dataView);
// Logs `"Some textMore content"`.
console.log(textDecoder.decode(dataView));

// Read starting at offset 9 into the data view.
accessHandle.read(dataView, {at: 9});
// Logs `"More content"`.
console.log(textDecoder.decode(dataView));

// Truncate the file after 4 bytes.
accessHandle.truncate(4);

किसी फ़ाइल को ओरिजनल निजी फ़ाइल सिस्टम से, उपयोगकर्ता को दिखने वाले फ़ाइल सिस्टम में कॉपी करना

जैसा कि ऊपर बताया गया है, फ़ाइलों को ओरिजनल निजी फ़ाइल सिस्टम से, उपयोगकर्ता को दिखने वाले फ़ाइल सिस्टम में नहीं ले जाया जा सकता. हालांकि, फ़ाइलों को कॉपी किया जा सकता है. showSaveFilePicker() सिर्फ़ मुख्य थ्रेड में दिखता है, न कि वर्क थ्रेड में. इसलिए, कोड को मुख्य थ्रेड में चलाना न भूलें.

// On the main thread, not in the Worker. This assumes
// `fileHandle` is the `FileSystemFileHandle` you obtained
// the `FileSystemSyncAccessHandle` from in the Worker
// thread. Be sure to close the file in the Worker thread first.
const fileHandle = await opfsRoot.getFileHandle('fast');
try {
  // Obtain a file handle to a new file in the user-visible file system
  // with the same name as the file in the origin private file system.
  const saveHandle = await showSaveFilePicker({
    suggestedName: fileHandle.name || ''
  });
  const writable = await saveHandle.createWritable();
  await writable.write(await fileHandle.getFile());
  await writable.close();
} catch (err) {
  console.error(err.name, err.message);
}

ओरिजनल प्राइवेट फ़ाइल सिस्टम को डीबग करना

जब तक DevTools में पहले से मौजूद सहायता नहीं जोड़ी जाती (crbug/1284595 देखें), तब तक ऑरिजिन प्राइवेट फ़ाइल सिस्टम को डीबग करने के लिए, OPFS Explorer Chrome एक्सटेंशन का इस्तेमाल करें. ऊपर दिया गया स्क्रीनशॉट, नई फ़ाइलें और फ़ोल्डर बनाना सेक्शन से लिया गया है.

Chrome वेब स्टोर में OPFS Explorer Chrome DevTools एक्सटेंशन.

एक्सटेंशन इंस्टॉल करने के बाद, Chrome DevTools खोलें और OPFS एक्सप्लोरर टैब चुनें. इसके बाद, फ़ाइल हैरारकी की जांच की जा सकती है. फ़ाइल के नाम पर क्लिक करके, ओरिजनल निजी फ़ाइल सिस्टम से, उपयोगकर्ता को दिखने वाले फ़ाइल सिस्टम में फ़ाइलें सेव करें. साथ ही, ट्रैश कैन आइकॉन पर क्लिक करके, फ़ाइलों और फ़ोल्डर को मिटाएं.

डेमो

OPFS एक्सप्लोरर एक्सटेंशन इंस्टॉल करने पर, ऑरिजिन प्राइवेट फ़ाइल सिस्टम को डेमो में काम करते हुए देखें. यह डेमो, WebAssembly में कंपाइल किए गए SQLite डेटाबेस के लिए, ऑरिजिन प्राइवेट फ़ाइल सिस्टम का इस्तेमाल बैकएंड के तौर पर करता है. Glitch पर सोर्स कोड देखना न भूलें. ध्यान दें कि यहां एम्बेड किया गया वर्शन, ऑरिजिन के निजी फ़ाइल सिस्टम के बैकएंड का इस्तेमाल नहीं करता. ऐसा इसलिए है, क्योंकि iframe क्रॉस-ऑरिजिन है. हालांकि, डेमो को किसी अलग टैब में खोलने पर, यह बैकएंड का इस्तेमाल करता है.

मीटिंग में सामने आए नतीजे

WHATWG के मुताबिक, ओरिजिन निजी फ़ाइल सिस्टम ने वेब पर फ़ाइलों को इस्तेमाल करने और उनसे इंटरैक्ट करने के तरीके को तय किया है. इससे, इस्तेमाल के ऐसे नए उदाहरणों को शामिल किया जा सका जिन्हें उपयोगकर्ता के लिए उपलब्ध फ़ाइल सिस्टम की मदद से हासिल नहीं किया जा सकता था. ब्राउज़र के सभी मुख्य वेंडर, जैसे कि Apple, Mozilla, और Google, इस प्रोग्राम में शामिल हैं और एक ही लक्ष्य के लिए काम कर रहे हैं. ओरिजिनल निजी फ़ाइल सिस्टम को बनाने में, कई लोगों की मदद ली जाती है. साथ ही, डेवलपर और उपयोगकर्ताओं के सुझाव, राय या शिकायतें इसकी बेहतरी के लिए ज़रूरी हैं. हम इस स्टैंडर्ड को बेहतर बनाना जारी रखेंगे. इसलिए, whatwg/fs रिपॉज़िटरी के बारे में समस्याओं या पुल रिक्वेस्ट के तौर पर सुझाव, राय या शिकायत भेजें.

आभार

इस लेख की समीक्षा ऑस्टिन सुली, एटिएन नोएल, और रेचल एंड्रयू ने की. Unsplash पर क्रिस्टीना रम्फ़ की हीरो इमेज.