Парсинг данных с файла
Мне необходимо сделать правильное чтение данных из txt-файла и по полученным данным построить один график для необходимого спектра(который выберет пользователь). В txt-файле несколько спектров, до 9 максимум. TXT-файл имеет такое наполнение:
Длина волны, нм % пропускания
Спектр 0
400,0 36,3558
401,0 35,6798
-- --
1095,2 60,4672
1096,2 60,6842
Спектр 3
400,0 16,0264
401,0 15,0475
Моя проблема в том, что не читаются правильно/не воспринимаются данные и дальше не происходит чтение для построения графика. В консоли пишет, что массив полученных данных 0, 0 полученных данных, ошибка парсинга и т.д. Мой код parseFile.jsx:
export default function parseFile(fileContent) {
const spectra = fileContent
.split('Спектр ')
.slice(1)
.map((spectrumData) => {
const lines = spectrumData.trim().split('\n');
const spectrumName = `Спектр ${lines.shift()}`;
const data = lines.map(line => {
const [wavelength, coefficient] = line.split(/\s+/).map(value => parseFloat(value.replace(',', '.')));
return { wavelength, coefficient };
});
return { name: spectrumName, data };
});
console.log("Parsed Spectra:", spectra);
return spectra.slice(0, 9);
}
Пробовал еще добавить конвертер файла, данные из файла все также не читаются. Код convertFile.jsx:
export default function convertFile(fileContent) {
if (typeof fileContent !== 'string') {
console.error("Invalid file content type:", typeof fileContent);
return '';
}
const lines = fileContent.split('\n');
const convertedLines = [];
let currentSpectrum = null;
lines.forEach((line) => {
const trimmedLine = line.trim();
if (/^Спектр\s*\d+/i.test(trimmedLine)) {
currentSpectrum = trimmedLine;
convertedLines.push(trimmedLine);
} else if (currentSpectrum && trimmedLine.includes(',')) {
const [wavelength, coefficient] = trimmedLine.split(',').map(Number);
if (!isNaN(wavelength) && !isNaN(coefficient) && wavelength >= 400 && wavelength <= 1100) {
convertedLines.push(`${wavelength},${coefficient}`);
}
}
});
const convertedContent = convertedLines.join('\n');
console.log("Converted Content:", convertedContent);
return convertedContent;
}
Если нужен какой-либо еще файл, то напишите. Вот структура проекта:
- ├── /src
- │ ├── /components
- │ │ ├── FileUpload.jsx
- │ │ ├── Chart.jsx
- │ │ ├── Header.jsx
- │ │ ├── SpectrumSelector.jsx
- │ │ ├── WelcomePage.jsx
- │ ├── /styles
- │ │ ├── FileUpload.css
- │ │ ├── Chart.css
- │ │ ├── Header.css
- │ │ ├── SpectrumSelector.css
- │ │ ├── WelcomePage.css
- │ ├── /utils
- │ │ └── parseFile.jsx
- │ │ └── convertFile.jsx
- │ ├── App.jsx
- │ ├── main.jsx
- │ ├── index.css
- │ ├── App.css
Загружаемый файл обрабатывается в файлах App и FileUpload. FileUpload:
import PropTypes from 'prop-types';
import parseFile from '../utils/parseFile';
import convertFile from '../utils/convertFile';
import { useState } from 'react';
import '../styles/FileUpload.css';
function FileUpload({ onFileData }) {
const [fileName, setFileName] = useState("Файл не выбран");
const [inputKey, setInputKey] = useState(Date.now()); // Уникальный ключ для input
const handleFileChange = (event) => {
const file = event.target.files[0];
if (file) {
setFileName(file.name);
const reader = new FileReader();
reader.onload = (e) => {
try {
const buffer = e.target.result;
if (!(buffer instanceof ArrayBuffer)) {
throw new Error("Invalid buffer type"); // Если не ArrayBuffer, вызываем ошибку
}
let decoder = new TextDecoder("utf-8");
let text = decoder.decode(buffer);
if (!/[А-Яа-яЁё]/.test(text)) {
decoder = new TextDecoder("windows-1251");
text = decoder.decode(buffer);
}
console.log("File Content:", text);
const convertedContent = convertFile(text);
const parsedData = parseFile(convertedContent);
onFileData(parsedData);
} catch (error) {
console.error('Error parsing file:', error);
alert('Ошибка при парсинге файла. Пожалуйста, проверьте формат.');
onFileData(null);
}
};
reader.readAsArrayBuffer(file);
}
};
const handleReset = () => {
setFileName("Файл не выбран");
onFileData(null); // Передаем пустое значение для сброса графика
setInputKey(Date.now()); // Обновляем ключ для сброса input
};
return (
<div className="file-upload-container">
<label htmlFor="file-upload" className="file-label">{fileName}</label>
<input
key={inputKey}
id="file-upload"
type="file"
accept=".txt"
onChange={handleFileChange}
className="file-input"
/>
{fileName !== "Файл не выбран" && (
<button className="reset-button" onClick={handleReset}>
Очистить график
</button>
)}
</div>
);
}
FileUpload.propTypes = {
onFileData: PropTypes.func.isRequired,
};
export default FileUpload;
и App
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
import { useState } from 'react';
import WelcomePage from './components/WelcomePage';
import FileUpload from './components/FileUpload';
import Chart from './components/Chart';
import Header from './components/Header';
import convertFile from './utils/convertFile';
import parseFile from './utils/parseFile';
import SpectrumSelector from './components/SpectrumSelector';
import './App.css';
import './styles/FileUpload.css';
function App() {
const [data, setSpectraData] = useState(null);
const [selectedSpectrum, setSelectedSpectrum] = useState(null);
const handleFileData = (fileContent) => {
// Преобразуем данные перед парсингом
const convertedContent = convertFile(fileContent);
const parsedData = parseFile(convertedContent); // Парсим преобразованный файл
console.log('Parsed Data:', parsedData); // Выводим результат в консоль для проверки
setSpectraData(parsedData);
if (parsedData.length > 0) {
setSelectedSpectrum(parsedData[0].name); // Выбираем первый спектр по умолчанию
}
};
const handleSpectrumChange = (spectrumName) => {
console.log('Selected Spectrum:', spectrumName); // Отладочный вывод
setSelectedSpectrum(spectrumName);
};
return (
<Router>
<div className="app-container">
<Header />
<Routes>
<Route path="/" element={<WelcomePage />} />
<Route
path="/upload"
element={
<div className="upload-page">
<h1>Оптические свойства тонких пленок</h1>
<FileUpload onFileData={handleFileData} />
{data && (
<>
<SpectrumSelector
spectra={data}
selectedSpectrum={selectedSpectrum}
onSpectrumChange={handleSpectrumChange}
/>
{selectedSpectrum && (
<Chart data={data.find(spectrum => spectrum.name === selectedSpectrum)} />
)}
</>
)}
</div>
}
/>
</Routes>
</div>
</Router>
);
}
export default App;