File System Access API: लोकल फ़ाइलों का ऐक्सेस आसान बनाना

File System Access API की मदद से वेब ऐप्लिकेशन, उपयोगकर्ता के डिवाइस पर मौजूद फ़ाइलों और फ़ोल्डर में किए गए बदलावों को सीधे पढ़ सकते हैं या सेव कर सकते हैं.

फ़ाइल सिस्टम ऐक्सेस एपीआई क्या है?

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

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

File System Access API, ज़्यादातर Chromium ब्राउज़र पर काम करती है Windows, macOS, ChromeOS, और Linux. एक बड़ा अपवाद है Brave फ़िलहाल, सिर्फ़ फ़्लैग के पीछे उपलब्ध है. crbug.com/1011535 के संदर्भ में, Android की सुविधा पर काम किया जा रहा है.

File System Access API का इस्तेमाल करना

फ़ाइल सिस्टम ऐक्सेस API (एपीआई) की खूबी और उपयोगिता दिखाने के लिए, मैंने एक फ़ाइल टेक्स्ट Editor. इससे आपको टेक्स्ट फ़ाइल खोलने, उसमें बदलाव करने, और बदलावों को डिस्क पर वापस सेव करने या किसी कार्ड को शुरू करने में मदद मिलती है और बदलावों को डिस्क पर सेव करें. यह फ़ैंसी नहीं है, लेकिन इसमें आपकी मदद करने के लिए काफ़ी जानकारी है समझने में मदद मिलती है.

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

ब्राउज़र सहायता

  • Chrome: 86. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
  • एज: 86. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
  • Firefox: समर्थित नहीं. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
  • Safari: समर्थित नहीं. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है

सोर्स

सुविधा की पहचान

यह जानने के लिए कि फ़ाइल सिस्टम ऐक्सेस एपीआई काम करता है या नहीं, देखें कि पिकर तरीका आपकी दिलचस्पी है.

if ('showOpenFilePicker' in self) {
  // The `showOpenFilePicker()` method of the File System Access API is supported.
}

इसे आज़माएं

फ़ाइल सिस्टम ऐक्सेस एपीआई को काम करते हुए देखें टेक्स्ट एडिटर का डेमो.

डिवाइस के फ़ाइल सिस्टम से फ़ाइल पढ़ना

इसके लिए, सबसे पहले उपयोगकर्ता से एक फ़ाइल चुनने के लिए कहें. इसके बाद, उसे खोलें और पढ़ें फ़ाइल से कॉपी किया जा सकता है.

पढ़ने के लिए उपयोगकर्ता को कोई फ़ाइल चुनने के लिए कहें

फ़ाइल सिस्टम ऐक्सेस एपीआई का एंट्री पॉइंट यह है window.showOpenFilePicker(). कॉल किए जाने पर, यह फ़ाइल पिकर का डायलॉग दिखाता है, और उपयोगकर्ता को एक फ़ाइल चुनने का निर्देश देता है. फ़ाइल चुनने के बाद, एपीआई, फ़ाइल का कलेक्शन दिखाता है हैंडल करता है. विकल्प के तौर पर options पैरामीटर की मदद से, फ़ाइल पिकर के व्यवहार को बदला जा सकता है उदाहरण के लिए, उपयोगकर्ता को कई फ़ाइलें, डायरेक्ट्री या अलग-अलग तरह की फ़ाइलें चुनने की अनुमति देना. कोई भी विकल्प तय किए बिना, फ़ाइल पिकर से उपयोगकर्ता एक फ़ाइल चुन सकते हैं. यह है यह टेक्स्ट एडिटर के लिए बेहतरीन है.

कई अन्य बेहतर एपीआई की तरह, showOpenFilePicker() को भी सुरक्षित तरीके से कॉल किया जाना चाहिए कॉन्टेक्स्ट के साथ ही इस्तेमाल किया जाना चाहिए. साथ ही, इसे उपयोगकर्ता के जेस्चर से ही कॉल किया जाना चाहिए.

let fileHandle;
butOpenFile.addEventListener('click', async () => {
  // Destructure the one-element array.
  [fileHandle] = await window.showOpenFilePicker();
  // Do something with the file handle.
});

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

