B4J Question [B4X]How to compress and decompress strings using gzip.

byz

Active Member
Licensed User
Base64 + Gzip is a widely adopted method for efficient and text-safe data transmission in web APIs and network protocols. the WEBAPI interface compresses a large json string through gzip and returns it as a base64 encoded string. Therefore it needs to be unzipped. I've done it in vb.net, but b4x always fails.
DecompressString:
Sub DecompressString( base64 As String)
    Dim compress As CompressedStreams
    Dim su As StringUtils
    Dim compressed(), decompressed() As Byte
    compressed = su.DecodeBase64(base64)
    decompressed= compress.DecompressBytes(compressed, "gzip")
    xui.MsgboxAsync(BytesToString(decompressed,0, decompressed.Length, "UTF8"), "")
End Sub
LINE 6 ERROR TIPS: Caused by: java.util.zip.ZipException: Not in GZIP format

It's not clear if it's my method that's wrong or if it's a compatibility issue.
Attached are the test items
================A complete solution===================
This is the correct compression and compression code that supports gzip and zlib compression algorithms. In the second attachment is an OK test item.

 

Attachments

  • TestGZIP.zip
    10.6 KB · Views: 21
  • OK_TestGZIP.zip
    10.3 KB · Views: 16
Last edited:
Solution
DecompressString:
Sub DecompressString( base64 As String)
     ...
    compressed = su.DecodeBase64(base64)
    decompressed= compress.DecompressBytes(compressed, "gzip")
    ...
End Sub
LINE 6 ERROR TIPS: Caused by: java.util.zip.ZipException: Not in GZIP format
B4X:
    compressed = su.DecodeBase64(base64)
    decompressed= compress.DecompressBytes(compressed, "gzip")
This code is wrong, it(compressed) only is bytes which decoded Base64, not GZIP format. you can directly convert the bytes to string as below
B4X:
    Dim bc As ByteConverter
    Log(bc.StringFromBytes(compressed,"utf8"))

byz

Active Member
Licensed User
Your test data, based on what @emexes found
@teddybear already had the solution in #4!

B4X:
    Dim su As StringUtils
    Dim s As String=File.ReadString(File.DirAssets,"base64.txt")
    Dim d2() As Byte
    d2=su.DecodeBase64(s)
    Dim bc As ByteConverter
    Log(bc.StringFromBytes(d2 , "UTF8"))
    '{"appName":"WeatherTracker","version":"2.3.5","features":["real-time updates","5-day forecast","severe weather alerts","custom locations"],"settings":{"temperatureUnit":"Celsius","notificationEnabled":true,"refreshInterval":30,"theme":"dark"},"user":{"id":"WTU-7845-2023","premiumMember":false,"lastActive":"2023-11-15T08:23:17Z"},"systemInfo":{"apiCallsToday":147,"uptime":"36:14:22","memoryUsage":"64%"},"messages":[{"id":1,"text":"Welcome to WeatherTracker!","priority":"low"},{"id":2,"text":"New update available","priority":"medium"}]}
You're right, I'm sorry I didn't notice @teddybear 's reply because it was busy
 
Upvote 0

byz

Active Member
Licensed User
This code is wrong, it(compressed) only is bytes which decoded Base64, not GZIP format. you can directly convert the bytes to string as below
@William Lancee @teddybear @aeric @emexes @JackKirk
An interesting phenomenon, I just used gzip and zlib to compress the string, and this method can be successfully decompressed.

OK CODE:
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")

    'test code
    Dim s As String=File.ReadString(File.DirAssets,"base64.txt")
    Dim s2 As String=(DecompressString(s))
    File.WriteString(    File.DirApp,"1.json",s2)
    Dim s3 As String=(CompressString(s2))
    File.WriteString(    File.DirApp,"1.txt",s3)
End Sub

Sub CompressString(str As String) As String
    Dim bc As ByteConverter
    Dim su As StringUtils
    Dim compress As CompressedStreams
    Dim bytes() As Byte = bc.StringToBytes(str, "UTF8")
    'Dim b() As Byte=compress.CompressBytes(bytes,"zlib")
    Dim b() As Byte=compress.CompressBytes(bytes,"gzip")
    Return su.EncodeBase64(b)
End Sub

Sub DecompressString( base64 As String) As String
    Dim su As StringUtils
    Dim d2() As Byte
    d2=su.DecodeBase64(base64)
    Dim bc As ByteConverter
    Return bc.StringFromBytes(d2 , "UTF8")
End Sub

GZIP/ZLIB testing tools https://codebeautify.org/gzip-decompress-online
 
Upvote 0

aeric

Expert
Licensed User
Longtime User
I think this is better to demonstrate that su.DecodeBase64(base64) is doing the decompressing.
The commented code shows it is not needed.

B4X:
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
    Dim json As String = File.ReadString(File.DirAssets, "json.txt")
    CompressString(json)
End Sub

Private Sub Button1_Click
    DecompressString
End Sub

Sub CompressString (s As String)
    Dim compress As CompressedStreams
    Dim compressed() As Byte = compress.CompressBytes(s.GetBytes("UTF8"), "gzip")
    Dim base64 As String = su.EncodeBase64(compressed)
    File.WriteString(File.DirApp, "base64.txt", base64)
End Sub

Sub DecompressString
    Dim base64 As String = File.ReadString(File.DirApp, "base64.txt")
    Dim compressed() As Byte = su.DecodeBase64(base64)
    'Dim decompressed() As Byte = compress.DecompressBytes(compressed, "gzip")
    'Dim s As String = BytesToString(decompressed, 0, decompressed.Length, "UTF8")
    Dim s As String = BytesToString(compressed, 0, compressed.Length, "UTF8")
    Log(s)
End Sub
 
  • Like
Reactions: byz
Upvote 0
Top