خواندن فایل ها در جاوا اسکریپت

انتخاب و تعامل با فایل‌ها در دستگاه محلی کاربر یکی از رایج‌ترین ویژگی‌های وب است. این قابلیت به کاربران اجازه می‌دهد تا فایل‌ها را انتخاب کرده و آنها را در یک سرور آپلود کنند، برای مثال، هنگام اشتراک‌گذاری عکس‌ها یا ارسال اسناد مالیاتی. همچنین به سایت‌ها اجازه می‌دهد تا بدون نیاز به انتقال داده‌ها در شبکه، آنها را بخوانند و دستکاری کنند. این صفحه نحوه استفاده از جاوا اسکریپت برای تعامل با فایل‌ها را شرح می‌دهد.

API دسترسی به سیستم فایل مدرن

رابط برنامه‌نویسی کاربردی دسترسی به سیستم فایل (File System Access API) راهی برای خواندن و نوشتن در فایل‌ها و دایرکتوری‌ها در سیستم محلی کاربر فراهم می‌کند. این رابط در اکثر مرورگرهای مبتنی بر کرومیوم مانند کروم و اج موجود است. برای کسب اطلاعات بیشتر در مورد آن، به «رابط برنامه‌نویسی کاربردی دسترسی به سیستم فایل» مراجعه کنید.

از آنجا که API دسترسی به سیستم فایل با همه مرورگرها سازگار نیست، توصیه می‌کنیم از browser-fs-access استفاده کنید، یک کتابخانه کمکی که در صورت وجود API جدید از آن استفاده می‌کند و در صورت عدم وجود آن، به رویکردهای قدیمی بازمی‌گردد.

کار با فایل‌ها، به روش کلاسیک

این راهنما به شما نشان می‌دهد که چگونه با استفاده از متدهای قدیمی جاوا اسکریپت با فایل‌ها تعامل داشته باشید.

انتخاب فایل‌ها

دو روش اصلی برای انتخاب فایل‌ها وجود دارد: استفاده از عنصر ورودی HTML و استفاده از ناحیه کشیدن و رها کردن .

عنصر ورودی HTML

ساده‌ترین راه برای انتخاب فایل‌ها توسط کاربران، استفاده از عنصر <input type="file"> است که در هر مرورگر اصلی پشتیبانی می‌شود. وقتی روی آن کلیک شود، به کاربر اجازه می‌دهد یک فایل یا در صورت وجود ویژگی multiple ، چندین فایل را با استفاده از رابط کاربری انتخاب فایل داخلی سیستم عامل خود انتخاب کند. وقتی کاربر انتخاب یک یا چند فایل را تمام کرد، رویداد change عنصر فعال می‌شود. می‌توانید از event.target.files که یک شیء FileList است، به لیست فایل‌ها دسترسی پیدا کنید. هر آیتم در FileList یک شیء File است.

<!-- The `multiple` attribute lets users select multiple files. -->
<input type="file" id="file-selector" multiple>
<script>
  const fileSelector = document.getElementById('file-selector');
  fileSelector.addEventListener('change', (event) => {
    const fileList = event.target.files;
    console.log(fileList);
  });
</script>

مثال زیر به کاربر اجازه می‌دهد چندین فایل را با استفاده از رابط کاربری انتخاب فایل داخلی سیستم عامل خود انتخاب کند و سپس هر فایل انتخاب شده را در کنسول ثبت کند.

محدود کردن انواع فایل‌هایی که کاربران می‌توانند انتخاب کنند

در برخی موارد، ممکن است بخواهید انواع فایل‌هایی را که کاربران می‌توانند انتخاب کنند محدود کنید. برای مثال، یک برنامه ویرایش تصویر فقط باید تصاویر را بپذیرد، نه فایل‌های متنی. برای تنظیم محدودیت‌های نوع فایل، یک ویژگی accept به عنصر ورودی اضافه کنید تا مشخص شود کدام نوع فایل‌ها پذیرفته می‌شوند:

<input type="file" id="file-selector" accept=".jpg, .jpeg, .png">

کشیدن و رها کردن سفارشی

در برخی از مرورگرها، عنصر <input type="file"> همچنین یک هدف رها کردن است که به کاربران امکان می‌دهد فایل‌ها را با کشیدن و رها کردن به برنامه شما وارد کنند. با این حال، این هدف رها کردن کوچک است و استفاده از آن می‌تواند دشوار باشد. در عوض، پس از ارائه ویژگی‌های اصلی با استفاده از عنصر <input type="file"> ، می‌توانید یک سطح بزرگ و سفارشی برای کشیدن و رها کردن فراهم کنید.

منطقه رهاسازی خود را انتخاب کنید

سطح سقوط شما به طراحی کاربردتان بستگی دارد. ممکن است فقط بخواهید بخشی از پنجره به عنوان سطح سقوط باشد، اما می‌توانید از کل پنجره استفاده کنید.

تصویری از Squoosh، یک برنامه وب فشرده‌سازی تصویر.
Squoosh کل پنجره را به یک منطقه‌ی رهاسازی تبدیل می‌کند.

برنامه فشرده‌سازی تصویر Squoosh به کاربر اجازه می‌دهد تا یک تصویر را به هر جایی از پنجره بکشد و برای فراخوانی عنصر <input type="file"> روی انتخاب تصویر کلیک کند. هر قسمتی را که به عنوان ناحیه رها کردن انتخاب می‌کنید، مطمئن شوید که برای کاربر واضح است که می‌تواند فایل‌ها را به آن سطح بکشد.

