如何从 MATLAB 中的 zip 存档中提取单个文件?

How to extract a single file from a zip archive in MATLAB?

单个文件unzip

MATLAB中的unzip()函数只提供了输入zip文件位置和输出目录位置的功能。有没有办法从 zip 存档中只提取一个文件而不是所有文件?

如果特定文件已知并且它是唯一需要的文件,这将减少提取文件的时间。

MATLAB 的unzip

这对于 standard MATLAB function 是不可能的,但是...让我们破解该函数以使其执行所需的操作!

MATLAB 的 unzip 单文件破解

使用来自 MATLAB 的 unzip()extractArchive() 的代码(从 unzip() 调用),可以创建自定义函数以仅从 zip 存档中提取单个文件。

function [] = extractFile(zipFilename, outputDir, outputFile)
% extractFile

% Obtain the entry's output names
outputName = fullfile(outputDir, outputFile);

% Create a stream copier to copy files.
streamCopier = ...
    com.mathworks.mlwidgets.io.InterruptibleStreamCopier.getInterruptibleStreamCopier;

% Create a Java zipFile object and obtain the entries.
try
    % Create a Java file of the Zip filename.
    zipJavaFile = java.io.File(zipFilename);

    % Create a java ZipFile and validate it.
    zipFile = org.apache.tools.zip.ZipFile(zipJavaFile);

    % Get entry
    entry = zipFile.getEntry(outputFile);

catch exception
    if ~isempty(zipFile)
        zipFile.close;
    end
    delete(cleanUpUrl);
    error(message('MATLAB:unzip:unvalidZipFile', zipFilename));
end

% Create the Java File output object using the entry's name.
file = java.io.File(outputName);

% If the parent directory of the entry name does not exist, then create it.
parentDir = char(file.getParent.toString);
if ~exist(parentDir, 'dir')
    mkdir(parentDir)
end

% Create an output stream
try
    fileOutputStream = java.io.FileOutputStream(file);
catch exception
    overwriteExistingFile = file.isFile && ~file.canWrite;
    if overwriteExistingFile
        warning(message('MATLAB:extractArchive:UnableToOverwrite', outputName));
    else
        warning(message('MATLAB:extractArchive:UnableToCreate', outputName));
    end
    return
end

% Create an input stream from the API
fileInputStream = zipFile.getInputStream(entry);

% Extract the entry via the output stream.
streamCopier.copyStream(fileInputStream, fileOutputStream);

% Close the output stream.
fileOutputStream.close;

end