फ़ाइल के हैंडल का रेफ़रंस रखना बेहतर रहता है, ताकि इसे बाद में इस्तेमाल किया जा सके. यह होगा फ़ाइल में बदलाव सेव करने या फ़ाइल से जुड़ी कोई अन्य कार्रवाई करने के लिए ज़रूरी है.

फ़ाइल सिस्टम से फ़ाइल पढ़ना

अब आपके पास फ़ाइल का हैंडल है, तो आपके पास फ़ाइल की प्रॉपर्टी देखने या उस फ़ाइल को ऐक्सेस करने का विकल्प है. फ़िलहाल, मैं इसका कॉन्टेंट पढ़ूँगी. handle.getFile() को कॉल करने पर, File वाला मैसेज दिखेगा ऑब्जेक्ट होता है, जिसमें एक BLOB होता है. ब्लॉब से डेटा प्राप्त करने के लिए, इसके किसी तरीके, (slice(), stream(), text() या arrayBuffer()).

const file = await fileHandle.getFile();
const contents = await file.text();

FileSystemFileHandle.getFile() से मिले File ऑब्जेक्ट को सिर्फ़ तब तक पढ़ा जा सकता है, जब तक डिस्क पर मौजूद फ़ाइल नहीं बदली है. अगर डिस्क पर मौजूद फ़ाइल में बदलाव किया जाता है, तो File ऑब्जेक्ट बन जाता है पढ़ा नहीं जा सकता. बदलावों को पढ़ने के लिए, आपको नया File ऑब्जेक्ट पाने के लिए getFile() को फिर से कॉल करना होगा डेटा शामिल है.

यह रही पूरी जानकारी

जब उपयोगकर्ता खोलें बटन पर क्लिक करते हैं, तब ब्राउज़र एक फ़ाइल पिकर दिखाता है. जब वे कोई फ़ाइल चुन लेते हैं, तो ऐप्लिकेशन कॉन्टेंट को पढ़ता है और उन्हें <textarea> में डाल देता है.

let fileHandle;
butOpenFile.addEventListener('click', async () => {
  [fileHandle] = await window.showOpenFilePicker();
  const file = await fileHandle.getFile();
  const contents = await file.text();
  textArea.value = contents;
});

लोकल फ़ाइल सिस्टम में फ़ाइल लिखें

टेक्स्ट एडिटर में, फ़ाइल को सेव करने के दो तरीके हैं: सेव करें और इस रूप में सेव करें. सेव करें पहले वापस लाए गए फ़ाइल हैंडल का इस्तेमाल करके, बदलावों को मूल फ़ाइल में वापस लिखता है. लेकिन सेव करें जैसे एक नई फ़ाइल बनाता है, इसलिए नए फ़ाइल हैंडल की ज़रूरत होती है.

एक नई फ़ाइल बनाएं

फ़ाइल सेव करने के लिए, showSaveFilePicker() पर कॉल करें. इससे आपको फ़ाइल पिकर दिखेगा "सेव करें" में मोड है, जिससे उपयोगकर्ता नई फ़ाइल चुन सकता है जिसे वह सेव करने के लिए इस्तेमाल करना चाहता है. टेक्स्ट के लिए Editor, मैं चाहता था कि यह अपने-आप एक .txt एक्सटेंशन भी जोड़ दे. इसलिए, मैंने कुछ अतिरिक्त पैरामीटर का इस्तेमाल करें.

async function getNewFileHandle() {
  const options = {
    types: [
      {
        description: 'Text Files',
        accept: {
          'text/plain': ['.txt'],
        },
      },
    ],
  };
  const handle = await window.showSaveFilePicker(options);
  return handle;
}

डिस्क पर किए गए बदलावों को सेव करें

किसी फ़ाइल में किए गए बदलावों को सेव करने का तरीका, आपको मेरे टेक्स्ट एडिटर डेमो में मिल जाएगा GitHub. फ़ाइल सिस्टम के मुख्य इंटरैक्शन इसमें हैं fs-helpers.js. सबसे आसान तरीके से, यह प्रोसेस नीचे दिए गए कोड की तरह दिखेगी. मैं आपको हर चरण पर बताऊंगी और इसके बारे में विस्तार से बताऊंगी.

