0

私は C# が初めてで、単純な Web サービスを作成しています。zip ファイルを取得し、ファイル システムで解凍します。C# コードでは次のとおりです。

[WebMethod]
public String SetZip(string device_id, string file)
{
    if (device_id == null || device_id.Length == 0)
    {
        return "10;no auth data";
    }

    StringBuilder output = new StringBuilder();

    if (direcory == null)
    {
        return output.ToString();
    }

    string dirname = "c:\\temp\\" + direcory + "\\";

    if (!System.IO.Directory.Exists(dirname))
    {
        System.IO.Directory.CreateDirectory(dirname);
    }

    string filename = dirname + "file1.txt";

    string text = UnZipStr(Convert.FromBase64String(file));

    File.WriteAllText(filename, text);

    output.AppendLine("0;done");

    return output.ToString();
}

public static string UnZipStr(byte[] input)
{
    using (MemoryStream memstream = new MemoryStream())
    {
        using (MemoryStream inputStream = new MemoryStream(input))
        {
            using (DeflateStream gzip =
              new DeflateStream(inputStream, CompressionMode.Decompress))
            {
                using (StreamReader reader =
                  new StreamReader(gzip, System.Text.Encoding.UTF8))
                {
                    return reader.ReadToEnd();
                }
            }
        }
    }
}

Java コードから zip データを送信します。

    void callService(byte[] xmlData) {
    SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
    request.addProperty("device_id", AGENT);

    Deflater deflater = new Deflater();
    deflater.setInput(xmlData);
    deflater.finish();

     ByteArrayOutputStream baos = new ByteArrayOutputStream();
     byte[] buf = new byte[1024];
     while (!deflater.finished()) {
         int byteCount = deflater.deflate(buf);
         baos.write(buf, 0, byteCount);
     }
     deflater.end();

     byte[] compressedBytes = baos.toByteArray();

    request.addPropertyIfValue("file", org.kobjects.base64.Base64.encode(compressedBytes));...}

C# コードでは、StreamReader からデータを読み取るときに例外が発生します

SoapFault - faultcode: 'soap:Server' faultstring:     'System.Web.Services.Protocols.SoapException: ---> InvalidDataException: Block length does    not correspond to the complement.
System.IO.Compression.Inflater.DecodeUncompressedBlock(Boolean& end_of_block)
System.IO.Compression.Inflater.Decode()
System.IO.Compression.Inflater.Inflate(Byte[] bytes, Int32 offset, Int32 length)
System.IO.Compression.DeflateStream.Read(Byte[] array, Int32 offset, Int32 count)
System.IO.StreamReader.ReadBuffer()
System.IO.StreamReader.ReadToEnd()
Service.UnZipStr(Byte[] input) в c:\inetpub\wwwroot\WebSite\App_Code\Service.cs: at 94
Service.SetZip(String device_id, String file) в c:\inetpub\wwwroot\WebSite\App_Code    \Service.cs: at 73

私が間違っていることは何ですか?

4

2 に答える 2

0

@Joni Salonenがデフレートの問題に答えたようですので、アーキテクチャについて少し追加したいと思います。問題を切り分けるには、2つの懸念を分離する必要があります。まず、zipファイルをドロップする必要があります。次に、それを収縮させる必要があります。次に、問題のある領域に個別に焦点を合わせます。後でいつでも2つの懸念事項を「パイプライン」することができます。

ところで、多くの場合、生のzipファイルがあると便利です。特に、何かが計画どおりに機能しない場合は、セーフティネットになります。ファイルをキャプチャする機会が1回しかない場合。

于 2012-02-23T15:59:20.810 に答える
0

編集:私は掘り下げてきましたが、C# が認識する Java から DEFLATE 形式のデータを生成する方法がありますDeflater(int,boolean)。コンストラクターを使用する必要があります。したがって、Java コードを次のように変更します。

Deflater deflater = new Deflater(Deflater.DEFAULT_COMPRESSION, true);
deflater.setInput(xmlData);
deflater.finish();

その理由は、デフレーターがデフォルトで ZLIB ヘッダーとチェックサムを出力するためです。これは C#DeflateStreamでは想定されていません。


Java と C# は「deflate」圧縮アルゴリズムの正確な種類について同意していないようですが、私のテストでは「gzip」が機能するはずです。

これはJavaで圧縮xmlDataします:

ByteArrayOutputStream baos = new ByteArrayOutputStream()
OutputStream out = new GZIPOutputStream(baos);
out.write(xmlData);
out.close();
byte[] compressedBytes = baos.toByteArray();

inputこれは C# で解凍します。

using (MemoryStream inputStream = new MemoryStream(input))
{
  using (GZipStream gzip = new GZipStream(inputStream, CompressionMode.Decompress))
  {
    using (StreamReader reader = new StreamReader(gzip, System.Text.Encoding.UTF8))
    {
      return reader.ReadToEnd();
    }
  }
}
于 2012-02-23T15:27:35.303 に答える