উত্স বেসরকারী ফাইল সিস্টেম

ফাইল সিস্টেম স্ট্যান্ডার্ড একটি অরিজিন প্রাইভেট ফাইল সিস্টেম (OPFS) একটি স্টোরেজ এন্ডপয়েন্ট হিসাবে পৃষ্ঠার উত্সের জন্য ব্যক্তিগত হিসাবে প্রবর্তন করে এবং ব্যবহারকারীর কাছে দৃশ্যমান নয় যা একটি বিশেষ ধরনের ফাইলে ঐচ্ছিক অ্যাক্সেস প্রদান করে যা কার্য সম্পাদনের জন্য অত্যন্ত অপ্টিমাইজ করা হয়।

ব্রাউজার সমর্থন

অরিজিন প্রাইভেট ফাইল সিস্টেম আধুনিক ব্রাউজার দ্বারা সমর্থিত এবং ফাইল সিস্টেম লিভিং স্ট্যান্ডার্ডে ওয়েব হাইপারটেক্সট অ্যাপ্লিকেশন টেকনোলজি ওয়ার্কিং গ্রুপ ( WHATWG ) দ্বারা প্রমিত।

ব্রাউজার সমর্থন

  • 86
  • 86
  • 111
  • 15.2

উৎস

প্রেরণা

আপনি যখন আপনার কম্পিউটারে ফাইলগুলির কথা ভাবেন, আপনি সম্ভবত একটি ফাইলের শ্রেণিবিন্যাস সম্পর্কে ভাবেন: ফোল্ডারে সংগঠিত ফাইলগুলি যা আপনি আপনার অপারেটিং সিস্টেমের ফাইল এক্সপ্লোরারের সাথে অন্বেষণ করতে পারেন৷ উদাহরণস্বরূপ, উইন্ডোজে, টম নামক ব্যবহারকারীর জন্য, তাদের করণীয় তালিকা C:\Users\Tom\Documents\ToDo.txt এ থাকতে পারে। এই উদাহরণে, ToDo.txt হল ফাইলের নাম, এবং Users , Tom , এবং Documents হল ফোল্ডারের নাম৷ উইন্ডোজে `C:` ড্রাইভের রুট ডিরেক্টরি উপস্থাপন করে।

ওয়েবে ফাইলের সাথে কাজ করার ঐতিহ্যগত উপায়

একটি ওয়েব অ্যাপ্লিকেশনে করণীয় তালিকা সম্পাদনা করতে, এটি স্বাভাবিক প্রবাহ:

  1. ব্যবহারকারী একটি সার্ভারে ফাইল আপলোড করে বা <input type="file"> দিয়ে ক্লায়েন্টে খোলে
  2. ব্যবহারকারী তাদের পরিবর্তন করে, এবং তারপরে একটি ইনজেক্ট করা <a download="ToDo.txt> দিয়ে ফলাফল ফাইলটি ডাউনলোড করে যা আপনি জাভাস্ক্রিপ্টের মাধ্যমে প্রোগ্রামে click()
  3. ফোল্ডার খোলার জন্য, আপনি <input type="file" webkitdirectory> এ একটি বিশেষ বৈশিষ্ট্য ব্যবহার করেন, যেটির মালিকানা নাম থাকা সত্ত্বেও কার্যত সর্বজনীন ব্রাউজার সমর্থন রয়েছে।

ওয়েবে ফাইল নিয়ে কাজ করার আধুনিক উপায়

এই প্রবাহটি ব্যবহারকারীরা কীভাবে ফাইল সম্পাদনা করার কথা ভাবেন তার প্রতিনিধি নয়, এবং এর অর্থ হল ব্যবহারকারীরা তাদের ইনপুট ফাইলগুলির ডাউনলোড করা অনুলিপি দিয়ে শেষ করে। অতএব, ফাইল সিস্টেম অ্যাক্সেস এপিআই তিনটি পিকার পদ্ধতি চালু করেছে showOpenFilePicker() , showSaveFilePicker() , এবং showDirectoryPicker() — যা তাদের নাম অনুসারে ঠিক তাই করে। তারা নিম্নরূপ একটি প্রবাহ সক্ষম করে:

  1. showOpenFilePicker() দিয়ে ToDo.txt খুলুন এবং একটি FileSystemFileHandle অবজেক্ট পান।
  2. FileSystemFileHandle অবজেক্ট থেকে, ফাইল হ্যান্ডেলের getFile() পদ্ধতিতে কল করে একটি File পান।
  3. ফাইলটি পরিবর্তন করুন, তারপর হ্যান্ডেলে requestPermission({mode: 'readwrite'}) কল করুন।
  4. ব্যবহারকারী যদি অনুমতির অনুরোধ গ্রহণ করেন, তবে পরিবর্তনগুলিকে মূল ফাইলে আবার সংরক্ষণ করুন।
  5. বিকল্পভাবে, showSaveFilePicker() কল করুন এবং ব্যবহারকারীকে একটি নতুন ফাইল বাছাই করতে দিন। (যদি ব্যবহারকারী একটি পূর্বে খোলা ফাইল বাছাই করে, তবে এর বিষয়বস্তু ওভাররাইট করা হবে।) পুনরাবৃত্তি সংরক্ষণের জন্য, আপনি ফাইলের হ্যান্ডেলটি চারপাশে রাখতে পারেন, তাই আপনাকে ফাইল সংরক্ষণ ডায়ালগটি আবার দেখাতে হবে না।