// 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();
}

डिस्क पर डेटा लिखने के लिए एक FileSystemWritableFileStream ऑब्जेक्ट का इस्तेमाल किया जाता है, जो एक सब-क्लास है WritableStream में से. फ़ाइल में createWritable() को कॉल करके स्ट्रीम बनाएं हैंडल ऑब्जेक्ट के साथ जोड़ा जा सकता है. createWritable() को कॉल करने पर, ब्राउज़र पहले यह जांच करता है कि उपयोगकर्ता ने अनुमति दी है या नहीं फ़ाइल में लिखने की अनुमति है. अगर लिखने की अनुमति नहीं दी गई है, तो ब्राउज़र अनुरोध करता है उसके लिए अनुमति दें. अगर अनुमति नहीं दी जाती है, तो createWritable() DOMException के लिए सेव किया गया है और ऐप्लिकेशन इस फ़ाइल में बदलाव नहीं कर पाएगा. टेक्स्ट एडिटर में, DOMException ऑब्जेक्ट, saveFile() तरीके में मैनेज किए जाते हैं.

write() तरीका एक स्ट्रिंग लेता है. टेक्स्ट एडिटर के लिए इसकी ज़रूरत होती है. हालांकि, इसमें यह जानकारी भी लग सकती है BufferSource या Blob दबाएं. उदाहरण के लिए, किसी स्ट्रीम को सीधे यह:

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.
}

आपके पास स्ट्रीम में seek() या truncate() का इस्तेमाल करके, फ़ाइल को किसी खास जगह पर रखना या उसका साइज़ बदलना है.

सुझाया गया फ़ाइल नाम तय करके, डायरेक्ट्री शुरू करें

कई मामलों में हो सकता है कि आप अपने ऐप्लिकेशन को किसी डिफ़ॉल्ट फ़ाइल नाम या जगह का सुझाव देना चाहें. उदाहरण के लिए, टेक्स्ट संपादक Untitled के बजाय Untitled Text.txt के डिफ़ॉल्ट फ़ाइल नाम का सुझाव दे सकता है. आपने लोगों तक पहुंचाया मुफ़्त में ऐसा करने के लिए, showSaveFilePicker के विकल्पों में से suggestedName प्रॉपर्टी को पास करें.

const fileHandle = await self.showSaveFilePicker({
  suggestedName: 'Untitled Text.txt',
  types: [{
    description: 'Text documents',
    accept: {
      'text/plain': ['.txt'],
    },
  }],
});

डिफ़ॉल्ट शुरुआती डायरेक्ट्री पर भी यही बात लागू होती है. अगर आप टेक्स्ट एडिटर बना रहे हैं, तो फ़ाइल सेव करने या फ़ाइल खोलने का डायलॉग बॉक्स, डिफ़ॉल्ट documents फ़ोल्डर में शुरू किया जाता है, जबकि किसी इमेज के लिए एडिटर, डिफ़ॉल्ट pictures फ़ोल्डर में शुरू किया जा सकता है. आप डिफ़ॉल्ट शुरू करने का सुझाव दे सकते हैं निर्देशिका को showSaveFilePicker, showDirectoryPicker() पर startIn प्रॉपर्टी पास करके या showOpenFilePicker तरीके भी इस्तेमाल किए जा सकते हैं.

const fileHandle = await self.showOpenFilePicker({
  startIn: 'pictures'
});

जानी-मानी सिस्टम डायरेक्ट्री की सूची यहां दी गई है:

  • desktop: उपयोगकर्ता की डेस्कटॉप डायरेक्ट्री, अगर ऐसी कोई चीज़ मौजूद है.
  • documents: वह डायरेक्ट्री जिसमें आम तौर पर उपयोगकर्ता के बनाए गए दस्तावेज़ सेव किए जाते हैं.
  • downloads: वह डायरेक्ट्री जहां आम तौर पर डाउनलोड की गई फ़ाइलें सेव की जाती हैं.
  • music: वह डायरेक्ट्री जहां आम तौर पर ऑडियो फ़ाइलें सेव की जाती हैं.
  • pictures: वह डायरेक्ट्री जहां फ़ोटो और अन्य इमेज आम तौर पर सेव की जाती हैं.
  • videos: वह डायरेक्ट्री जहां आम तौर पर वीडियो या फ़िल्में सेव की जाती हैं.

