Как загрузить папки, чтобы реагировать со спецсимволами в названии

У меня проблема с загрузкой javascript: Я использую этот код:

const handleParameterSearchUpload = async (event) => {
    const files = event.target.files;
    console.info(files);
    const folders = {};

    for (let i = 0; i < files.length; i++) {
      const file = files[i];
      const filePath = file.webkitRelativePath;
      const pathParts = filePath.split('/');

      // If the file is in a subfolder, add the file to the folder's list
      if (pathParts.length > 2) {
        const folderName = encodeURIComponent(pathParts[1]);
        if (!folders[folderName]) {
          folders[folderName] = [];
        }
        folders[folderName].push(file);
      }
    }
    console.info(folders.length);
    // Call processFiles for each folder
    for (const folderName in folders) {
      const folderFiles = folders[folderName];
      await processFiles(folderFiles, true);
      console.info("Processed", folderName);
    }
    parameterSearchInputRef.current.value = "";
  };

для обработки файлов в папке.

Здесь используется этот код:

<input
  type = "file"
  webkitdirectory = "true"
  style = {{ display: 'none' }
  ref = {parameterSearchInputRef} 
  onChange = {handleParameterSearchUpload} 
/>

Теперь в этой папке есть файлы и подпапки, которые не пустуют. К сожалению, у меня проблема. Когда я загружаю папку, загружаются файлы, но не подпапки. Проблема не в коде, потому что когда я переименовываю папку, она работает нормально, но с этим именем папки, которое я загружаю:

20240118-165159[param.defaults]CombinationParamSearch{sheets.l4_cortex_inh.params.cell.params.v_thresh_[-57.5, -58],sheets.l4_cortex_exc.AfferentConnection.base_weight_[0.0013, 0.0016, 0.0018]}

это не работает.

К сожалению, я всегда буду загружать эти типы папок на веб-страницу. Как решить проблему? Подпапки имеют следующее название: SelfSustainedPushPull_ParameterSearch_____base_weight_0.0013_v_thresh_-57.5SelfSustainedPushPull_ParameterSearch_____base_weight_0.0013_v_thresh_-58

и так далее

К сожалению, основная проблема заключается в том, что подпапки, похоже, не загружаются, потому что, если я регистрирую консоль, ни подпапки, ни содержимое внутри них не регистрируются. Я действительно не знаю, как решить эту проблему, не используя пакеты типа fs или path. Есть идеи? К сожалению, я не могу просто попросить пользователей переименовать папки, потому что эти имена папок созданы другим программным обеспечением.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
147
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Насколько я знаю, React не любит webkitdirectory, а также webkitdirectory может скоро быть устаревшим в пользу дропзон. Не совсем уверен в этом, но это то, что я читал в некоторых обсуждениях по этому поводу. Кроме того, я не думаю, что он полностью совместим со всеми браузерами. См. совместимость браузеров.

Для загрузки файлов с помощью каталогов и подкаталогов зачастую более эффективно использовать стандартный «API файлов HTML» в сочетании с DirectoryReader. Еще одна вещь, которую следует учитывать, — это рекурсивный обход структуры каталогов.

Вот пример того, как вы можете это реализовать:

const handleParameterSearchUpload = async (event) => {
  const traverseFiles = async (files) => {
    for (let i = 0; i < files.length; i++) {
      const file = files[i];
      if (file.isDirectory) {
        const directoryReader = file.createReader();
        const entries = await new Promise((resolve) => {
          directoryReader.readEntries(resolve);
        });
        await traverseFiles(entries);
      } else {
        // Process the file
        console.info("Uploading file:", file.name);
        // Upload logic
    }
  };

  const files = event.target.files;
  console.info("Uploaded files:", files);

  await traverseFiles(files);

  // Clear `event.target.value` instead, since we can access the input element
  // directly from the event object. No need for ref.
  event.target.value = "";
};

На всякий случай я также хочу упомянуть: вам нужно использовать decodeURIComponent, чтобы получить исходное имя папки после ее закодирования.

Вообще говоря, использование FTP или SFTP для загрузки файлов на сервер было бы идеальным подходом для обработки папок с несколькими подпапками и файлами. HTTP не совсем подходит для массовой передачи файлов. Другое решение, которое вы можете рассмотреть, — это заархивировать файлы перед их загрузкой на сервер, а затем разархивировать их на стороне сервера.

Непосредственная загрузка папок с Javascript в React может быть сложной задачей, особенно со специальными символами в именах. Вот почему и некоторые альтернативные подходы:

Проблемы с загрузкой папок:

  • Ограничения браузера: стандартный элемент загрузки HTML-файла (<input type = "file">) не поддерживает прямой выбор папок. Хотя атрибут webkitdirectory существует (для Chrome и Safari), он не поддерживается широко и может быть признан устаревшим.

Альтернативные подходы:

  1. Использование библиотек:

    Такие библиотеки, как https://react-dropzone.js.org/, могут обрабатывать выбор папок и предоставлять удобный интерфейс перетаскивания. Эти библиотеки часто обрабатывают специальные символы, соответствующим образом кодируя их перед отправкой на сервер.

  2. Файловый API с рекурсией:

    Вы можете использовать API файлов HTML5 с объектом DirectoryReader для перемещения по выбранной структуре каталогов. Вот разбивка:

    • Зафиксируйте событие выбора файла в своем компоненте React.
    • Используйте event.target.files для доступа к выбранным файлам.
    • Прокрутите файлы:
      • Если это каталог, используйте createReader для файлового объекта, чтобы создать DirectoryReader.
      • Используйте readEntries на ридере, чтобы получить массив дочерних записей (файлов и подкаталогов).
      • Вызовите рекурсивную функцию для обработки каждой записи (обработка файлов и повторение для каталогов).
    • Внутри цикла поиска файлов проверьте, является ли это каталогом, используя file.isDirectory.
    • Что касается файлов, вы можете обрабатывать их загрузку с помощью специальных символов, кодируя имена файлов с помощью encodeURIComponent перед отправкой их на сервер. Не забудьте декодировать их обратно на стороне сервера.

Важная заметка:

Загрузка больших структур папок с большим количеством файлов может не подходить для HTTP-запросов из-за ограничений. Рассмотрите библиотеки или серверные решения для обработки больших загрузок.

const handleFolderUpload = async (event) => {
  const files = event.target.files;

  const traverseFiles = async (entries) => {
    for (let i = 0; i < entries.length; i++) {
      const entry = entries[i];
      if (entry.isDirectory) {
        const directoryReader = entry.createReader();
        const subEntries = await new Promise((resolve) => directoryReader.readEntries(resolve));
        await traverseFiles(subEntries);
      } else {
        // Process the file
        const encodedFilename = encodeURIComponent(entry.name);
        console.info("Uploading file:", encodedFilename);
        // Implement your upload logic here, sending encodedFilename to the server
      }
    }
  };

  await traverseFiles(files);
  // Clear the file input after processing
  event.target.value = "";
};

Другие вопросы по теме