ফাইল সিস্টেম অ্যাক্সেস এপিআই ওয়েব অ্যাপগুলিকে ব্যবহারকারীর ডিভাইসের ফাইল এবং ফোল্ডারে সরাসরি পরিবর্তনগুলি পড়তে বা সংরক্ষণ করতে দেয়।
প্রকাশিত: ১৯ আগস্ট, ২০২৪
ফাইল সিস্টেম অ্যাক্সেস API ডেভেলপারদের শক্তিশালী ওয়েব অ্যাপ তৈরি করতে সক্ষম করে যা ব্যবহারকারীর স্থানীয় ডিভাইসে থাকা ফাইলগুলির সাথে ইন্টারঅ্যাক্ট করে, যেমন IDE, ফটো এবং ভিডিও এডিটর, টেক্সট এডিটর এবং আরও অনেক কিছু। ব্যবহারকারী যখন একটি ওয়েব অ্যাপ অ্যাক্সেস দেয়, তখন এই API তাদের ব্যবহারকারীর ডিভাইসে থাকা ফাইল এবং ফোল্ডারগুলিতে সরাসরি পরিবর্তনগুলি পড়তে বা সংরক্ষণ করতে দেয়। ফাইল পড়া এবং লেখার বাইরে, ফাইল সিস্টেম অ্যাক্সেস API একটি ডিরেক্টরি খোলার এবং এর বিষয়বস্তু গণনা করার ক্ষমতা প্রদান করে।
যদি আপনি আগে ফাইল পড়া এবং লেখার সাথে কাজ করে থাকেন, তাহলে আমি যা শেয়ার করতে যাচ্ছি তার বেশিরভাগই আপনার পরিচিত হবে। আমি আপনাকে যাইহোক এটি পড়তে উৎসাহিত করছি, কারণ সমস্ত সিস্টেম একই রকম হয় না।
ফাইল সিস্টেম অ্যাক্সেস API উইন্ডোজ, ম্যাকওএস, ক্রোমওএস, লিনাক্স এবং অ্যান্ড্রয়েডের বেশিরভাগ ক্রোমিয়াম ব্রাউজারে সমর্থিত। একটি উল্লেখযোগ্য ব্যতিক্রম হল ব্রেভ যেখানে এটি বর্তমানে শুধুমাত্র একটি পতাকার পিছনে উপলব্ধ ।
ফাইল সিস্টেম অ্যাক্সেস API ব্যবহার করে
ফাইল সিস্টেম অ্যাক্সেস API-এর শক্তি এবং উপযোগিতা দেখানোর জন্য, আমি একটি একক ফাইল টেক্সট এডিটর লিখেছি। এটি আপনাকে একটি টেক্সট ফাইল খুলতে, এটি সম্পাদনা করতে, পরিবর্তনগুলি ডিস্কে সংরক্ষণ করতে, অথবা একটি নতুন ফাইল শুরু করতে এবং পরিবর্তনগুলি ডিস্কে সংরক্ষণ করতে দেয়। এটি কোনও অভিনব জিনিস নয়, তবে ধারণাগুলি বুঝতে আপনাকে যথেষ্ট সাহায্য করে।
ব্রাউজার সাপোর্ট
বৈশিষ্ট্য সনাক্তকরণ
ফাইল সিস্টেম অ্যাক্সেস API সমর্থিত কিনা তা জানতে, আপনার আগ্রহী পিকার পদ্ধতিটি বিদ্যমান কিনা তা পরীক্ষা করুন।
if ('showOpenFilePicker' in self) {
// The `showOpenFilePicker()` method of the File System Access API is supported.
}
চেষ্টা করে দেখুন
টেক্সট এডিটর ডেমোতে ফাইল সিস্টেম অ্যাক্সেস API-এর কার্যকারিতা দেখুন।
স্থানীয় ফাইল সিস্টেম থেকে একটি ফাইল পড়ুন
আমি প্রথম যে ব্যবহারের ক্ষেত্রে এটি মোকাবেলা করতে চাই তা হল ব্যবহারকারীকে একটি ফাইল বেছে নিতে বলা, তারপর ডিস্ক থেকে সেই ফাইলটি খুলুন এবং পড়ুন।
ব্যবহারকারীকে পড়ার জন্য একটি ফাইল বেছে নিতে বলুন
ফাইল সিস্টেম অ্যাক্সেস API-এর এন্ট্রি পয়েন্ট হল window.showOpenFilePicker() । কল করা হলে, এটি একটি ফাইল পিকার ডায়ালগ দেখায় এবং ব্যবহারকারীকে একটি ফাইল নির্বাচন করতে অনুরোধ করে। তারা একটি ফাইল নির্বাচন করার পরে, API ফাইল হ্যান্ডেলগুলির একটি অ্যারে ফেরত দেয়। একটি ঐচ্ছিক options প্যারামিটার আপনাকে ফাইল পিকারের আচরণকে প্রভাবিত করতে দেয়, উদাহরণস্বরূপ, ব্যবহারকারীকে একাধিক ফাইল, বা ডিরেক্টরি, বা বিভিন্ন ধরণের ফাইল নির্বাচন করার অনুমতি দিয়ে। কোনও বিকল্প নির্দিষ্ট না করে, ফাইল পিকার ব্যবহারকারীকে একটি ফাইল নির্বাচন করতে দেয়। এটি একটি টেক্সট এডিটরের জন্য উপযুক্ত।
অন্যান্য অনেক শক্তিশালী API-এর মতো, 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 অবজেক্ট ফেরত আসে, যার মধ্যে একটি ব্লব থাকে। ব্লব থেকে ডেটা পেতে, এর যেকোনো একটি পদ্ধতি ( 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() কল করুন, যা ফাইল পিকারকে "সংরক্ষণ" মোডে দেখায়, যা ব্যবহারকারীকে সংরক্ষণের জন্য ব্যবহার করতে চান এমন একটি নতুন ফাইল নির্বাচন করতে দেয়। টেক্সট এডিটরের জন্য, আমি এটি স্বয়ংক্রিয়ভাবে একটি .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() , অথবা showOpenFilePicker পদ্ধতিতে একটি startIn প্রপার্টি পাস করে একটি ডিফল্ট স্টার্ট ডিরেক্টরি প্রস্তাব করতে পারেন।
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() কল করে (re-)request করুন। এটি ফাইল এবং ডিরেক্টরি হ্যান্ডেলের জন্য একই কাজ করে। আপনাকে যথাক্রমে 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 কী এবং true বা false এর বুলিয়ান মান সহ একটি ঐচ্ছিক options অবজেক্ট পাস করে, আপনি নির্ধারণ করতে পারেন যে একটি নতুন ফাইল বা ফোল্ডার তৈরি করা উচিত কিনা যদি এটি বিদ্যমান না থাকে।
// 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 অথবা FileSystemDirectoryHandle এ remove() কল করুন।
// Delete a file.
await fileHandle.remove();
// Delete a directory.
await directoryHandle.remove();
ফাইল এবং ফোল্ডারগুলির নাম পরিবর্তন এবং স্থানান্তর
FileSystemHandle ইন্টারফেসে move() কল করে ফাইল এবং ফোল্ডারগুলির নাম পরিবর্তন করা যেতে পারে অথবা নতুন স্থানে স্থানান্তর করা যেতে পারে। 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');
টেনে আনুন এবং ছেড়ে দিন ইন্টিগ্রেশন
HTML Drag and Drop ইন্টারফেস ওয়েব অ্যাপ্লিকেশনগুলিকে একটি ওয়েব পৃষ্ঠায় টেনে আনা এবং ফেলে দেওয়া ফাইল গ্রহণ করতে সক্ষম করে। একটি টেনে আনা এবং ড্রপ অপারেশনের সময়, টেনে আনা ফাইল এবং ডিরেক্টরি আইটেমগুলি যথাক্রমে ফাইল এন্ট্রি এবং ডিরেক্টরি এন্ট্রিগুলির সাথে যুক্ত হয়। DataTransferItem.getAsFileSystemHandle() পদ্ধতিটি যদি টেনে আনা আইটেমটি একটি ফাইল হয় তবে FileSystemFileHandle অবজেক্টের সাথে একটি প্রতিশ্রুতি প্রদান করে এবং যদি টেনে আনা আইটেমটি একটি ডিরেক্টরি হয় তবে FileSystemDirectoryHandle অবজেক্টের সাথে একটি প্রতিশ্রুতি প্রদান করে। নিম্নলিখিত তালিকাটি এটিকে কার্যকরভাবে দেখায়। মনে রাখবেন যে Drag and Drop ইন্টারফেসের DataTransferItem.kind ফাইল এবং ডিরেক্টরি উভয়ের জন্য "file" , যেখানে FileSystemHandle.kind ফাইল এবং ডিরেক্টরি উভয়ের জন্য "ফাইল" এবং ফাইল সিস্টেম অ্যাক্সেস API এর 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}`);
}
}
});
অরিজিন প্রাইভেট ফাইল সিস্টেম অ্যাক্সেস করা
"origin private file system" হল একটি স্টোরেজ এন্ডপয়েন্ট যা, নাম থেকেই বোঝা যায়, পৃষ্ঠার অরিজিনের সাথে প্রাইভেট। যদিও ব্রাউজারগুলি সাধারণত এই অরিজিন প্রাইভেট ফাইল সিস্টেমের কন্টেন্টগুলিকে ডিস্কে কোথাও রেখে এটি বাস্তবায়ন করে, তবুও এর উদ্দেশ্য এই নয় যে কন্টেন্টগুলি ব্যবহারকারীর কাছে অ্যাক্সেসযোগ্য হবে। একইভাবে, এমন কোনও ফাইল বা ডিরেক্টরি থাকার আশা করা যায় না যার নামের সাথে অরিজিন প্রাইভেট ফাইল সিস্টেমের শিশুদের নামের মিল রয়েছে। যদিও ব্রাউজারটি মনে করতে পারে যে ফাইল আছে, অভ্যন্তরীণভাবে - যেহেতু এটি একটি অরিজিন প্রাইভেট ফাইল সিস্টেম - ব্রাউজার এই "ফাইলগুলি" একটি ডাটাবেস বা অন্য কোনও ডেটা স্ট্রাকচারে সংরক্ষণ করতে পারে। মূলত, আপনি যদি এই API ব্যবহার করেন, তাহলে হার্ড ডিস্কের কোথাও তৈরি করা ফাইলগুলি একের সাথে মিলে যাবে বলে আশা করবেন না । রুট 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 });
অরিজিন প্রাইভেট ফাইল সিস্টেম থেকে পারফরম্যান্সের জন্য অপ্টিমাইজ করা ফাইলগুলিতে অ্যাক্সেস করা
অরিজিন প্রাইভেট ফাইল সিস্টেম একটি বিশেষ ধরণের ফাইলে ঐচ্ছিক অ্যাক্সেস প্রদান করে যা কর্মক্ষমতার জন্য অত্যন্ত অপ্টিমাইজ করা হয়, উদাহরণস্বরূপ, একটি ফাইলের বিষয়বস্তুতে ইন-প্লেস এবং এক্সক্লুসিভ লেখার অ্যাক্সেস প্রদান করে। 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 });
পলিফিলিং
ফাইল সিস্টেম অ্যাক্সেস API পদ্ধতিগুলি সম্পূর্ণরূপে পলিফিল করা সম্ভব নয়।
-
showOpenFilePicker()পদ্ধতিটি একটি<input type="file">উপাদানের সাথে আনুমানিক করা যেতে পারে। -
showSaveFilePicker()পদ্ধতিটি একটি<a download="file_name">উপাদান দিয়ে সিমুলেট করা যেতে পারে, যদিও এটি একটি প্রোগ্রাম্যাটিক ডাউনলোড ট্রিগার করে এবং বিদ্যমান ফাইলগুলিকে ওভাররাইট করার অনুমতি দেয় না। -
showDirectoryPicker()পদ্ধতিটি অ-মানক<input type="file" webkitdirectory>উপাদান দিয়ে কিছুটা অনুকরণ করা যেতে পারে।
আমরা browser-fs-access নামে একটি লাইব্রেরি তৈরি করেছি যা সম্ভব হলে ফাইল সিস্টেম অ্যাক্সেস API ব্যবহার করে এবং অন্যান্য সকল ক্ষেত্রে এই পরবর্তী সেরা বিকল্পগুলিতে ফিরে আসে।
নিরাপত্তা এবং অনুমতি
Chrome টিম "শক্তিশালী ওয়েব প্ল্যাটফর্ম বৈশিষ্ট্যগুলিতে অ্যাক্সেস নিয়ন্ত্রণ" -এ সংজ্ঞায়িত মূল নীতিগুলি ব্যবহার করে ফাইল সিস্টেম অ্যাক্সেস API ডিজাইন এবং বাস্তবায়ন করেছে, যার মধ্যে রয়েছে ব্যবহারকারী নিয়ন্ত্রণ এবং স্বচ্ছতা এবং ব্যবহারকারীর কর্মদক্ষতা।
একটি ফাইল খোলা বা একটি নতুন ফাইল সংরক্ষণ করা

একটি ফাইল খোলার সময়, ব্যবহারকারী ফাইল পিকার ব্যবহার করে একটি ফাইল বা ডিরেক্টরি পড়ার অনুমতি প্রদান করে। খোলা ফাইল পিকারটি শুধুমাত্র একটি নিরাপদ প্রেক্ষাপট থেকে পরিবেশন করা হলে ব্যবহারকারীর অঙ্গভঙ্গি ব্যবহার করে দেখানো যেতে পারে। ব্যবহারকারীরা যদি তাদের মন পরিবর্তন করে, তাহলে তারা ফাইল পিকারে নির্বাচন বাতিল করতে পারে এবং সাইটটি কোনও কিছুতে অ্যাক্সেস পাবে না। এটি <input type="file"> উপাদানের মতো একই আচরণ।

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

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

একবার একজন ব্যবহারকারী একটি ওয়েব অ্যাপকে স্থানীয় ফাইল সংরক্ষণের অনুমতি দিলে, ব্রাউজারটি ঠিকানা বারে একটি আইকন দেখায়। আইকনে ক্লিক করলে একটি পপ-ওভার খোলে যেখানে ব্যবহারকারীকে অ্যাক্সেস দেওয়া ফাইলগুলির তালিকা দেখানো হয়। ব্যবহারকারী চাইলে যেকোনো সময় সেই অ্যাক্সেস প্রত্যাহার করতে পারেন।
অনুমতির স্থায়িত্ব
ওয়েব অ্যাপটি ফাইলের পরিবর্তনগুলি প্রম্পট না করেই সংরক্ষণ করতে পারে যতক্ষণ না এর মূল অংশের সমস্ত ট্যাব বন্ধ হয়ে যায়। একবার একটি ট্যাব বন্ধ হয়ে গেলে, সাইটটি সমস্ত অ্যাক্সেস হারায়। পরের বার ব্যবহারকারী যখন ওয়েব অ্যাপ ব্যবহার করবেন, তখন তাদের ফাইলগুলিতে অ্যাক্সেসের জন্য পুনরায় অনুরোধ করা হবে।
প্রতিক্রিয়া
ফাইল সিস্টেম অ্যাক্সেস এপিআই সম্পর্কে আপনার অভিজ্ঞতা সম্পর্কে আমরা শুনতে চাই।
API ডিজাইন সম্পর্কে আমাদের বলুন
API-তে কি এমন কিছু আছে যা আপনার প্রত্যাশা অনুযায়ী কাজ করছে না? নাকি আপনার ধারণা বাস্তবায়নের জন্য প্রয়োজনীয় কোনও পদ্ধতি বা বৈশিষ্ট্য অনুপস্থিত? নিরাপত্তা মডেল সম্পর্কে আপনার কোন প্রশ্ন বা মন্তব্য আছে?
- WICG ফাইল সিস্টেম অ্যাক্সেস গিটহাব রেপোতে একটি স্পেক সমস্যা ফাইল করুন, অথবা বিদ্যমান কোনও সমস্যায় আপনার মতামত যোগ করুন।
বাস্তবায়নে সমস্যা?
আপনি কি Chrome এর বাস্তবায়নে কোন বাগ খুঁজে পেয়েছেন? নাকি বাস্তবায়নটি স্পেসিফিকেশন থেকে আলাদা?
- https://new.crbug.com এ একটি বাগ ফাইল করুন। যতটা সম্ভব বিস্তারিত তথ্য, পুনরুৎপাদনের নির্দেশাবলী অন্তর্ভুক্ত করতে ভুলবেন না এবং Components কে
Blink>Storage>FileSystemএ সেট করুন।
API ব্যবহার করার পরিকল্পনা করছেন?
আপনার সাইটে ফাইল সিস্টেম অ্যাক্সেস এপিআই ব্যবহার করার পরিকল্পনা করছেন? আপনার জনসাধারণের সমর্থন আমাদের বৈশিষ্ট্যগুলিকে অগ্রাধিকার দিতে সাহায্য করে এবং অন্যান্য ব্রাউজার বিক্রেতাদের দেখায় যে তাদের সমর্থন করা কতটা গুরুত্বপূর্ণ।
- আপনি কীভাবে এটি ব্যবহার করার পরিকল্পনা করছেন তা WICG ডিসকোর্স থ্রেডে শেয়ার করুন।
-
#FileSystemAccessহ্যাশট্যাগ ব্যবহার করে @ChromiumDev- এ একটি টুইট পাঠান এবং আপনি এটি কোথায় এবং কীভাবে ব্যবহার করছেন তা আমাদের জানান।
সহায়ক লিঙ্ক
- পাবলিক ব্যাখ্যাকারী
- ফাইল সিস্টেম অ্যাক্সেস স্পেসিফিকেশন এবং ফাইল স্পেসিফিকেশন
- ট্র্যাকিং বাগ
- ChromeStatus.com এন্ট্রি
- টাইপস্ক্রিপ্ট সংজ্ঞা
- ফাইল সিস্টেম অ্যাক্সেস API - Chromium নিরাপত্তা মডেল
- ব্লিঙ্ক কম্পোনেন্ট:
Blink>Storage>FileSystem
স্বীকৃতি
ফাইল সিস্টেম অ্যাক্সেস API স্পেকটি মারিজন ক্রুসেলব্রিঙ্ক লিখেছেন।