जानी-मानी सिस्टम डायरेक्ट्री के अलावा, किसी मौजूदा फ़ाइल या डायरेक्ट्री हैंडल को इस तरह से भी भेजा जा सकता है: startIn के लिए एक मान. इसके बाद, डायलॉग उसी डायरेक्ट्री में खुलेगा.

// Assume `directoryHandle` is a handle to a previously opened directory.
const fileHandle = await self.showOpenFilePicker({
  startIn: directoryHandle
});

अलग-अलग फ़ाइल पिकर इस्तेमाल करने का मकसद बताना

कभी-कभी ऐप्लिकेशन में अलग-अलग कामों के लिए अलग-अलग पिकर होते हैं. उदाहरण के लिए, रिच टेक्स्ट एडिटर की मदद से उपयोगकर्ता टेक्स्ट फ़ाइलें खोल सकते हैं और इमेज इंपोर्ट भी कर सकते हैं. डिफ़ॉल्ट रूप से, हर फ़ाइल पिकर आखिरी बार याद रखी गई जगह पर खुलेगा. id वैल्यू सेव करके, इसे गच्चा देने की कोशिश की जा सकती है इस्तेमाल कर सकते हैं. अगर id तय किया गया है, तो फ़ाइल पिकर लागू करने के दौरान उस id के लिए, आख़िरी बार इस्तेमाल की गई डायरेक्ट्री को अलग करें.

const fileHandle1 = await self.showSaveFilePicker({
  id: 'openText',
});

const fileHandle2 = await self.showSaveFilePicker({
  id: 'importImage',
});

IndexedDB में फ़ाइल हैंडल या डायरेक्ट्री हैंडल को स्टोर करना

फ़ाइल हैंडल और डायरेक्ट्री हैंडल को क्रम से लगाया जा सकता है. इसका मतलब है कि फ़ाइल या डायरेक्ट्री के हैंडल को सेव किया जा सकता है indexedDB के लिए डायरेक्ट्री हैंडल चुनें या उन्हें एक ही टॉप-लेवल के बीच भेजने के लिए postMessage() को कॉल करें ऑरिजिन.

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

कोड का यह उदाहरण, फ़ाइल हैंडल और डायरेक्ट्री हैंडल को सेव और वापस पाने के बारे में बताता है. आप Glitch पर इसे इस्तेमाल करते हुए देखें. (मैं उपयोग करता/करती हूं idb-keyval की लाइब्रेरी का इस्तेमाल करें.

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);
  }
});

सेव किए गए फ़ाइल या डायरेक्ट्री के हैंडल और अनुमतियां

अनुमतियां, सेशन के बीच हमेशा लागू नहीं होती हैं. इसलिए, आपको यह पुष्टि करनी होगी कि उपयोगकर्ता ने queryPermission() का इस्तेमाल करके फ़ाइल या डायरेक्ट्री को अनुमति दी है. अगर नहीं, तो कॉल करें इसका अनुरोध करने के लिए, requestPermission(). यह फ़ाइल और डायरेक्ट्री हैंडल के लिए एक ही तरह से काम करता है. आपने लोगों तक पहुंचाया मुफ़्त में fileOrDirectoryHandle.requestPermission(descriptor) या fileOrDirectoryHandle.queryPermission(descriptor).

टेक्स्ट एडिटर में, मैंने verifyPermission() तरीका बनाया है. इससे यह पता चलता है कि उपयोगकर्ता ने पहले से ही अनुमति दी गई है और ज़रूरी होने पर अनुरोध करता है.

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;
}

पढ़ने के अनुरोध के साथ लिखने की अनुमति का अनुरोध करके, मैंने अनुमति वाले प्रॉम्प्ट की संख्या कम कर दी है; फ़ाइल खोलते समय उपयोगकर्ता को एक प्रॉम्प्ट दिखता है. साथ ही, वह फ़ाइल को पढ़ने और उसमें बदलाव करने, दोनों की अनुमति देता है.

