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.
Scanned 9/5/2026
Install to Claude Code
npx -y skills add matlab/matlab-agentic-toolkit --skill matlab-import-export-data --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Matlab Import Export Data?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/matlab-matlab-import-export-data)More formats (shields.io, HTML) on the badges page.
---
name: matlab-import-export-data
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.
license: https://www.mathworks.com/content/dam/mathworks/license/pmrl/license.md
metadata:
author: MathWorks
version: "1.0"
---
# 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`, not `fopen`/`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-solution` skill)
- Database access via ODBC/JDBC — reading, writing, or querying relational databases (use `matlab-use-database` skill)
- SQL-based queries on large CSV/Parquet/JSON files for reduction before analysis (use `matlab-use-duckdb` skill)
- Vehicle data from MDF/MF4/BLF/ASC log files or CAN/LIN bus decoding (use `matlab-import-export-vehicle-data` skill)
- Vehicle network communication setup with CAN/CAN FD/J1939 (use `matlab-use-vehicle-network` skill)
- Tracking data import for sensor fusion workflows (use `matlab-import-tracking-data` skill)
- Medical image data — DICOM, NIfTI, or Analyze formats (use `matlab-read-medical-data` skill)
- Market or financial data feeds (use `matlab-access-datafeed` skill)
- 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** — the `string` type 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 `FileType` when 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 using `detectImportOptions` with `readtable`, pass `FileType` on `detectImportOptions` — `readtable` does not accept `FileType` when an import options object is provided.
- **Handle missing value placeholders at read time** — use `TreatAsMissing` on `readtable` instead of calling `standardizeMissing` after 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 both `Delimiter` and `DecimalSeparator` when 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):
```matlab
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:
```matlab
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`:
```matlab
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**: Both `Inf` and `-Inf` are 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, `parquetread` promotes it to `double` (MATLAB integer types have no missing representation). For int64/uint64, values above 2^53 silently lose precision. Detect by comparing `parquetinfo` schema against `class(T.col)`. Workaround: use `parquetDatastore` with `ReadSize="file"` and `readall`, which preserves integer types and imports nulls as 0. Without nulls, all integer types round-trip through `parquetread` exactly.
- **Excel merged cells → unexpected values**: Merged cells silently produce duplicated values or missing data. Use `MergedCellColumnRule` and `MergedCellRowRule` to control interpretation:
```matlab
T = readtable("report.xlsx", ...
"MergedCellColumnRule", "placeleft", "MergedCellRowRule", "placetop");
```
Mitigation: split complex into real/imag columns before writing to Excel.
```matlab
% 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
```
```matlab
% 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
```
```matlab
% 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:
```matlab
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:
```matlab
T = readtable("https://example.com/api/v2/export/measurements", "FileType", "text");
```
For authenticated endpoints, use `weboptions`:
```matlab
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`:
```matlab
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:
```matlab
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`:
```matlab
T = readtable("data.json", "FileType", "json");
```
**Read directly from compressed archives** without manual extraction (R2025a+):
```matlab
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:
```matlab
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:
```matlab
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:
```matlab
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:
```matlab
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:
```matlab
% Reading: readlines returns a string array — no file handles needed
lines = readlines("config.txt");
matches = lines(contains(lines, "keyword"));
```
```matlab
% Writing: writelines handles string arrays directly
messages = ["Starting process"; "Step 1 complete"; "Done"];
writelines(messages, "output.log");
```
```matlab
% 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:
```matlab
% 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
```
```matlab
% 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`:
```matlab
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:
```matlab
% Reading JSON into a struct
config = readstruct("app_config.json");
host = config.database.host;
```
```matlab
% Writing a struct to JSON
writestruct(config, "output_config.json");
```
```matlab
% Reading XML into a struct
params = readstruct("device_config.xml");
rate = params.sensor.rate;
```
```matlab
% 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.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!