Распаковать строку в java из сжатой строки в С#

Я искал правильное решение для распаковки строки в java, исходящей из кода С#. Я пробовал себя с множеством методов в java, таких как (gzip, inflatter и т. д.), но не получил решение. Я получил некоторую ошибку при попытке распаковать строку в java из сжатой строки из кода С#.

Мой код С# для сжатия строки:

public static string CompressString(string text)
{

   byte[] byteArray = Encoding.GetEncoding(1252).GetBytes(text);//  Encoding.ASCII.GetBytes(text);

   using (var ms = new MemoryStream())
   {
    // Compress the text
    using (var ds = new DeflateStream(ms, CompressionMode.Compress))
    {
     ds.Write(byteArray, 0, byteArray.Length);
    }

    return Convert.ToBase64String(ms.ToArray());
   }
  }

И распакуйте строку в java, используя

private static void compressAndDecompress(){
    try {
        // Encode a String into bytes
        String string = "xxxxxxSAMPLECOMPRESSEDSTRINGxxxxxxxxxx";
        // // Compress the bytes
        byte[] decoded = Base64.decodeBase64(string.getBytes());
        byte[] output = new byte[4096];
        // Decompress the bytes
        Inflater decompresser = new Inflater();
        decompresser.setInput(decoded);

        int resultLength = decompresser.inflate(output);
        decompresser.end();

        // Decode the bytes into a String
        String outputString = new String(output, 0, resultLength, "UTF-8");

        System.out.println(outputString);
    } catch(java.io.UnsupportedEncodingException ex) {    
        ex.printStackTrace();
    } catch (java.util.zip.DataFormatException ex) {
        ex.printStackTrace();
    }
}

Я получаю это исключение при запуске приведенного выше кода:

java.util.zip.DataFormatException: incorrect header check

Пожалуйста, дайте мне пример кода в java для распаковки строки java. Спасибо


person Muthu kader    schedule 04.09.2013    source источник
comment
Пожалуйста, покажите нам сообщение об ошибке, которое вы получили.   -  person BetaRide    schedule 04.09.2013


Ответы (3)


Мой код С# для сжатия:

 private string Compress(string text)
    {
        byte[] buffer = Encoding.UTF8.GetBytes(text);
        MemoryStream ms = new MemoryStream();
        using (GZipStream zip = new GZipStream(ms, CompressionMode.Compress, true))
        {
            zip.Write(buffer, 0, buffer.Length);
        }

        ms.Position = 0;
        MemoryStream outStream = new MemoryStream();

        byte[] compressed = new byte[ms.Length];
        ms.Read(compressed, 0, compressed.Length);

        byte[] gzBuffer = new byte[compressed.Length + 4];
        System.Buffer.BlockCopy(compressed, 0, gzBuffer, 4, compressed.Length);
        System.Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gzBuffer, 0, 4);
        return Convert.ToBase64String(gzBuffer);
    }

Код Java для распаковки текста

private String Decompress(String compressedText)
{

    byte[] compressed = compressedText.getBytes("UTF8");
    compressed = org.apache.commons.codec.binary.Base64.decodeBase64(compressed);
    byte[] buffer=new byte[compressed.length-4];
    buffer = copyForDecompression(compressed,buffer, 4, 0);
    final int BUFFER_SIZE = 32;
    ByteArrayInputStream is = new ByteArrayInputStream(buffer);
    GZIPInputStream gis = new GZIPInputStream(is, BUFFER_SIZE);
    StringBuilder string = new StringBuilder();
    byte[] data = new byte[BUFFER_SIZE];
    int bytesRead;
    while ((bytesRead = gis.read(data)) != -1) 
    {
        string.append(new String(data, 0, bytesRead));
    }
    gis.close();
    is.close();
    return string.toString();
}
private  byte[] copyForDecompression(byte[] b1,byte[] b2,int srcoffset,int dstoffset)
{       
    for(int i=0;i<b2.length && i<b1.length;i++)
    {
        b2[i]=b1[i+4];
    }
    return b2;
}

Этот код отлично работает для меня.

person dbw    schedule 04.09.2013
comment
Спасибо @Deepak Bhatia, я пытаюсь распаковать ваш код Java, я не получил никаких исключений, но он не дал результата, он возвращается после этой строки кода GZIPInputStream gis = new GZIPInputStream(is, BUFFER_SIZE);. Я не У меня нет разрешения на изменение метода сжатия в С#. Так что я должен, как и в С#. Но в java декомпрессия не работает. Пожалуйста, помогите мне - person Muthu kader; 04.09.2013
comment
Извините, я не распечатал исключение. Теперь он выдает java.util.zip.ZipException: не в формате GZIP - person Muthu kader; 04.09.2013
comment
согласно сообщению stackoverflow.com/questions/8490718/, stackoverflow.com/questions/6522778/ дефлятор по умолчанию, используемый в C#, не имеет эквивалента java, поэтому пользователи предпочитают Gzip, Ziplib или некоторые другие методы zip. Но если вы найдете его, опубликуйте ответ, так как он поможет и другим пользователям. - person dbw; 04.09.2013
comment
У меня похожая проблема - java.util.zip.ZipException: не в формате GZIP. Удалось ли вам найти какое-либо решение для этого ?? - person Ashu; 01.04.2015
comment
@Ashu Я долго работал над этим, может быть, вы получите тот же код, что и выше, и посмотрите, работает ли он...... - person dbw; 02.04.2015
comment
Наконец-то я использовал исполняемый файл 7zip для распаковки файлов. Это лучше всего подходит для моего варианта использования, потому что я не контролирую код .Net и не могу его изменить. На случай, если кто-то захочет использовать то же самое, я публикую фрагмент здесь.................................. ................................................. ...................... Runtime.getRuntime().exec(new String[]{‹‹Путь к exe››, x, ‹‹путь к сжатому files››}, null, new File(‹‹Путь к распакованным файлам››)); - person Ashu; 03.04.2015
comment
Код работал отлично! Спасибо, вы экономите мне много времени. - person user3430360; 09.05.2016