किसी डायरेक्ट्री को खोलना और उसके कॉन्टेंट की गिनती करना

किसी डायरेक्ट्री में मौजूद सभी फ़ाइलों की गिनती करने के लिए, showDirectoryPicker() को कॉल करें. किसी उपयोगकर्ता पिकर में एक डायरेक्ट्री चुनता है, जिसके बाद FileSystemDirectoryHandle 'वापस किया गया' फ़ंक्शन का इस्तेमाल करके, डायरेक्ट्री की फ़ाइलों की गिनती की जा सकती है और उन्हें ऐक्सेस किया जा सकता है. डिफ़ॉल्ट रूप से, आपको का ऐक्सेस है, लेकिन अगर आपको लिखने का ऐक्सेस चाहिए, तो तरीके में { mode: 'readwrite' }.

butDir.addEventListener('click', async () => {
  const dirHandle = await window.showDirectoryPicker();
  for await (const entry of dirHandle.values()) {
    console.log(entry.kind, entry.name);
  }
});

उदाहरण के लिए, अगर आपको अलग से getFile() का इस्तेमाल करके, हर फ़ाइल को ऐक्सेस करना है, तो फ़ाइल साइज़, हर नतीजे पर एक क्रम में await का इस्तेमाल न करें, बल्कि साथ ही, उदाहरण के लिए, Promise.all() का इस्तेमाल करके.

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));
});

किसी डायरेक्ट्री में फ़ाइलें और फ़ोल्डर बनाना या उन्हें ऐक्सेस करना

किसी डायरेक्ट्री से, फ़ाइलें और फ़ोल्डर बनाए या ऐक्सेस किए जा सकते हैं. इसके लिए, getFileHandle() या getDirectoryHandle() तरीका. create की कुंजी और बूलियन वैल्यू के साथ एक वैकल्पिक options ऑब्जेक्ट पास करके true या false, यह तय किया जा सकता है कि नई फ़ाइल या फ़ोल्डर मौजूद न होने पर, उसे बनाया जाए या नहीं.

// 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 });

डायरेक्ट्री में किसी आइटम के पाथ को हल करना

किसी डायरेक्ट्री में मौजूद फ़ाइलों या फ़ोल्डर के साथ काम करते समय, आइटम के पाथ को ठीक करने में मदद मिल सकती है सवाल है. ऐसा करने के लिए, resolve() नाम का इस्तेमाल किया जा सकता है. समाधान करने के लिए, आइटम, डायरेक्ट्री का डायरेक्ट या इनडायरेक्ट चाइल्ड हो सकता है.

// 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"]

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

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

// Delete a file.
await directoryHandle.removeEntry('Abandoned Projects.txt');
// Recursively delete a folder.
await directoryHandle.removeEntry('Old Stuff', { recursive: true });

किसी फ़ाइल या फ़ोल्डर को सीधे मिटाना

अगर आपके पास किसी फ़ाइल या डायरेक्ट्री हैंडल का ऐक्सेस है, तो FileSystemFileHandle पर remove() को कॉल करें या इसे हटाने के लिए FileSystemDirectoryHandle.

// Delete a file.
await fileHandle.remove();
// Delete a directory.
await directoryHandle.remove();

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

फ़ाइलों और फ़ोल्डर का नाम बदला जा सकता है या उन्हें किसी नई जगह पर ले जाया जा सकता है. इसके लिए, इस लिंक पर move() को कॉल करें FileSystemHandle इंटरफ़ेस. FileSystemHandle का चाइल्ड इंटरफ़ेस FileSystemFileHandle और FileSystemDirectoryHandle. move() वाले तरीके में एक या दो पैरामीटर होते हैं. पहला विकल्प, इनमें से कोई एक विकल्प चुन सकता है गंतव्य फ़ोल्डर के लिए नए नाम वाली स्ट्रिंग या FileSystemDirectoryHandle. इस बाद वाला केस, वैकल्पिक दूसरा पैरामीटर नए नाम वाली एक स्ट्रिंग है, इसलिए स्थानांतरण और नाम बदलने से एक ही चरण में पूरा हो सकता है.