ওয়েবে ফাইলের সাথে কাজ করার সীমাবদ্ধতা

এই পদ্ধতিগুলির মাধ্যমে অ্যাক্সেসযোগ্য ফাইল এবং ফোল্ডারগুলিকে ব্যবহারকারী-দৃশ্যমান ফাইল সিস্টেম বলা যেতে পারে। ওয়েব থেকে সংরক্ষিত ফাইল এবং এক্সিকিউটেবল ফাইলগুলিকে বিশেষভাবে ওয়েবের চিহ্ন দিয়ে চিহ্নিত করা হয়, তাই একটি অতিরিক্ত সতর্কতা রয়েছে যা অপারেটিং সিস্টেম একটি সম্ভাব্য বিপজ্জনক ফাইল কার্যকর করার আগে দেখাতে পারে৷ একটি অতিরিক্ত নিরাপত্তা বৈশিষ্ট্য হিসাবে, ওয়েব থেকে প্রাপ্ত ফাইলগুলিও নিরাপদ ব্রাউজিং দ্বারা সুরক্ষিত থাকে, যা, সরলতার জন্য এবং এই নিবন্ধটির প্রেক্ষাপটে, আপনি একটি ক্লাউড-ভিত্তিক ভাইরাস স্ক্যান হিসাবে ভাবতে পারেন৷ আপনি যখন ফাইল সিস্টেম অ্যাক্সেস API ব্যবহার করে একটি ফাইলে ডেটা লেখেন, তখন লেখাগুলি ইন-প্লেস হয় না, কিন্তু একটি অস্থায়ী ফাইল ব্যবহার করে। এই সমস্ত নিরাপত্তা চেক পাস না করা পর্যন্ত ফাইল নিজেই পরিবর্তন করা হয় না। আপনি যেমন কল্পনা করতে পারেন, এই কাজটি ফাইল অপারেশনগুলিকে তুলনামূলকভাবে ধীর করে তোলে, যেখানে সম্ভব উন্নতি প্রয়োগ করা সত্ত্বেও, উদাহরণস্বরূপ, macOS-এ । এখনও প্রতিটি write() কল স্বয়ংসম্পূর্ণ, তাই হুডের নীচে এটি ফাইলটি খোলে, প্রদত্ত অফসেটের সন্ধান করে এবং অবশেষে ডেটা লেখে।

প্রক্রিয়াকরণের ভিত্তি হিসাবে ফাইল

একই সময়ে, ফাইলগুলি ডেটা রেকর্ড করার একটি দুর্দান্ত উপায়। উদাহরণস্বরূপ, SQLite একটি ফাইলে সমগ্র ডাটাবেস সংরক্ষণ করে। আরেকটি উদাহরণ হল ছবি প্রক্রিয়াকরণে ব্যবহৃত মিপম্যাপ । মিপম্যাপগুলি হল প্রাক-গণনা করা, চিত্রগুলির অপ্টিমাইজ করা ক্রম, যার প্রত্যেকটিই আগের তুলনায় ক্রমান্বয়ে কম রেজোলিউশনের উপস্থাপনা, যা অনেকগুলি ক্রিয়াকলাপকে দ্রুত জুম করার মতো করে। তাহলে কিভাবে ওয়েব অ্যাপ্লিকেশনগুলি ফাইলের সুবিধা পেতে পারে, কিন্তু ওয়েব-ভিত্তিক ফাইল প্রক্রিয়াকরণের পারফরম্যান্স খরচ ছাড়া? উত্তর হল অরিজিন প্রাইভেট ফাইল সিস্টেম

ব্যবহারকারী-দৃশ্যমান বনাম মূল ব্যক্তিগত ফাইল সিস্টেম