Была точно такая же проблема. Можно решить через

byte[] compressed = Base64Utils.decodeFromString("mybase64encodedandwithc#zippedcrap");
Inflater decompresser = new Inflater(true);
decompresser.setInput(compressed);
byte[] result = new byte[4096];
decompresser.inflate(result);
decompresser.end();
System.out.printf(new String(result));

Магия происходит с параметром boolen при создании экземпляра Inflator.

БВ Хьюберт

person Hubert Ströbitzer    schedule 30.09.2016

Для любимых гуглеров,

Как упоминал @dbw,

согласно сообщению Как распаковать сжатый поток с java.util.zip.Deflater в .NET?, эквивалент java.util.zip.deflater в C# дефлятор по умолчанию, используемый в C#, не имеет никакого эквивалента java, поэтому пользователи предпочитают Gzip, Ziplib или некоторые другие методы zip.

относительно простым методом будет использование GZip. А для принятого ответа одна проблема заключается в том, что в этом методе вы должны самостоятельно добавлять размер данных к сжатой строке, и, что более важно, как по моему собственному опыту в нашем производственном приложении, оно глючит, когда строка достигает ~ 2000 символов!

ошибка в System.io.Compression.GZipStream

в любом случае, используя SharpZipLib в С#, проблема исчезнет, ​​и все будет так же просто, как следующие фрагменты:

ДЖАВА:

import android.util.Base64;

import com.google.android.gms.common.util.IOUtils;

import org.jetbrains.annotations.Nullable;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

public class CompressionHelper {

    @Nullable
    public static String compress(@Nullable String data) {
        if(data == null || data.length() == 0)
            return null;
        try {

            // Create an output stream, and a gzip stream to wrap over.
            ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length());
            GZIPOutputStream gzip = new GZIPOutputStream(bos);

            // Compress the input string
            gzip.write(data.getBytes());
            gzip.close();
            byte[] compressed;
            // Convert to base64
            compressed = Base64.encode(bos.toByteArray(),Base64.NO_WRAP);
            bos.close();
            // return the newly created string
            return new String(compressed);
        } catch(IOException e) {

            return null;
        }
    }


    @Nullable
    public static String decompress(@Nullable String compressedText) {
        if(compressedText == null || compressedText.length() == 0)
            return null;
        try {
            // get the bytes for the compressed string
            byte[] compressed = compressedText.getBytes("UTF-8");

            // convert the bytes from base64 to normal string
            compressed = Base64.decode(compressed, Base64.NO_WRAP);

            ByteArrayInputStream bis = new ByteArrayInputStream(compressed);
            GZIPInputStream gis = new GZIPInputStream(bis);
            byte[] bytes = IOUtils.toByteArray(gis);
            return new String(bytes, "UTF-8");

        }catch (IOException e){
            e.printStackTrace();
        }

        return null;
    }

}

и С#:

using ICSharpCode.SharpZipLib.GZip; //PM> Install-Package SharpZipLib
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GeneralTools
{
    public static class CompressionTools
    {
        public static string CompressString(string text)
        {
            if (string.IsNullOrEmpty(text))
                return null;
            byte[] buffer = Encoding.UTF8.GetBytes(text);
            using (var compressedStream = new MemoryStream())
            {
                GZip.Compress(new MemoryStream(buffer), compressedStream, false);
                byte[] compressedData = compressedStream.ToArray();
                return Convert.ToBase64String(compressedData);
            }
        }


        public static string DecompressString(string compressedText)
        {
            if (string.IsNullOrEmpty(compressedText))
                return null;
            byte[] gZipBuffer = Convert.FromBase64String(compressedText);
            using (var memoryStream = new MemoryStream())
            {
                using (var compressedStream = new MemoryStream(gZipBuffer))
                {
                    var decompressedStream = new MemoryStream();
                    GZip.Decompress(compressedStream, decompressedStream, false);

                    return Encoding.UTF8.GetString(decompressedStream.ToArray()).Trim();
                }
            }
        }


    }

}

вы также можете найти коды здесь

person Muhammad Naderi    schedule 20.04.2019