matlab-import-export-data
GitHub提供MATLAB中CSV、Excel、JSON等数据文件的导入导出最佳实践,涵盖格式处理、编码、URL读取及错误排查。
Trigger Scenarios
Install
npx skills add matlab/matlab-agentic-toolkit --skill matlab-import-export-data -g -y
SKILL.md
Frontmatter
{
"name": "matlab-import-export-data",
"license": "https:\/\/www.mathworks.com\/content\/dam\/mathworks\/license\/pmrl\/license.md",
"metadata": {
"author": "MathWorks",
"version": "1.0"
},
"description": "Read or write data files in MATLAB. Use when the task involves tables, spreadsheets, delimited text, or structured files in CSV, Excel, Parquet, JSON, or XML format — including but not limited to importing, exporting, loading, parsing, converting, validating, configuring import options, reading from URLs, handling locales or encodings, diagnosing file errors, and modernizing legacy file I\/O code. MATLAB provides built-in functions for these workflows with no additional products required.\n"
}
MATLAB Data Import/Export
Guidance for MATLAB data I/O — correct patterns for delimiters, locales, format-specific quirks, and common error messages.
When to Use
- Reading or writing CSV, Excel, Parquet, or JSON files in MATLAB with
readtable/writetable/detectImportOptions - Troubleshooting data I/O errors (misleading messages, "file not found" variants)
- Reading data from URLs or authenticated REST API endpoints
- Importing non-English locale data (European decimals, semicolons)
- Validating imported data for silent corruption (NaN, 65535, type widening)
- Reading compressed files or JSON with non-identifier keys
- Reading or writing text files (use
readlines/writelines, notfopen/fgetl/fprintf) - Reading or writing XML files (use MAXP provider, not legacy JAXP)
When NOT to Use
- Large files that may not fit in memory, or choosing between tall arrays, datastores, and parallel workflows (use
matlab-choose-big-data-solutionskill) - Database access via ODBC/JDBC — reading, writing, or querying relational databases (use
matlab-use-databaseskill) - SQL-based queries on large CSV/Parquet/JSON files for reduction before analysis (use
matlab-use-duckdbskill) - Vehicle data from MDF/MF4/BLF/ASC log files or CAN/LIN bus decoding (use
matlab-import-export-vehicle-dataskill) - Vehicle network communication setup with CAN/CAN FD/J1939 (use
matlab-use-vehicle-networkskill) - Tracking data import for sensor fusion workflows (use
matlab-import-tracking-dataskill) - Medical image data — DICOM, NIfTI, or Analyze formats (use
matlab-read-medical-dataskill) - Market or financial data feeds (use
matlab-access-datafeedskill) - Simulink data logging or signal I/O (use Simulink-specific workflows)
- Image or audio file I/O (
imread,audioread— different domain) - Streaming or real-time data acquisition (use Data Acquisition Toolbox)
- File system operations, path manipulation, or folder traversal
General principles
- Validate after import. Append 2-3 assertion-style checks that verify the imported data matches expectations.
- Always set
TextType="string"for text and Excel imports — thestringtype is more efficient and easier to work with than char or cell arrays of character vectors. This only needs to be set for delimited text and spreadsheet formats; XML, JSON, and other formats already return strings by default. - Specify
FileTypewhen reading from URLs that lack a recognizable extension — MIME type detection handles some cases, but API endpoints and non-standard URLs still need explicit format (see Topic 4). When usingdetectImportOptionswithreadtable, passFileTypeondetectImportOptions—readtabledoes not acceptFileTypewhen an import options object is provided. - Handle missing value placeholders at read time — use
TreatAsMissingonreadtableinstead of callingstandardizeMissingafter import. - Read directly from compressed files —
readtable,readmatrix,readtimetable, and other read functions accept ZIP, GZ, and TAR file paths directly without manual extraction (R2025a+). - European CSVs use
;as delimiter because,is the decimal separator — set bothDelimiterandDecimalSeparatorwhen contextual cues suggest European-format data.
Topics
1. Import Function Selection (Delimiter & Locale Handling)
When contextual cues suggest European-format data (German/French/Italian offices, semicolon-delimited files, column names in a European language), proactively set Delimiter, DecimalSeparator, and Encoding (UTF-8 for umlauts/accents):
opts = detectImportOptions("messdaten.csv", ...
"Delimiter", ";", "DecimalSeparator", ",", "Encoding", "UTF-8");
T = readtable("messdaten.csv", opts);
For files containing path-like data (/data/exp_01/run_003/results.mat), explicitly set the actual delimiter — detection may pick / from the path column:
opts = detectImportOptions("fileList.csv");
opts.Delimiter = ",";
T = readtable("fileList.csv", opts);
For numeric data with embedded unit suffixes (e.g., 6.53e+001dB, -9.00e+001°), use TrimNonNumeric (R2022a+) to strip non-numeric characters instead of textscan or regexp:
T = readtable("circuit_output.txt", "Delimiter", {"\t", ","}, ...
"NumHeaderLines", 1, "TrimNonNumeric", true);
TrimNonNumeric can be passed directly to readtable as a name-value pair, or set per-variable via setvaropts(opts, vars, "TrimNonNumeric", true) when only specific columns have suffixes.
2. Error Message Interpretation
MATLAB I/O error messages can be broad, pointing to a general category rather than the specific issue:
| Error Message | Likely Actual Cause | Recovery |
|---|---|---|
"Entry may be password-protected or encrypted" |
Disk space insufficient in temp directory for unzip (observed in R2020a–R2023b) | Check available space with tempdir; free space or redirect temp |
"Unrecognized file extension" |
URL lacks a recognizable file extension | Specify FileType name-value pair explicitly (see Topic 4) |
3. Import Validation & Data Fidelity
After importing from Excel or Parquet, check for silent data corruption:
-
Excel
Inf→ 65535: BothInfand-Infare written as 65535. Values of exactly 65535 that seem physically implausible likely represent Inf. -
Excel complex → NaN: Excel cannot store complex numbers. An entirely NaN column from a spreadsheet may contain complex data in the source.
-
Parquet integer columns with nulls → silent type promotion: When any integer column (int8/16/32/64, uint8/16/32/64) contains null values,
parquetreadpromotes it todouble(MATLAB integer types have no missing representation). For int64/uint64, values above 2^53 silently lose precision. Detect by comparingparquetinfoschema againstclass(T.col). Workaround: useparquetDatastorewithReadSize="file"andreadall, which preserves integer types and imports nulls as 0. Without nulls, all integer types round-trip throughparquetreadexactly. -
Excel merged cells → unexpected values: Merged cells silently produce duplicated values or missing data. Use
MergedCellColumnRuleandMergedCellRowRuleto control interpretation:
T = readtable("report.xlsx", ...
"MergedCellColumnRule", "placeleft", "MergedCellRowRule", "placetop");
Mitigation: split complex into real/imag columns before writing to Excel.
% Spreadsheet: check for Inf→65535 and complex→NaN
for i = 1:width(T)
col = T.(T.Properties.VariableNames{i});
if isnumeric(col) && all(isnan(col)) && height(T) > 0
warning('Column "%s" is all-NaN — may contain complex numbers', ...
T.Properties.VariableNames{i});
end
if isnumeric(col) && any(col == 65535)
warning('Column "%s" contains 65535 — may represent Inf from Excel', ...
T.Properties.VariableNames{i});
end
end
% Parquet: detect null-triggered int64/uint64→double promotion (precision loss)
info = parquetinfo("data.parquet");
T = parquetread("data.parquet");
for i = 1:numel(info.VariableNames)
if ismember(info.VariableTypes(i), ["int64","uint64"]) && isa(T.(info.VariableNames(i)), "double")
warning('Column "%s" is %s in schema but double after read (nulls caused promotion)', ...
info.VariableNames(i), info.VariableTypes(i));
end
end
% Workaround: parquetDatastore preserves integer types (nulls become 0)
pds = parquetDatastore("data.parquet", "ReadSize", "file");
T = readall(pds);
When filtering Parquet data, use rowfilter (R2022a+) to push predicates into the read — this avoids loading unwanted rows into memory:
rf = rowfilter(["status", "age"]);
rf = rf.status == "active" & rf.age >= 18;
T = parquetread("users.parquet", "RowFilter", rf);
4. Reading from URLs & REST APIs
Always specify FileType explicitly — MATLAB cannot infer format from API endpoints:
T = readtable("https://example.com/api/v2/export/measurements", "FileType", "text");
For authenticated endpoints, use weboptions:
opts = weboptions("Timeout", 30, ...
"HeaderFields", {"Authorization", "Bearer " + token});
diopts = detectImportOptions(url, "WebOptions", opts);
T = readtable(url, diopts);
5. Readtable/Writetable Patterns
Prefer TextType and TreatAsMissing at read time instead of post-import convertvars/standardizeMissing:
T = readtable("data.csv", "TextType", "string", "TreatAsMissing", "not applicable");
Use readtimetable (R2019a+) for time-series data — it creates a timetable directly with row times, avoiding a separate table2timetable conversion:
TT = readtimetable("sensor_log.csv", "RowTimes", "timestamp");
Read tabular JSON directly with readtable (R2026a+) — for JSON files with tabular structure, use FileType="json" instead of manually parsing with jsondecode:
T = readtable("data.json", "FileType", "json");
Read directly from compressed archives without manual extraction (R2025a+):
T = readtable("data.csv.gz");
T = readtable("archive.zip/folder/data.csv");
Control error handling at import with MissingRule and ImportErrorRule (R2020b+) to fail fast or omit bad rows instead of silently filling with NaN:
T = readtable("data.csv", "MissingRule", "error");
T = readtable("data.csv", "ImportErrorRule", "omitrow");
Use struct2table + writetable to export structs to CSV — do not write manual field-expansion loops:
T = struct2table(data.Results);
writetable(T, "results.csv");
writetable automatically expands vector-valued fields into numbered columns (e.g., MemSet_1, MemSet_2). For JSON/XML output, use writestruct instead (see Topic 9).
Use writecell for cell array export (R2019a+) — do not convert to table first:
writecell(results, "output.csv");
Read tabular XML directly with readtable — for XML files with repeating elements that map to rows, use readtable with RowNodeName and optionally TableNodeName instead of manual DOM parsing:
T = readtable("measurements.xml", ...
"TableNodeName", "measurements", "RowNodeName", "measurement");
6. Text File I/O: readlines/writelines over fopen patterns (R2020b+)
Prefer readlines/writelines for simple text file I/O — avoid fopen/fgetl/fprintf/fclose when reading or writing entire files as string arrays:
% Reading: readlines returns a string array — no file handles needed
lines = readlines("config.txt");
matches = lines(contains(lines, "keyword"));
% Writing: writelines handles string arrays directly
messages = ["Starting process"; "Step 1 complete"; "Done"];
writelines(messages, "output.log");
% Line-by-line processing: read all then operate vectorially
lines = readlines("events.log");
lines = lines(lines ~= ""); % remove empties
parts = split(lines, "|"); % vectorized split
timestamps = parts(:,1);
levels = parts(:,2);
The fopen/fgetl loop pattern is legacy — readlines is simpler, handles empty files gracefully, and enables vectorized string operations on the entire file at once.
7. XML I/O: MAXP over JAXP
Use the MAXP provider (R2024b+) for all XML operations — it is pure MATLAB and does not require Java:
% Reading XML with MAXP
import matlab.io.xml.dom.*
doc = parseFile(Parser, "settings.xml");
params = getElementsByTagName(doc, "parameter");
for i = 1:params.Length
node = params.item(i);
name = getAttribute(node, "name");
value = getAttribute(node, "value");
end
% Writing XML with MAXP
import matlab.io.xml.dom.*
doc = Document("testResults");
root = getDocumentElement(doc);
for i = 1:height(T)
tc = createElement(doc, "testcase");
setAttribute(tc, "name", T.test_name(i));
setAttribute(tc, "status", T.status(i));
appendChild(root, tc);
end
xmlwrite("results.xml", doc);
Do NOT use the legacy JAXP interface (com.mathworks.xml.XMLUtils.createDocument, getElementsByTagName on Java DOM objects, getAttribute with 0-based item() indexing). MAXP is pure MATLAB and does not require Java.
8. JSON with Non-Identifier Keys (R2024b+)
When JSON keys contain spaces, hyphens, or other characters invalid as MATLAB identifiers, use dictionary instead of struct:
d = readdictionary("config.json");
val = d("my-custom-key");
d("new key with spaces") = 42;
writedictionary(d, "config.json");
jsondecode converts such keys to valid identifiers (e.g., my_custom_key), losing the original key names on round-trip. readdictionary/writedictionary preserve keys exactly.
9. Struct I/O: readstruct/writestruct over jsondecode/xmlread (R2020b+ XML, R2023b+ JSON)
Use readstruct/writestruct for struct-based file I/O — do not use fileread+jsondecode or xmlread+DOM traversal when the goal is a struct:
% Reading JSON into a struct
config = readstruct("app_config.json");
host = config.database.host;
% Writing a struct to JSON
writestruct(config, "output_config.json");
% Reading XML into a struct
params = readstruct("device_config.xml");
rate = params.sensor.rate;
% Writing a struct to XML
writestruct(params, "params.xml");
readstruct/writestruct handle JSON and XML in one call, preserving nested field structure. Avoid the legacy patterns: fileread+jsondecode/jsonencode+fopen+fwrite for JSON, or xmlread+getElementsByTagName+getAttribute for XML.
Copyright 2026 The MathWorks, Inc.
Version History
- 2026.08.13 Current 2026-08-16 07:19


