Do you know how to read ZIP file contents (e.g. list files in zip, compression ratio of files ...) in Google Drive by using Apps Script? Thanks.
I can't find Apps Script API for my purpose. I wrote simple codes to read file name and its compress ratio in zip file. (It works with file size < 50MB because of Blob.getBytes() limitation).
Referred this document for ZIP file format.
const ZIP_FILE_ID = "... Add your file ID here ...";
const OFFSET_TO_COMPRESS_SIZE = 18;
const OFFSET_TO_UNCOMPRESS_SIZE = 22;
const OFFSET_TO_FILENAME_LEN = 26;
const OFFSET_TO_EXTRA_LEN = 28;
const OFFSET_TO_FILENAME = 30;
function checkEntrySignature(bytesData, start) {
if (bytesData[start] != 0x50) return false;
if (bytesData[start + 1] != 0x4B) return false;
if (bytesData[start + 2] != 0x03) return false;
if (bytesData[start + 3] != 0x04) return false;
return true;
}
function read4bytesAsNumber(bytesData, start) {
let numArray = Uint8Array.from(bytesData.slice(
start, start + 4));
var number = numArray[0];
number += numArray[1] << 8;
number += numArray[2] << 16;
number += numArray[3] << 24;
return number;
}
function read2bytesAsNumber(bytesData, start) {
let numArray = Uint8Array.from(bytesData.slice(
start, start + 2));
var number = numArray[0];
number += numArray[1] << 8;
return number;
}
function readBytesAsString(bytesData, start, length) {
let slicedBytes = bytesData.slice(start, start + length);
return String.fromCharCode.apply(null, slicedBytes);
}
function myFunction() {
let zipFile = DriveApp.getFileById(ZIP_FILE_ID);
let zipBytes = zipFile.getBlob().getBytes();
var entryIndex = 0;
while(true) {
isZipEntry = checkEntrySignature(zipBytes, entryIndex)
if (isZipEntry == false) {
break;
}
compressedSize = read4bytesAsNumber(zipBytes,
entryIndex + OFFSET_TO_COMPRESS_SIZE);
uncompressedSize = read4bytesAsNumber(zipBytes,
entryIndex + OFFSET_TO_UNCOMPRESS_SIZE);
compressRatio = 1 - compressedSize / uncompressedSize;
fileNameLength = read2bytesAsNumber(zipBytes,
entryIndex + OFFSET_TO_FILENAME_LEN);
extraFieldLength = read2bytesAsNumber(zipBytes,
entryIndex + OFFSET_TO_EXTRA_LEN);
fileName = readBytesAsString(zipBytes,
entryIndex + OFFSET_TO_FILENAME, fileNameLength);
Logger.log(fileName + ", compressed:" + compressRatio);
// calculate index to next entry
entryIndex = entryIndex + OFFSET_TO_FILENAME +
compressedSize + fileNameLength + extraFieldLength;
}
}