Home > Back-end >  get uncompressed size of zip
get uncompressed size of zip

Time:06-09

I am trying to automate Oracle Database patching on Windows and one of the issues I have is with verifying that enough space is available on server(s) in order to copy and extract the patches.

What I need is a quick way to get the uncompressed size of a zip archive(Oracle Patches) in order to make sure there is enough space available for the script to copy and extract the patches.

I started from this thread:

7z get total size of uncompress contents?

Which seemed promising as per samson7point1's answer:

'C:\Program Files\7-Zip\7z.exe' l '.\folder-with-zips\*.zip' | select-string -pattern "1 files" | Foreach {$size=[long]"$(($_ -split '\s ',4)[2])";$total =$size;"$([math]::Round($total/1024/1024/1024,2))"   " GB"}

But the above does not seem to work for me, probably I am doing something wrong.

Starting from that thread I tried to develop something in powershell which would sum the "Size" column of 7z and I got to this powershell script:

function getsizeofzip
{
$stopwatch = [System.Diagnostics.Stopwatch]::startNew()
$username = "yayo"
$password = ConvertTo-SecureString "yayo" -AsPlainText -Force
$Credentials = New-Object System.Management.Automation.PSCredential ($username, $password)
$masina = "yayo"
Write-Host Gathering list of zip files to calculate extract size -ForeGroundColor yellow
$alabala = Invoke-Command -ScriptBlock {Invoke-Expression "&'C:\Program Files\7-Zip\7z.exe' l -ba -slt Z:\Oracle\OraDB19c3\*.zip"} -Computer $masina -Credential $Credentials | Select-String "Size = "
Write-Host Saving output to file -ForegroundColor Yellow
$alabala >> vvv.txt
$total = 0
Write-Host Calculating extract size -ForeGroundColor yellow
for ( $index = 0; $index -lt $alabala.count; $index = $index   2)
{
$temp = $alabala | Select-Object -Index $index
$size = $temp -replace "Size = " -replace ""
#$size
$total  =  ($size -as [int])
#Write-Host Current total $total
}
$stopWatch.Elapsed.TotalMinutes
$stopWatch.Stop()
Write-Host Totalul este ($total/1024/1024/1024)GB
}

Which outputs:

Gathering list of zip files to calculate extract size 

Saving output to file Calculating extract size

21.5341170483333 

Totalul este 4.49708485417068 GB 

As you can see the following 7z command is executed:

'C:\Program Files\7-Zip\7z.exe' l -ba -slt Z:\Oracle\OraDB19c3\*.zip"

-ba -slt parameters are for sorting command output, to get rid of headers atleast and I get the following output:

Path = 33808367\files\sqlpatch\33808367
Folder =  
Size = 0
Packed Size = 0
Modified = 2022-05-02 11:51:38
Created = 
Accessed = 
Attributes = D drwxr-xr-x
Encrypted = -
Comment = 
CRC = 
Method = Store
Characteristics = UT 0x7875
Host OS = Unix
Version = 10
Volume Index = 0
Offset = 251558554

Path = 33808367\files\sqlpatch\33808367\24758240
Folder =  
Size = 0
Packed Size = 0
Modified = 2022-05-01 13:25:40
Created = 
Accessed = 
Attributes = D drwxr-xr-x
Encrypted = -
Comment = 
CRC = 
Method = Store
Characteristics = UT 0x7875
Host OS = Unix
Version = 10
Volume Index = 0
Offset = 251558645

Path = 33808367\files\sqlpatch\33808367\24758240\rollback_files
Folder =  
Size = 0
Packed Size = 0
Modified = 2022-05-01 13:25:40
Created = 
Accessed = 
Attributes = D drwxr-xr-x
Encrypted = -
Comment = 
CRC = 
Method = Store
Characteristics = UT 0x7875
Host OS = Unix
Version = 10
Volume Index = 0
Offset = 251558745

Path = 33808367\files\sqlpatch\33808367\24758240\rollback_files\19.1.0.0.0
Folder =  
Size = 0
Packed Size = 0
Modified = 2022-05-01 13:25:40
Created = 
Accessed = 
Attributes = D drwxr-xr-x
Encrypted = -
Comment = 
CRC = 
Method = Store
Characteristics = UT 0x7875
Host OS = Unix
Version = 10
Volume Index = 0
Offset = 251558860

Path = 33808367\files\sqlpatch\33808367\24758240\rollback_files\19.1.0.0.0\javavm
Folder =  
Size = 0
Packed Size = 0
Modified = 2022-05-01 13:25:40
Created = 
Accessed = 
Attributes = D drwxr-xr-x
Encrypted = -
Comment = 
CRC = 
Method = Store
Characteristics = UT 0x7875
Host OS = Unix
Version = 10
Volume Index = 0
Offset = 251558986

....
...

As i didn't know how to format the table (i tried a bit) in order to only select the Size column ... I piped that output to Select-String "Size =" which now outputs:

Size = 0
Packed Size = 0
Size = 86652
Packed Size = 13750
Size = 0
Packed Size = 0
Size = 0
Packed Size = 0
Size = 0
Packed Size = 0
Size = 92973512
Packed Size = 12818027
Size = 0
Packed Size = 0
Size = 0
Packed Size = 0
Size = 205157781
Packed Size = 58369063
Size = 209589951
Packed Size = 59788028
Size = 0
Packed Size = 0
Size = 0
Packed Size = 0
Size = 0
Packed Size = 0
Size = 205157781

Now I loop through this ( index 2) to get all values and sum them up. This works but ...

Problem with above script is that for a Oracle patch that has a compressed size of 1.6g and 10s of thousands of files it takes ... 23 minutes ... this is somehow too much and as I am not very good with powershell or optimization in general I am looking for some advices.

Can you help point me in the right direction with:

-Is there a faster way to sort the 7z output with powershell? I tried formatting the string output to a table for easier parsing but I did not succeed, Format-Table (I understand this is for output only) or any similar cmdlets are of no help, table is not sortable by default ... -Is there maybe another native utility for Windows that can show the uncompressed size of a zip file?

CodePudding user response:

Try this, it removes the requirement to write and then parse a text file which is probably where most of the time is being spent. This solution streams the output of the 7zip command to a foreach object. Within the foreach loop we look for lines containing "Size = " and then process any matches.

#Configure variable to hold our result
$size = 0

#Call 7zip and stream the output to a foreach object
&'C:\Program Files\7-Zip\7z.exe' l -bso0 -slt "C:\Temp\oracle.zip" | %{

    #Match the string "Size = anything" in 2 capture groups one of which will contain the filesize
    if($_ -match "(^Size\s=\s)(\d $)"){
        
        #Add the uncompressed filesize to our result variable
        $size  = $matches[2] -as [int]
    }
}

#Show the result in MB
$size / 1MB
  • Related