ফাইল সিস্টেম স্ট্যান্ডার্ড একটি অরিজিন প্রাইভেট ফাইল সিস্টেম (OPFS) চালু করেছে, যা পেজের অরিজিনের জন্য ব্যক্তিগত এবং ব্যবহারকারীর কাছে অদৃশ্য একটি স্টোরেজ এন্ডপয়েন্ট। এটি পারফরম্যান্সের জন্য অত্যন্ত অপ্টিমাইজ করা এক বিশেষ ধরনের ফাইলে ঐচ্ছিক অ্যাক্সেস প্রদান করে।
ব্রাউজার সমর্থন
অরিজিন প্রাইভেট ফাইল সিস্টেম আধুনিক ব্রাউজার দ্বারা সমর্থিত এবং ওয়েব হাইপারটেক্সট অ্যাপ্লিকেশন টেকনোলজি ওয়ার্কিং গ্রুপ ( WHATWG ) কর্তৃক ফাইল সিস্টেম লিভিং স্ট্যান্ডার্ড- এ এটিকে প্রমিত করা হয়েছে।
অনুপ্রেরণা
যখন আপনি আপনার কম্পিউটারের ফাইলগুলোর কথা ভাবেন, তখন সম্ভবত আপনি একটি ফাইল হায়ারার্কির কথা ভাবেন: ফাইলগুলো ফোল্ডারে সাজানো থাকে, যা আপনি আপনার অপারেটিং সিস্টেমের ফাইল এক্সপ্লোরার দিয়ে দেখতে পারেন। উদাহরণস্বরূপ, উইন্ডোজে, টম নামের একজন ব্যবহারকারীর করণীয় কাজের তালিকাটি C:\Users\Tom\Documents\ToDo.txt এ থাকতে পারে। এই উদাহরণে, ToDo.txt হলো ফাইলের নাম, এবং Users , Tom , ও Documents হলো ফোল্ডারের নাম। উইন্ডোজে ‘C:’ ড্রাইভের রুট ডিরেক্টরিকে বোঝায়।
ওয়েবে ফাইল নিয়ে কাজ করার সাধারণ পদ্ধতি
একটি ওয়েব অ্যাপ্লিকেশনে করণীয় তালিকা সম্পাদনা করার সাধারণ প্রক্রিয়াটি হলো:
- ব্যবহারকারী ফাইলটি সার্ভারে আপলোড করে অথবা
<input type="file">ব্যবহার করে ক্লায়েন্টে খোলে । - ব্যবহারকারী তার পরিবর্তনগুলো সম্পন্ন করেন এবং তারপর ফলাফলস্বরূপ ফাইলটি ডাউনলোড করেন , যেটিতে একটি
<a download="ToDo.txt>ট্যাগ যুক্ত থাকে, যা আপনি জাভাস্ক্রিপ্ট ব্যবহার করে প্রোগ্রাম্যাটিকভাবেclick()। - ফোল্ডার খোলার জন্য
<input type="file" webkitdirectory>-এ একটি বিশেষ অ্যাট্রিবিউট ব্যবহার করা হয়, যার নামটি মালিকানাধীন হলেও এটি কার্যত সব ব্রাউজারেই সমর্থিত।
ওয়েবে ফাইল নিয়ে কাজ করার আধুনিক পদ্ধতি
এই কার্যপ্রবাহটি ব্যবহারকারীরা যেভাবে ফাইল সম্পাদনা করেন তার প্রতিনিধিত্ব করে না, এবং এর ফলে ব্যবহারকারীরা তাদের ইনপুট ফাইলগুলোর ডাউনলোড করা কপি পেয়ে যান। তাই, ফাইল সিস্টেম অ্যাক্সেস এপিআই তিনটি পিকার মেথড চালু করেছে:
এগুলো নিম্নরূপ একটি প্রবাহ সক্ষম করে:
-
showOpenFilePicker()ব্যবহার করেToDo.txtখুলুন এবং একটিFileSystemFileHandleঅবজেক্ট পান। -
FileSystemFileHandleঅবজেক্ট থেকে ফাইল হ্যান্ডেলেরgetFile()মেথড কল করে একটিFileনিন। - ফাইলটি পরিবর্তন করুন, তারপর হ্যান্ডেলটিতে
requestPermission({mode: 'readwrite'})কল করুন। - যদি ব্যবহারকারী অনুমতির অনুরোধটি গ্রহণ করেন, তাহলে পরিবর্তনগুলো মূল ফাইলে সংরক্ষণ করুন।
- বিকল্পভাবে,
showSaveFilePicker()কল করুন এবং ব্যবহারকারীকে একটি নতুন ফাইল বেছে নিতে দিন। (যদি ব্যবহারকারী পূর্বে খোলা কোনো ফাইল বেছে নেন, তবে তার বিষয়বস্তু ওভাররাইট হয়ে যাবে।) বারবার সেভ করার জন্য, আপনি ফাইল হ্যান্ডেলটি রেখে দিতে পারেন, ফলে আপনাকে ফাইল সেভ ডায়ালগটি আবার দেখাতে হবে না।
ওয়েবে ফাইল নিয়ে কাজ করার সীমাবদ্ধতা
এই পদ্ধতিগুলোর মাধ্যমে অ্যাক্সেসযোগ্য ফাইল এবং ফোল্ডারগুলো এমন একটি সিস্টেমে থাকে যাকে ব্যবহারকারী-দৃশ্যমান ফাইল সিস্টেম বলা যেতে পারে। ওয়েব থেকে সেভ করা ফাইল, এবং বিশেষ করে এক্সিকিউটেবল ফাইলগুলোকে ‘ মার্ক অফ দ্য ওয়েব’ দিয়ে চিহ্নিত করা হয়, ফলে কোনো সম্ভাব্য বিপজ্জনক ফাইল এক্সিকিউট হওয়ার আগে অপারেটিং সিস্টেম একটি অতিরিক্ত সতর্কবার্তা দেখাতে পারে। একটি অতিরিক্ত নিরাপত্তা বৈশিষ্ট্য হিসেবে, ওয়েব থেকে প্রাপ্ত ফাইলগুলো ‘সেফ ব্রাউজিং’ দ্বারাও সুরক্ষিত থাকে, যাকে সরলতার স্বার্থে এবং এই ডকুমেন্টের প্রেক্ষাপটে, আপনি একটি ক্লাউড-ভিত্তিক ভাইরাস স্ক্যান হিসেবে ভাবতে পারেন। যখন আপনি ফাইল সিস্টেম অ্যাক্সেস এপিআই (File System Access API) ব্যবহার করে কোনো ফাইলে ডেটা লেখেন, তখন সেই লেখাগুলো ইন-প্লেস (in-place) হয় না, বরং একটি টেম্পোরারি ফাইল ব্যবহার করে। ফাইলটি নিজে পরিবর্তিত হয় না, যতক্ষণ না এটি এই সমস্ত নিরাপত্তা যাচাইয়ে উত্তীর্ণ হয়।
এই কাজটি ফাইল অপারেশনকে তুলনামূলকভাবে ধীর করে তোলে, যদিও যেখানে সম্ভব সেখানে উন্নতি সাধন করা হয়েছে, যেমন macOS-এ । তবুও প্রতিটি write() কল স্বয়ংসম্পূর্ণ, তাই আড়ালে এটি ফাইলটি খোলে, প্রদত্ত অফসেটে যায় এবং সবশেষে ডেটা লেখে।
প্রক্রিয়াকরণের ভিত্তি হিসেবে ফাইল
একই সাথে, ডেটা রেকর্ড করার জন্য ফাইল একটি চমৎকার উপায়। উদাহরণস্বরূপ, SQLite সম্পূর্ণ ডেটাবেস একটিমাত্র ফাইলে সংরক্ষণ করে। আরেকটি উদাহরণ হলো ইমেজ প্রসেসিং-এ ব্যবহৃত মিপম্যাপ । মিপম্যাপ হলো পূর্ব-গণনাকৃত, অপ্টিমাইজ করা ছবির ক্রম, যার প্রতিটি পূর্ববর্তীটির ক্রমান্বয়ে নিম্ন রেজোলিউশনের একটি উপস্থাপনা, যা জুম করার মতো অনেক অপারেশনকে দ্রুততর করে তোলে। তাহলে ওয়েব অ্যাপ্লিকেশনগুলো কীভাবে ফাইলের সুবিধাগুলো পেতে পারে, কিন্তু ওয়েব-ভিত্তিক ফাইল প্রসেসিংয়ের পারফরম্যান্সের খরচ ছাড়াই? এর উত্তর হলো অরিজিন প্রাইভেট ফাইল সিস্টেম ।
ব্যবহারকারী-দৃশ্যমান বনাম মূল ব্যক্তিগত ফাইল সিস্টেম
অপারেটিং সিস্টেমের ফাইল এক্সপ্লোরার ব্যবহার করে ব্রাউজ করা ব্যবহারকারী-দৃশ্যমান ফাইল সিস্টেমের মতো নয়, যেখানে ফাইল ও ফোল্ডার পড়া, লেখা, সরানো এবং নাম পরিবর্তন করা যায়, অরিজিন প্রাইভেট ফাইল সিস্টেম ব্যবহারকারীদের দেখার জন্য নয়। অরিজিন প্রাইভেট ফাইল সিস্টেমের ফাইল ও ফোল্ডারগুলো, নাম থেকেই বোঝা যায়, ব্যক্তিগত এবং আরও নির্দিষ্টভাবে বললে, একটি সাইটের অরিজিনের জন্য ব্যক্তিগত। DevTools Console-এ location.origin টাইপ করে একটি পেজের অরিজিন খুঁজে বের করুন। উদাহরণস্বরূপ, https://developer.chrome.com/articles/ পেজটির অরিজিন হলো https://developer.chrome.com । অরিজিনের তত্ত্ব সম্পর্কে আরও জানতে "Understanding 'same-site' and 'same-origin'" অংশটি পড়ুন।
একই অরিজিন শেয়ার করে এমন সমস্ত পেজ একই অরিজিন প্রাইভেট ফাইল সিস্টেমের ডেটা দেখতে পারে, তাই https://developer.chrome.com/docs/extensions/mv3/getstarted/extensions-101/ আগের উদাহরণের মতোই একই বিবরণ দেখতে পারে। প্রতিটি অরিজিনের নিজস্ব স্বাধীন অরিজিন প্রাইভেট ফাইল সিস্টেম থাকে, যার মানে হলো https://developer.chrome.com এর অরিজিন প্রাইভেট ফাইল সিস্টেমটি, ধরা যাক, 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);
প্রধান থ্রেড বা ওয়েব ওয়ার্কার
অরিজিন প্রাইভেট ফাইল সিস্টেম ব্যবহার করার দুটি উপায় আছে: মেইন থ্রেডে অথবা একটি ওয়েব ওয়ার্কারে । ওয়েব ওয়ার্কার মেইন থ্রেডকে ব্লক করতে পারে না, যার মানে হলো এই প্রেক্ষাপটে এপিআইগুলো সিনক্রোনাস হতে পারে, যা সাধারণত মেইন থ্রেডে অনুমোদিত নয়। সিনক্রোনাস এপিআইগুলো দ্রুততর হতে পারে কারণ এগুলোতে প্রমিজ নিয়ে কাজ করার প্রয়োজন হয় না, এবং সি-এর মতো যে ভাষাগুলোকে ওয়েবঅ্যাসেম্বলিতে কম্পাইল করা যায়, সেগুলোতে ফাইল অপারেশনগুলো সাধারণত সিনক্রোনাস হয়ে থাকে।
// This is synchronous C code.
FILE *f;
f = fopen("example.txt", "w+");
fputs("Some text\n", f);
fclose(f);
আপনার যদি দ্রুততম ফাইল অপারেশনের প্রয়োজন হয়, অথবা আপনি ওয়েবঅ্যাসেম্বলি (WebAssembly) নিয়ে কাজ করেন, তাহলে সরাসরি 'ওয়েব ওয়ার্কার (Web Worker)-এ অরিজিন প্রাইভেট ফাইল সিস্টেম (origin private file system) ব্যবহার ' অংশে চলে যান।
প্রধান থ্রেডে অরিজিন প্রাইভেট ফাইল সিস্টেম ব্যবহার করুন
নতুন ফাইল এবং ফোল্ডার তৈরি করুন
একবার আপনার একটি রুট ফোল্ডার তৈরি হয়ে গেলে, যথাক্রমে 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(): একটি বাফারের বিষয়বস্তু ফাইলে লেখে, যা ঐচ্ছিকভাবে একটি নির্দিষ্ট অফসেটে করা যায়, এবং লিখিত বাইটের সংখ্যা ফেরত দেয়। ফেরত আসা লিখিত বাইটের সংখ্যা পরীক্ষা করে কলাররা ত্রুটি এবং আংশিক লেখা শনাক্ত ও পরিচালনা করতে পারে। -
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);
}
অরিজিন প্রাইভেট ফাইল সিস্টেম ডিবাগ করুন
বিল্ট-ইন ডেভটুলস সাপোর্ট যোগ না হওয়া পর্যন্ত (দেখুন crbug/1284595 ), অরিজিন প্রাইভেট ফাইল সিস্টেম ডিবাগ করার জন্য OPFS Explorer ক্রোম এক্সটেনশনটি ব্যবহার করুন। প্রসঙ্গত, নতুন ফাইল ও ফোল্ডার তৈরি করার অংশের স্ক্রিনশটটি সরাসরি এক্সটেনশনটি থেকে নেওয়া হয়েছে।

