У меня проблема с загрузкой 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. Есть идеи? К сожалению, я не могу просто попросить пользователей переименовать папки, потому что эти имена папок созданы другим программным обеспечением.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Насколько я знаю, 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 может быть сложной задачей, особенно со специальными символами в именах. Вот почему и некоторые альтернативные подходы:
Проблемы с загрузкой папок:
<input type = "file">) не поддерживает прямой выбор папок. Хотя атрибут webkitdirectory существует (для Chrome и Safari), он не поддерживается широко и может быть признан устаревшим.Альтернативные подходы:
Использование библиотек:
Такие библиотеки, как https://react-dropzone.js.org/, могут обрабатывать выбор папок и предоставлять удобный интерфейс перетаскивания. Эти библиотеки часто обрабатывают специальные символы, соответствующим образом кодируя их перед отправкой на сервер.
Файловый API с рекурсией:
Вы можете использовать API файлов HTML5 с объектом DirectoryReader для перемещения по выбранной структуре каталогов. Вот разбивка:
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 = "";
};