অপারেটিং সিস্টেমের ফাইল এক্সপ্লোরার ব্যবহার করে ব্রাউজ করা ব্যবহারকারী-দৃশ্যমান ফাইল সিস্টেমের বিপরীতে, ফাইল এবং ফোল্ডারগুলির সাথে আপনি পড়তে, লিখতে, সরাতে এবং নাম পরিবর্তন করতে পারেন, মূল ব্যক্তিগত ফাইল সিস্টেমটি ব্যবহারকারীদের দ্বারা দেখার জন্য নয়। অরিজিন প্রাইভেট ফাইল সিস্টেমের ফাইল এবং ফোল্ডারগুলি, নাম থেকে বোঝা যায়, ব্যক্তিগত, এবং আরও নির্দিষ্টভাবে, একটি সাইটের উত্সের জন্য ব্যক্তিগত। DevTools কনসোলে location.origin টাইপ করে একটি পৃষ্ঠার উৎস আবিষ্কার করুন। উদাহরণস্বরূপ, https://developer.chrome.com/articles/ পৃষ্ঠাটির উত্স হল https://developer.chrome.com (অর্থাৎ, অংশটি /articles মূলের অংশ নয় )৷ আপনি "একই-সাইট" এবং "একই-উৎপত্তি" বোঝার মধ্যে উত্সের তত্ত্ব সম্পর্কে আরও পড়তে পারেন। যে সমস্ত পৃষ্ঠাগুলি একই উত্স ভাগ করে সেগুলি একই উত্সের ব্যক্তিগত ফাইল সিস্টেম ডেটা দেখতে পারে, তাই https://developer.chrome.com/docs/extensions/mv3/getstarted/extensions-101/ আগের উদাহরণের মতো একই বিবরণ দেখতে পারে৷ প্রতিটি অরিজিনের নিজস্ব স্বতন্ত্র অরিজিন প্রাইভেট ফাইল সিস্টেম থাকে, যার অর্থ https://developer.chrome.com এর অরিজিন প্রাইভেট ফাইল সিস্টেম https: https://web.dev এর থেকে সম্পূর্ণ আলাদা। উইন্ডোজে, ব্যবহারকারী-দৃশ্যমান ফাইল সিস্টেমের রুট ডিরেক্টরি হল C:\\ । অরিজিন প্রাইভেট ফাইল সিস্টেমের সমতুল্য হল অ্যাসিঙ্ক্রোনাস মেথড navigator.storage.getDirectory() কল করার মাধ্যমে একটি প্রাথমিকভাবে খালি রুট ডিরেক্টরি প্রতি অরিজিন। ব্যবহারকারী-দৃশ্যমান ফাইল সিস্টেম এবং অরিজিন প্রাইভেট ফাইল সিস্টেমের তুলনার জন্য, নিম্নলিখিত চিত্রটি দেখুন। ডায়াগ্রামটি দেখায় যে রুট ডিরেক্টরি বাদে, আপনার ডেটা এবং স্টোরেজ প্রয়োজনীয়তার জন্য প্রয়োজনীয় ফাইল এবং ফোল্ডারগুলির একটি শ্রেণিবিন্যাস সহ ধারণাগতভাবে অন্য সবকিছু একই রকম।

ব্যবহারকারী-দৃশ্যমান ফাইল সিস্টেমের চিত্র এবং দুটি অনুকরণীয় ফাইল শ্রেণিবিন্যাস সহ অরিজিন প্রাইভেট ফাইল সিস্টেম। ব্যবহারকারী-দৃশ্যমান ফাইল সিস্টেমের এন্ট্রি পয়েন্ট হল একটি সিম্বলিক হার্ডডিস্ক, মূল প্রাইভেট ফাইল সিস্টেমের এন্ট্রি পয়েন্ট হল 'navigator.storage.getDirectory' পদ্ধতির কলিং।

অরিজিন প্রাইভেট ফাইল সিস্টেমের স্পেসিফিকেশন

ব্রাউজারে অন্যান্য স্টোরেজ মেকানিজমের মতো (উদাহরণস্বরূপ, লোকাল স্টোরেজ বা ইনডেক্সডডিবি ), অরিজিন প্রাইভেট ফাইল সিস্টেম ব্রাউজার কোটা সীমাবদ্ধতার সাপেক্ষে। যখন একজন ব্যবহারকারী সমস্ত ব্রাউজিং ডেটা বা সমস্ত সাইট ডেটা সাফ করে, তখন মূল ব্যক্তিগত ফাইল সিস্টেমটিও মুছে ফেলা হবে। 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);