এক্সটেনশনটি ইনস্টল করার পর, Chrome DevTools খুলুন, OPFS Explorer ট্যাবটি নির্বাচন করুন, এবং এরপর আপনি ফাইল হায়ারার্কি পরিদর্শন করার জন্য প্রস্তুত। অরিজিন প্রাইভেট ফাইল সিস্টেম থেকে ইউজার-ভিজিবল ফাইল সিস্টেমে ফাইল সেভ করতে ফাইলের নামে ক্লিক করুন এবং ফাইল ও ফোল্ডার ডিলিট করতে ট্র্যাশ ক্যান আইকনে ক্লিক করুন।
ডেমো
একটি ডেমোতে অরিজিন প্রাইভেট ফাইল সিস্টেমের কার্যকারিতা দেখুন (যদি আপনি OPFS Explorer এক্সটেনশনটি ইনস্টল করেন), যেখানে এটিকে WebAssembly-তে কম্পাইল করা একটি SQLite ডাটাবেসের ব্যাকএন্ড হিসেবে ব্যবহার করা হয়েছে। GitHub-এ এর সোর্স কোডটি অবশ্যই দেখে নেবেন। লক্ষ্য করুন, এমবেডেড সংস্করণটি অরিজিন প্রাইভেট ফাইল সিস্টেম ব্যাকএন্ড ব্যবহার করে না (কারণ আইফ্রেমটি ক্রস-অরিজিন), কিন্তু যখন আপনি ডেমোটি একটি আলাদা ট্যাবে খোলেন, তখন এটি তা ব্যবহার করে।
উপসংহার
WHATWG দ্বারা নির্দিষ্ট করা অরিজিন প্রাইভেট ফাইল সিস্টেম, ওয়েবে ফাইল ব্যবহার এবং তার সাথে মিথস্ক্রিয়ার পদ্ধতিকে নতুন রূপ দিয়েছে। এটি এমন সব নতুন ব্যবহারের সুযোগ তৈরি করেছে যা ব্যবহারকারী-দৃশ্যমান ফাইল সিস্টেমের মাধ্যমে অর্জন করা অসম্ভব ছিল। সমস্ত প্রধান ব্রাউজার নির্মাতা—অ্যাপল, মোজিলা এবং গুগল—এতে একমত এবং একটি যৌথ দৃষ্টিভঙ্গি পোষণ করে। অরিজিন প্রাইভেট ফাইল সিস্টেমের উন্নয়ন মূলত একটি সম্মিলিত প্রচেষ্টা, এবং এর অগ্রগতির জন্য ডেভেলপার ও ব্যবহারকারীদের মতামত অপরিহার্য।
যেহেতু আমরা মানটিকে পরিমার্জন ও উন্নত করে চলেছি, তাই whatwg/fs রিপোজিটরির উপর Issues বা Pull Requests আকারে মতামত সাদরে গৃহীত হবে।
সম্পর্কিত লিঙ্ক
- ফাইল সিস্টেম স্ট্যান্ডার্ড স্পেক
- ফাইল সিস্টেম স্ট্যান্ডার্ড রিপো
- অরিজিন প্রাইভেট ফাইল সিস্টেম ওয়েবকিট পোস্ট সহ ফাইল সিস্টেম এপিআই
- OPFS এক্সপ্লোরার এক্সটেনশন
কৃতজ্ঞতা স্বীকার
এই নথিটি অস্টিন সুলি , এতিয়েন নোয়েল এবং র্যাচেল অ্যান্ড্রু পর্যালোচনা করেছেন।