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

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

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

ऑरिजिन प्राइवेट फ़ाइल सिस्टम, आधुनिक ब्राउज़र के साथ काम करता है. साथ ही, इसे Web Hypertext Application Technology Working Group (WHATWG) ने File System Living Standard में स्टैंडर्ड के तौर पर शामिल किया है.

Browser Support

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

Source

वजह

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

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

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

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

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

इस फ़्लो से यह पता नहीं चलता कि उपयोगकर्ता, फ़ाइलों में बदलाव करने के बारे में क्या सोचते हैं. इसका मतलब है कि उपयोगकर्ताओं को अपनी इनपुट फ़ाइलों की डाउनलोड की गई कॉपी मिलती हैं. इसलिए, File System Access API ने तीन पिकर मेथड लॉन्च किए हैं:

ये कुकी, इस तरह से फ़्लो को चालू करती हैं:

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

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

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

इस वजह से, फ़ाइल से जुड़े काम करने में थोड़ा समय लगता है. हालांकि, जहां भी हो सका है वहां सुधार किए गए हैं. उदाहरण के लिए, macOS पर. हालांकि, हर write() कॉल में सभी ज़रूरी जानकारी शामिल होती है. इसलिए, यह फ़ाइल को खोलता है, दिए गए ऑफ़सेट को ढूंढता है, और आखिर में डेटा लिखता है.

प्रोसेसिंग के लिए फ़ाइलें

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

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

ऑपरेटिंग सिस्टम के फ़ाइल एक्सप्लोरर का इस्तेमाल करके, उपयोगकर्ता को दिखने वाले फ़ाइल सिस्टम में फ़ाइलों और फ़ोल्डर को पढ़ा, लिखा, एक जगह से दूसरी जगह ले जाया, और उनका नाम बदला जा सकता है. हालांकि, ओरिजिन प्राइवेट फ़ाइल सिस्टम को उपयोगकर्ताओं के लिए नहीं बनाया गया है. ओरिजन प्राइवेट फ़ाइल सिस्टम में मौजूद फ़ाइलें और फ़ोल्डर, नाम के मुताबिक निजी होते हैं. साथ ही, ये किसी साइट के ओरिजन के लिए निजी होते हैं. DevTools Console में location.origin टाइप करके, किसी पेज का ऑरिजिन पता करें. उदाहरण के लिए, पेज https://developer.chrome.com/articles/ का ऑरिजिन https://developer.chrome.com है. ऑरिजिन के सिद्धांत के बारे में ज़्यादा जानने के लिए, "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() को कॉल करके ऐक्सेस किया जाता है.

उपयोगकर्ता को दिखने वाले फ़ाइल सिस्टम और ऑरिजिन प्राइवेट फ़ाइल सिस्टम की तुलना करने के लिए, यह डायग्राम देखें. डायग्राम से पता चलता है कि रूट डायरेक्ट्री के अलावा, बाकी सब कुछ एक जैसा है. इसमें फ़ाइलों और फ़ोल्डर का क्रम होता है, ताकि आपके डेटा और स्टोरेज की ज़रूरतों के हिसाब से उन्हें व्यवस्थित किया जा सके.

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

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

ब्राउज़र में स्टोरेज के अन्य तरीकों (उदाहरण के लिए, 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 है. इसे सामान्य FileSystemFileHandle से createSyncAccessHandle() को कॉल करके हासिल किया जाता है.

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

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

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

  • getSize(): इससे फ़ाइल का साइज़ बाइट में मिलता है.
  • write(): Writes the content of a buffer into the file, optionally at a given offset, and returns the number of written bytes. लिखे गए बाइट की संख्या की जाँच करने से, कॉल करने वाले लोग गड़बड़ियों और आंशिक रूप से लिखे गए डेटा का पता लगा सकते हैं और उन्हें ठीक कर सकते हैं.
  • 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 Web Store में OPFS Explorer Chrome DevTools एक्सटेंशन.

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

डेमो

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

नतीजा

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

हम इस स्टैंडर्ड को लगातार बेहतर बना रहे हैं. इसलिए, अगर आपको कोई सुझाव, शिकायत या राय देनी है, तो whatwg/fs repository में जाकर, समस्याओं के बारे में बताएं या पुल अनुरोध करें.

Acknowledgements

इस दस्तावेज़ की समीक्षा ऑस्टिन सुली, एटिएन नोएल, और राशेल एंड्रू ने की है.