Task 400: .MLX File Format
Task 400: .MLX File Format
File Format Specifications for the .MLX File Format
The .MLX file format is used by MATLAB for Live Scripts and Functions. It is a binary format based on the Open Packaging Conventions (OPC) standard, which extends the ZIP file format. Code and formatted content are stored in XML using the Office Open XML (ECMA-376) format, with output stored separately. The file can be opened as a ZIP archive to access its internal structure, which typically includes folders like matlab
, metadata
, and _rels
, along with files such as document.xml
(code and rich text), output.xml
(serialized outputs), [Content_Types].xml
, and potential media files. The underlying ZIP format specifications are defined in the PKWARE APPNOTE.TXT document, detailing headers, compression, and archive structure.
- List of all the properties of this file format intrinsic to its file system:
The properties are the attributes associated with each entry (file or folder) in the ZIP archive structure of the .MLX file, as defined in the ZIP format. These include:
- File name
- Version needed to extract
- General purpose bit flag
- Compression method
- Last modification time
- Last modification date
- CRC-32 of uncompressed data
- Compressed size
- Uncompressed size
- File name length
- Extra field length
- File comment length
- Disk number start
- Internal file attributes
- External file attributes
- Relative offset of local header
- Extra field data (if present, may include Zip64 extensions for large files)
- File comment (if present)
These properties are derived from the local file headers, central directory headers, and extra fields in the ZIP format.
- Two direct download links for files of format .MLX:
- https://raw.githubusercontent.com/mathworks/matlab-mobile-fitness-tracker/master/ExampleModel.mlx
- https://raw.githubusercontent.com/MattTearle/Getting-Started-with-MATLAB/master/solarproduction_analysis.mlx
- Ghost blog embedded HTML JavaScript for drag and drop .MLX file to dump properties:
- Python class for .MLX file handling:
import zipfile
import datetime
class MLXHandler:
def __init__(self, filename):
self.filename = filename
self.zipf = None
def open(self):
self.zipf = zipfile.ZipFile(self.filename, 'r')
def read_and_print_properties(self):
if not self.zipf:
self.open()
for info in self.zipf.infolist():
print(f"File name: {info.filename}")
print(f"Compression method: {zipfile.compressorname(info.compress_type)} ({info.compress_type})")
dt = datetime.datetime(*info.date_time)
print(f"Last modification date/time: {dt}")
print(f"CRC-32: {info.CRC}")
print(f"Compressed size: {info.compress_size}")
print(f"Uncompressed size: {info.file_size}")
print(f"Comment: {info.comment.decode() if info.comment else 'None'}")
print(f"Internal attributes: {info.internal_attr}")
print(f"External attributes: {info.external_attr}")
print(f"File mode: {oct(info.external_attr >> 16)}") # Example for permissions
print("\n")
def write_new_mlx(self, new_filename, files_to_add):
# Create a new .mlx (ZIP) file with added files
with zipfile.ZipFile(new_filename, 'w', zipfile.ZIP_DEFLATED) as new_zip:
for file_path in files_to_add:
new_zip.write(file_path)
print(f"New .MLX file written: {new_filename}")
def close(self):
if self.zipf:
self.zipf.close()
# Example usage:
# handler = MLXHandler('example.mlx')
# handler.read_and_print_properties()
# handler.write_new_mlx('new.mlx', ['file1.txt', 'file2.xml'])
# handler.close()
- Java class for .MLX file handling:
import java.io.*;
import java.util.zip.*;
import java.util.Enumeration;
public class MLXHandler {
private String filename;
private ZipFile zipf;
public MLXHandler(String filename) {
this.filename = filename;
}
public void open() throws IOException {
zipf = new ZipFile(filename);
}
public void readAndPrintProperties() throws IOException {
if (zipf == null) {
open();
}
Enumeration<? extends ZipEntry> entries = zipf.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
System.out.println("File name: " + entry.getName());
System.out.println("Compression method: " + entry.getMethod());
System.out.println("Last modification time: " + entry.getTime());
System.out.println("CRC-32: " + entry.getCrc());
System.out.println("Compressed size: " + entry.getCompressedSize());
System.out.println("Uncompressed size: " + entry.getSize());
System.out.println("Comment: " + (entry.getComment() != null ? entry.getComment() : "None"));
System.out.println("Extra: " + (entry.getExtra() != null ? entry.getExtra().length + " bytes" : "None"));
System.out.println("\n");
}
}
public void writeNewMlx(String newFilename, String[] filesToAdd) throws IOException {
try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(newFilename))) {
for (String filePath : filesToAdd) {
File file = new File(filePath);
zos.putNextEntry(new ZipEntry(file.getName()));
try (FileInputStream fis = new FileInputStream(file)) {
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
}
zos.closeEntry();
}
}
System.out.println("New .MLX file written: " + newFilename);
}
public void close() throws IOException {
if (zipf != null) {
zipf.close();
}
}
// Example usage:
// public static void main(String[] args) throws IOException {
// MLXHandler handler = new MLXHandler("example.mlx");
// handler.readAndPrintProperties();
// handler.writeNewMlx("new.mlx", new String[]{"file1.txt", "file2.xml"});
// handler.close();
// }
}
- JavaScript class for .MLX file handling (requires Node.js with 'adm-zip' module for ZIP handling):
const AdmZip = require('adm-zip'); // npm install adm-zip
class MLXHandler {
constructor(filename) {
this.filename = filename;
this.zip = null;
}
open() {
this.zip = new AdmZip(this.filename);
}
readAndPrintProperties() {
if (!this.zip) {
this.open();
}
const entries = this.zip.getEntries();
entries.forEach((entry) => {
console.log(`File name: ${entry.entryName}`);
console.log(`Compression method: ${entry.header.method}`);
console.log(`Last modification date/time: ${entry.header.time}`);
console.log(`CRC-32: ${entry.header.crc}`);
console.log(`Compressed size: ${entry.header.compressedSize}`);
console.log(`Uncompressed size: ${entry.header.size}`);
console.log(`Comment: ${entry.comment || 'None'}`);
console.log(`Internal attributes: ${entry.header.attr & 0xFFFF}`);
console.log(`External attributes: ${entry.header.attr >>> 16}`);
console.log('\n');
});
}
writeNewMlx(newFilename, filesToAdd) {
const newZip = new AdmZip();
filesToAdd.forEach((filePath) => {
newZip.addLocalFile(filePath);
});
newZip.writeZip(newFilename);
console.log(`New .MLX file written: ${newFilename}`);
}
}
// Example usage:
// const handler = new MLXHandler('example.mlx');
// handler.readAndPrintProperties();
// handler.writeNewMlx('new.mlx', ['file1.txt', 'file2.xml']);
- C class (using C++ for class support, assumes zlib or minizip library for ZIP handling; here using pseudo-code with stdio for simplicity, full ZIP parsing would require a library like minizip):
#include <iostream>
#include <string>
#include <vector>
#include <zip.h> // Requires libzip or similar; install via package manager
class MLXHandler {
private:
std::string filename;
zip_t* zipf;
public:
MLXHandler(const std::string& fn) : filename(fn), zipf(nullptr) {}
~MLXHandler() {
close();
}
bool open() {
int err = 0;
zipf = zip_open(filename.c_str(), ZIP_RDONLY, &err);
return zipf != nullptr;
}
void readAndPrintProperties() {
if (!zipf && !open()) {
std::cerr << "Failed to open file." << std::endl;
return;
}
zip_int64_t num_entries = zip_get_num_entries(zipf, 0);
for (zip_int64_t i = 0; i < num_entries; ++i) {
zip_stat_t sb;
if (zip_stat_index(zipf, i, 0, &sb) == 0) {
std::cout << "File name: " << sb.name << std::endl;
std::cout << "Compression method: " << sb.comp_method << std::endl;
std::cout << "Last modification time: " << sb.mtime << std::endl;
std::cout << "CRC-32: " << sb.crc << std::endl;
std::cout << "Compressed size: " << sb.comp_size << std::endl;
std::cout << "Uncompressed size: " << sb.size << std::endl;
std::cout << "External attributes: " << sb.external_attr << std::endl;
std::cout << "\n";
}
}
}
void writeNewMlx(const std::string& newFilename, const std::vector<std::string>& filesToAdd) {
zip_t* newZip = zip_open(newFilename.c_str(), ZIP_CREATE | ZIP_TRUNCATE, nullptr);
if (!newZip) {
std::cerr << "Failed to create new file." << std::endl;
return;
}
for (const auto& filePath : filesToAdd) {
zip_source_t* src = zip_source_file(newZip, filePath.c_str(), 0, 0);
if (src) {
zip_file_add(newZip, filePath.c_str(), src, ZIP_FL_ENC_UTF_8);
}
}
zip_close(newZip);
std::cout << "New .MLX file written: " << newFilename << std::endl;
}
void close() {
if (zipf) {
zip_close(zipf);
zipf = nullptr;
}
}
};
// Example usage:
// int main() {
// MLXHandler handler("example.mlx");
// handler.readAndPrintProperties();
// handler.writeNewMlx("new.mlx", {"file1.txt", "file2.xml"});
// return 0;
// }