منطقه سقوط را تعریف کنید

برای فعال کردن یک عنصر به عنوان یک منطقه کشیدن و رها کردن، شنونده‌هایی برای دو رویداد ایجاد کنید: dragover و رها کردن (dragover) و drop (drop). رویداد dragover رابط کاربری مرورگر را به‌روزرسانی می‌کند تا به صورت بصری نشان دهد که عمل کشیدن و رها کردن در حال ایجاد یک کپی از فایل است. رویداد drop پس از اینکه کاربر فایل‌ها را روی سطح رها کرد، فعال می‌شود. همانند عنصر ورودی، می‌توانید به لیست فایل‌ها از event.dataTransfer.files که یک شیء FileList است، دسترسی پیدا کنید. هر آیتم در FileList یک شیء File است.

const dropArea = document.getElementById('drop-area');

dropArea.addEventListener('dragover', (event) => {
  event.stopPropagation();
  event.preventDefault();
  // Style the drag-and-drop as a "copy file" operation.
  event.dataTransfer.dropEffect = 'copy';
});

dropArea.addEventListener('drop', (event) => {
  event.stopPropagation();
  event.preventDefault();
  const fileList = event.dataTransfer.files;
  console.log(fileList);
});

event.stopPropagation() و event.preventDefault() رفتار پیش‌فرض مرورگر را متوقف می‌کنند و به جای آن اجازه می‌دهند کد شما اجرا شود. بدون آنها، مرورگر از صفحه شما خارج شده و فایل‌هایی را که کاربر در پنجره مرورگر قرار داده است، باز می‌کند.

برای نمایش زنده، به کشیدن و رها کردن سفارشی مراجعه کنید.

در مورد دایرکتوری‌ها چطور؟

متأسفانه، روش مناسبی برای دسترسی به یک دایرکتوری با استفاده از جاوا اسکریپت وجود ندارد.

ویژگی webkitdirectory در عنصر <input type="file"> به کاربر اجازه می‌دهد یک یا چند دایرکتوری را انتخاب کند. این ویژگی در اکثر مرورگرهای اصلی به جز فایرفاکس برای اندروید و سافاری برای iOS پشتیبانی می‌شود .

اگر قابلیت کشیدن و رها کردن فعال باشد، کاربر ممکن است سعی کند یک دایرکتوری را به داخل ناحیه رها کردن بکشد. وقتی رویداد رها کردن اجرا می‌شود، یک شیء File برای دایرکتوری اضافه می‌شود، اما دسترسی به هیچ یک از فایل‌های موجود در دایرکتوری را فراهم نمی‌کند.

خواندن متادیتای فایل

شیء File شامل فراداده‌هایی در مورد فایل است. اکثر مرورگرها نام فایل، اندازه فایل و نوع MIME را ارائه می‌دهند، اگرچه بسته به پلتفرم، مرورگرهای مختلف ممکن است اطلاعات متفاوت یا اضافی ارائه دهند.

function getMetadataForFileList(fileList) {
  for (const file of fileList) {
    // Not supported in Safari for iOS.
    const name = file.name ? file.name : 'NOT SUPPORTED';
    // Not supported in Firefox for Android or Opera for Android.
    const type = file.type ? file.type : 'NOT SUPPORTED';
    // Unknown cross-browser support.
    const size = file.size ? file.size : 'NOT SUPPORTED';
    console.log({file, name, type, size});
  }
}

می‌توانید این را در عمل در نسخه نمایشی input-type-file مشاهده کنید.

خواندن محتوای یک فایل

FileReader برای خواندن محتوای یک شیء File در حافظه استفاده کنید. می‌توانید به FileReader بگویید که یک فایل را به عنوان یک بافر آرایه ، یک URL داده یا متن بخواند:

function readImage(file) {
  // Check if the file is an image.
  if (file.type && !file.type.startsWith('image/')) {
    console.log('File is not an image.', file.type, file);
    return;
  }

  const reader = new FileReader();
  reader.addEventListener('load', (event) => {
    img.src = event.target.result;
  });
  reader.readAsDataURL(file);
}

این مثال File که توسط کاربر ارائه شده است می‌خواند، سپس آن را به یک URL داده تبدیل می‌کند و از آن URL داده برای نمایش تصویر در یک عنصر img استفاده می‌کند. برای یادگیری نحوه تأیید اینکه کاربر یک فایل تصویری را انتخاب کرده است، به نسخه آزمایشی read-image-file مراجعه کنید.

نظارت بر پیشرفت خواندن یک فایل

هنگام خواندن فایل‌های بزرگ، ارائه یک رابط کاربری (UX) برای اطلاع کاربر از میزان پیشرفت خواندن می‌تواند مفید باشد. برای این کار، از رویداد progress که توسط FileReader ارائه می‌شود استفاده کنید. رویداد progress دو ویژگی دارد: loaded (مقدار خوانده شده) و total (مقدار خوانده شده).

function readFile(file) {
  const reader = new FileReader();
  reader.addEventListener('load', (event) => {
    const result = event.target.result;
    // Do something with result
  });

  reader.addEventListener('progress', (event) => {
    if (event.loaded && event.total) {
      const percent = (event.loaded / event.total) * 100;
      console.log(`Progress: ${Math.round(percent)}`);
    }
  });
  reader.readAsDataURL(file);
}