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.

  1. 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.

  1. Two direct download links for files of format .MLX:
  1. Ghost blog embedded HTML JavaScript for drag and drop .MLX file to dump properties:
MLX File Properties Dumper
Drag and drop a .MLX file here
  1. 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()
  1. 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();
    // }
}
  1. 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']);
  1. 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;
// }