此函数下载 zip 文件并解压,并将解压后的图像文件保存到 React Native Expo 应用程序的 expo 文件系统中。它确实成功下载文件、解压缩并保存图像。问题是,当我显示图像时,它们显得损坏和扭曲。我怀疑此功能有问题导致此问题,我将不胜感激任何建议。
const readZipFile = async (uri: string, privateAssetsDirectory: string) => {
try {
const response = await axios.get(uri, { responseType: 'arraybuffer' });
const zipBuffer = response.data;
// Create a new JSZip instance and load the zip buffer
const zip = await JSZip.loadAsync(zipBuffer);
// Get an array of file keys
const fileKeys = Object.keys(zip.files);
// Iterate over each file key in the zip archive
for (const filename of fileKeys) {
const file = zip.files[filename];
if (!file.dir && !isSystemFile(filename)) { // Exclude directories
// Extract the file contents as Uint8Array
const content = await file.async('uint8array');
// Convert Uint8Array to Base64 string
let base64Content = '';
for (let i = 0; i < content.length; i += 1024) {
const chunk = content.subarray(i, i + 1024);
base64Content += btoa(String.fromCharCode.apply(null, chunk));
}
// Save the file to the directory where the zip file is located
const filePath = privateAssetsDirectory + filename;
await FileSystem.writeAsStringAsync(
filePath,
base64Content,
{ encoding: FileSystem.EncodingType.Base64 }
);
//console.log('File:', filename, ', Size:', content.length);
//console.log('Saved at:', filePath);
}
}
} catch (error) {
console.error('Error reading zip file:', error);
throw error;
}
};
我期望图像能够显示,但它们扭曲了。您只能看到图像应包含的部分内容,部分图像只是灰色的。
我使用
react native
和 expo
来完成这个工作。通过这个功能,我下载并解压了多张图片。然后我用 <Image>
显示它们,它们没有损坏或扭曲,基本上一切正常。希望有帮助!
我用
fflate
代替jszip
,没有尝试过jszip
虽然我已经尝试过react-native-zip-archive
而且它甚至没有为我构建。
import * as FileSystem from "expo-file-system";
import { unzipSync } from "fflate";
import { Buffer } from "buffer";
const downloadAndUzipFiles = async (
url: string,
targetZipFilePath: string,
targetUnzipPath: string
): Promise<string[]> => {
console.log("Downloading from", url);
const downloadResult = await FileSystem.downloadAsync(url, targetZipFilePath);
console.log("Downloaded to", downloadResult.uri);
const zipFileBase64 = await FileSystem.readAsStringAsync(downloadResult.uri, {
encoding: FileSystem.EncodingType.Base64,
});
// Convert base64 string to Uint8Array for fflate to process
const zipArray = new Uint8Array(Buffer.from(zipFileBase64, "base64"));
// Unzip the file using fflate
const unzippedFiles = unzipSync(zipArray); // unzippedFiles is an object with file names as keys and Uint8Array as values
console.log("Files unzipped:", Object.keys(unzippedFiles));
// Ensure the unzipped folder exists
const folderInfo = await FileSystem.getInfoAsync(targetUnzipPath);
if (!folderInfo.exists) {
console.log("directory does not exist, creating...", targetUnzipPath);
await FileSystem.makeDirectoryAsync(targetUnzipPath, {
intermediates: true,
});
} else {
console.log("directory exists, resetting...", targetUnzipPath);
await FileSystem.deleteAsync(targetUnzipPath, { idempotent: true });
await FileSystem.makeDirectoryAsync(targetUnzipPath, {
intermediates: true,
});
}
// Save each unzipped file to the unzipped folder
const savedFiles = [];
for (const [fileName, fileData] of Object.entries(unzippedFiles)) {
const filePath = targetUnzipPath + fileName;
const base64Content = Buffer.from(fileData).toString("base64");
// Convert the file content (Uint8Array) to string (for text files) or directly save binary data (for images, etc.)
await FileSystem.writeAsStringAsync(filePath, base64Content, {
encoding: FileSystem.EncodingType.Base64,
});
savedFiles.push(filePath);
console.log(`Saved ${fileName} to ${filePath}`);
}
return savedFiles;
};