প্রধান থ্রেড বা ওয়েব ওয়ার্কার

অরিজিন প্রাইভেট ফাইল সিস্টেম ব্যবহার করার দুটি উপায় রয়েছে: মূল থ্রেডে বা ওয়েব ওয়ার্কারে । ওয়েব ওয়ার্কাররা মূল থ্রেড ব্লক করতে পারে না, যার মানে এই প্রসঙ্গে APIগুলি সিঙ্ক্রোনাস হতে পারে, একটি প্যাটার্ন যা সাধারণত প্রধান থ্রেডে অননুমোদিত। সিঙ্ক্রোনাস এপিআই দ্রুততর হতে পারে কারণ তারা প্রতিশ্রুতি মোকাবেলা করা এড়ায়, এবং ফাইল অপারেশনগুলি সাধারণত সি-এর মতো ভাষায় সিঙ্ক্রোনাস হয় যা 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() শুধুমাত্র প্রধান থ্রেডে উন্মুক্ত, কিন্তু Worker থ্রেডে নয়, সেখানে কোডটি চালাতে ভুলবেন না।

// 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 এক্সপ্লোরার Chrome DevTools এক্সটেনশন।

এক্সটেনশনটি ইনস্টল করার পরে, Chrome DevTools খুলুন, OPFS এক্সপ্লোরার ট্যাবটি নির্বাচন করুন এবং তারপরে আপনি ফাইলের শ্রেণিবিন্যাস পরিদর্শন করতে প্রস্তুত৷ ফাইলের নাম ক্লিক করে মূল প্রাইভেট ফাইল সিস্টেম থেকে ব্যবহারকারী-দৃশ্যমান ফাইল সিস্টেমে ফাইলগুলি সংরক্ষণ করুন এবং ট্র্যাশ ক্যান আইকনে ক্লিক করে ফাইল এবং ফোল্ডারগুলি মুছুন৷

ডেমো

ওয়েব অ্যাসেম্বলিতে সংকলিত SQLite ডাটাবেসের জন্য একটি ব্যাকএন্ড হিসাবে এটি ব্যবহার করে এমন একটি ডেমোতে (যদি আপনি OPFS এক্সপ্লোরার এক্সটেনশন ইনস্টল করেন) অরিজিন প্রাইভেট ফাইল সিস্টেমটি কার্যকর দেখুন। গ্লিচ-এ সোর্স কোডটি দেখতে ভুলবেন না। লক্ষ্য করুন কিভাবে নীচের এম্বেড করা সংস্করণটি অরিজিন প্রাইভেট ফাইল সিস্টেম ব্যাকএন্ড ব্যবহার করে না (কারণ iframe ক্রস-অরিজিন), কিন্তু আপনি যখন একটি পৃথক ট্যাবে ডেমো খুলবেন, তখন তা হয়।

উপসংহার

WHATWG দ্বারা নির্দিষ্ট করা অরিজিন প্রাইভেট ফাইল সিস্টেম, ওয়েবে ফাইলগুলির সাথে আমরা যেভাবে ব্যবহার করি এবং ইন্টারঅ্যাক্ট করি সেই পদ্ধতিটিকে আকার দিয়েছে৷ এটি নতুন ব্যবহারের ক্ষেত্রে সক্ষম করেছে যা ব্যবহারকারী-দৃশ্যমান ফাইল সিস্টেমের সাথে অর্জন করা অসম্ভব ছিল। সমস্ত প্রধান ব্রাউজার বিক্রেতারা—Apple, Mozilla, এবং Google—অন-বোর্ড রয়েছে এবং একটি যৌথ দৃষ্টিভঙ্গি ভাগ করে নিয়েছে৷ অরিজিন প্রাইভেট ফাইল সিস্টেমের বিকাশ একটি সহযোগিতামূলক প্রচেষ্টা, এবং বিকাশকারী এবং ব্যবহারকারীদের কাছ থেকে প্রতিক্রিয়া এর অগ্রগতির জন্য অপরিহার্য। যেহেতু আমরা মানকে পরিমার্জিত এবং উন্নত করতে থাকি, তাই ইস্যু বা পুল রিকোয়েস্টের আকারে whatwg/fs সংগ্রহস্থলের প্রতিক্রিয়া স্বাগত জানাই।

স্বীকৃতি

এই নিবন্ধটি অস্টিন সুলি , Etienne Noel , এবং Rachel Andrew দ্বারা পর্যালোচনা করা হয়েছে। আনস্প্ল্যাশে ক্রিস্টিনা রাম্পফের হিরো ছবি।