// 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');

इंटिग्रेशन को खींचें और छोड़ें

कॉन्टेंट बनाने एचटीएमएल 'खींचें और छोड़ें' इंटरफ़ेस वेब ऐप्लिकेशन को स्वीकार करने की अनुमति दें खींचकर छोड़ी गई फ़ाइलें एक वेब पेज पर. खींचें और छोड़ें कार्रवाई के दौरान, ड्रैग की गई फ़ाइल और डायरेक्ट्री आइटम जुड़े होते हैं और डायरेक्ट्री में एंट्री. DataTransferItem.getAsFileSystemHandle() तरीका, अगर खींचे गए आइटम की फ़ाइल है, तो FileSystemFileHandle ऑब्जेक्ट के साथ प्रॉमिस देता है, और अगर खींचकर छोड़ा गया आइटम एक डायरेक्ट्री है, तो FileSystemDirectoryHandle ऑब्जेक्ट के साथ प्रॉमिस करें. निम्न सूची दिखाता है. ध्यान दें कि 'खींचें और छोड़ें' इंटरफ़ेस के DataTransferItem.kind है दोनों फ़ाइलों और डायरेक्ट्री के लिए "file", जबकि फ़ाइल सिस्टम ऐक्सेस एपीआई का FileSystemHandle.kind है फ़ाइलों के लिए "file" और डायरेक्ट्री के लिए "directory".

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}`);
    }
  }
});

ऑरिजिन प्राइवेट फ़ाइल सिस्टम को ऐक्सेस करना

ऑरिजिन प्राइवेट फ़ाइल सिस्टम, स्टोरेज एंडपॉइंट होता है, जो कि पेज का ऑरिजिन. आम तौर पर, ब्राउज़र इसके कॉन्टेंट को बनाए रखकर इसे लागू करते हैं ऑरिजिन निजी फ़ाइल सिस्टम को कहीं भी डिस्क में इस्तेमाल किया जाता है, तो ऐसा नहीं है कि कॉन्टेंट उपयोगकर्ता हो सुलभ है. इसी तरह, यह उम्मीद नहीं है कि जिन फ़ाइलों या डायरेक्ट्री के नाम ऑरिजिन प्राइवेट फ़ाइल सिस्टम के चिल्ड्रेन के नाम मौजूद हैं. ब्राउज़र ऐसा लग सकता है कि यहां फ़ाइलें मौजूद हैं, जबकि यह एक ऑरिजिन प्राइवेट फ़ाइल सिस्टम है. ब्राउज़र किसी भी फ़ॉर्मैट में ये "फ़ाइलें" को डेटाबेस या किसी अन्य डेटा स्ट्रक्चर में इस्तेमाल किया जा सकता है. अगर इस एपीआई का इस्तेमाल किया जाता है, तो इस बात की उम्मीद करें कि बनाई गई फ़ाइलें, हार्ड डिस्क में कहीं एक वन-टू-वन फ़ाइल से मेल खाती हों. आप हमेशा की तरह इस पर काम कर सकते हैं: FileSystemDirectoryHandle रूट का ऐक्सेस मिलने के बाद, ऑरिजिन प्राइवेट फ़ाइल सिस्टम.

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 });

ब्राउज़र सहायता

  • Chrome: 86. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
  • एज: 86. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
  • Firefox: 111. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
  • Safari: 15.2. अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है

सोर्स

ऑरिजिन प्राइवेट फ़ाइल सिस्टम से, परफ़ॉर्मेंस के लिए ऑप्टिमाइज़ की गई फ़ाइलों को ऐक्सेस करना

ऑरिजिन प्राइवेट फ़ाइल सिस्टम, एक खास तरह की फ़ाइल का वैकल्पिक ऐक्सेस देता है प्रदर्शन के लिए ऑप्टिमाइज़ किया जाता है, उदाहरण के लिए, किसी फ़ाइल की कॉन्टेंट. Chromium 102 और उसके बाद के वर्शन में, ऑरिजिन प्राइवेट फ़ाइल सिस्टम के लिए एक और तरीका उपलब्ध है फ़ाइल को ऐक्सेस करना आसान बनाया जा रहा है: createSyncAccessHandle() (सिंक्रोनस पढ़ने और लिखने से जुड़ी कार्रवाइयों के लिए). इसे FileSystemFileHandle पर दिखाया गया है, लेकिन खास तौर पर वेब वर्कर.

// (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 });

पॉलीफ़िलिंग

File System Access API के तरीकों को पूरी तरह से पॉलीफ़िल नहीं किया जा सकता.

  • showOpenFilePicker() तरीके का अनुमान लगाने के लिए, <input type="file"> एलिमेंट का इस्तेमाल किया जा सकता है.
  • showSaveFilePicker() तरीके को <a download="file_name"> एलिमेंट की मदद से सिम्युलेट किया जा सकता है, हालांकि, इससे प्रोग्राम के हिसाब से डाउनलोड ट्रिगर होता है और मौजूदा फ़ाइलों को ओवरराइट नहीं किया जा सकता.
  • showDirectoryPicker() तरीके को कुछ हद तक नॉन-स्टैंडर्ड तरीकों की मदद से एम्युलेट किया जा सकता है <input type="file" webkitdirectory> एलिमेंट.

हमने browser-fs-access नाम की एक लाइब्रेरी बनाई है, जो System Access API की मदद से, जहां भी मुमकिन हो वहां सिस्टम ऐक्सेस एपीआई की मदद से, मामले.

सुरक्षा और अनुमतियां

Chrome टीम ने अपने मुख्य सिद्धांतों को ध्यान में रखते हुए, File System Access API को डिज़ाइन और लागू किया है शक्तिशाली वेब प्लैटफ़ॉर्म सुविधाओं का ऐक्सेस कंट्रोल करना में बताया गया है. इसमें उपयोगकर्ता भी शामिल है कंट्रोल और पारदर्शिता, और यूज़र एर्गोनॉमिक्स.

किसी फ़ाइल को खोलना या नई फ़ाइल सेव करना

पढ़ने के लिए फ़ाइल खोलने के लिए, फ़ाइल पिकर
मौजूदा फ़ाइल को पढ़ने के लिए खोलने के लिए इस्तेमाल किया जाने वाला फ़ाइल पिकर.

किसी फ़ाइल को खोलते समय, उपयोगकर्ता फ़ाइल पिकर का इस्तेमाल करके फ़ाइल या डायरेक्ट्री को पढ़ने की अनुमति देता है. खुली हुई फ़ाइल पिकर को सिर्फ़ उपयोगकर्ता जेस्चर का इस्तेमाल करके दिखाया जा सकता है. ऐसा तब किया जा सकता है, जब उसे सुरक्षित पेज से दिखाया जाए कॉन्टेक्स्ट. अगर उपयोगकर्ताओं का इरादा बदल जाए, तो वे फ़ाइल में चुने गए विकल्प को रद्द कर सकते हैं पिकर और साइट को किसी भी चीज़ का ऐक्सेस नहीं मिलता है. यह व्यवहार वैसा ही है जैसा <input type="file"> एलिमेंट.

फ़ाइल को डिस्क में सेव करने के लिए फ़ाइल पिकर.
फ़ाइल को डिस्क में सेव करने के लिए इस्तेमाल किया जाने वाला फ़ाइल पिकर.

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

प्रतिबंधित फ़ोल्डर

उपयोगकर्ताओं और उनके डेटा को सुरक्षित रखने के लिए, ब्राउज़र कुछ तय फ़ोल्डर, उदाहरण के लिए, Windows जैसे कोर ऑपरेटिंग सिस्टम फ़ोल्डर, macOS Library फ़ोल्डर. ऐसा होने पर ब्राउज़र एक प्रॉम्प्ट दिखाता है और उपयोगकर्ता से कोई दूसरा प्रॉम्प्ट चुनने के लिए कहता है फ़ोल्डर खोलें.

मौजूदा फ़ाइल या डायरेक्ट्री में बदलाव करना

उपयोगकर्ता से साफ़ तौर पर अनुमति लिए बिना वेब ऐप्लिकेशन, डिस्क पर मौजूद किसी फ़ाइल में बदलाव नहीं कर सकता.

अनुमति का प्रॉम्प्ट

अगर कोई व्यक्ति किसी ऐसी फ़ाइल में किए गए बदलावों को सेव करना चाहता है जिसे पहले उसने पढ़ने का ऐक्सेस दिया था, तो अनुमति का प्रॉम्प्ट दिखाता है, जिसमें साइट को डिस्क में बदलाव करने के लिए अनुमति का अनुरोध किया जाता है. अनुमति का अनुरोध सिर्फ़ उपयोगकर्ता के जेस्चर से ट्रिगर किया जा सकता है. उदाहरण के लिए, 'सेव करें' पर क्लिक करके बटन.

फ़ाइल सेव करने से पहले अनुमति का प्रॉम्प्ट दिखता है.
ब्राउज़र को बदलाव करने की अनुमति देने से पहले, उपयोगकर्ताओं को दिखने वाला प्रॉम्प्ट मौजूदा फ़ाइल पर अनुमति

इसके अलावा, IDE जैसी कई फ़ाइलों में बदलाव करने वाला वेब ऐप्लिकेशन भी सेव करने की अनुमति मांग सकता है खुलने के समय बदल जाता है.

अगर उपयोगकर्ता 'रद्द करें' का विकल्प चुनता है और लिखने का ऐक्सेस नहीं देता, तो वेब ऐप्लिकेशन लोकल फ़ाइल. इसे उपयोगकर्ताओं को अपना डेटा सेव करने का एक वैकल्पिक तरीका उपलब्ध कराना चाहिए, जैसे कि "download" फ़ाइल या डेटा को क्लाउड पर सेव करने के लिए किया जा सकता है.

पारदर्शिता

खोज बार (खोज क्वेरी डालने वाला बार) का आइकॉन
पता बार का आइकॉन यह दिखाता है कि उपयोगकर्ता ने वेबसाइट को इसके लिए अनुमति दी है को डिवाइस में सेव करें.

जब कोई उपयोगकर्ता किसी वेब ऐप्लिकेशन को लोकल फ़ाइल सेव करने की अनुमति देता है, तो ब्राउज़र एक आइकॉन दिखाता है लिखें. आइकॉन पर क्लिक करने से एक पॉप-ओवर खुलता है. इस पॉप-ओवर में उन फ़ाइलों की सूची दिखती है जो उपयोगकर्ता ने दी हैं का ऐक्सेस है. अगर उपयोगकर्ता चाहें, तो वे किसी भी समय इस ऐक्सेस को रद्द कर सकते हैं.

अनुमति का एक जैसा होना

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

सुझाव/राय दें या शिकायत करें

हम फ़ाइल सिस्टम ऐक्सेस एपीआई के इस्तेमाल से जुड़े आपके अनुभव जानना चाहते हैं.

हमें एपीआई के डिज़ाइन के बारे में बताएं

क्या एपीआई में ऐसा कुछ है जो आपकी उम्मीद के मुताबिक काम नहीं करता? या कुछ तरीके उपलब्ध नहीं हैं या प्रॉपर्टी से जोड़ना होगा? सुरक्षा से जुड़े सवाल पूछने या टिप्पणी करने के लिए मॉडल?

  • WICG File System Access GitHub रेपो पर, कोई खास समस्या दर्ज करें या अपनी राय दें करने के लिए प्रोत्साहित करते हैं.

क्या लागू करने में कोई समस्या हुई?

क्या आपको Chrome को लागू करने में कोई गड़बड़ी मिली? या क्या लागू करने का तरीका, स्पेसिफ़िकेशन से अलग है?

  • https://new.crbug.com पर जाकर, गड़बड़ी की शिकायत करें. ज़्यादा से ज़्यादा जानकारी दें, फिर से बनाने के निर्देश देखें और कॉम्पोनेंट को Blink>Storage>FileSystem पर सेट करें. तुरंत जवाब देने के लिए, Glitch काम करता है.

क्या आपको इस एपीआई का इस्तेमाल करना है?

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

मददगार लिंक

स्वीकार की गई

फ़ाइल सिस्टम ऐक्सेस एपीआई की खास जानकारी इन्होंने लिखा था मारिजन क्रुसेलब्रिंक.