2

我有一个任务

  1. 将 zip 文件从本地读取为二进制消息

  2. 通过 EMS 作为字符串传输二进制消息(由 java API 完成)

  3. 以字符串形式接收传输的二进制消息(由 java API 完成)

  4. 解压二进制消息,然后打印出来

我面临的问题是解压缩消息时出现 DataFormatException 。

我不知道哪个部分出了问题。

我用它来将文件读入二进制消息:

static String readFile_Stream(String fileName) throws IOException {
    File file = new File(fileName);
    byte[] fileData = new byte[(int) file.length()];
    FileInputStream in = new FileInputStream(file);
    in.read(fileData);
    String content = "";
    System.out.print("Sent message: ");
    for(byte b : fileData)
    {
        System.out.print(getBits(b));
        content += getBits(b);
    }
    in.close();
    return content;
}

static String getBits(byte b)
{
    String result = "";
    for(int i = 0; i < 8; i++)
        result = ((b & (1 << i)) == 0 ? "0" : "1") + result;
    return result;
}

我用它来解压缩消息:

private static byte[] toByteArray(String input)
{       
    byte[] byteArray = new byte[input.length()/8];
    for (int i=0;i<input.length()/8;i++)
    {
        String read_data = input.substring(i*8, i*8+8); 
        short a = Short.parseShort(read_data, 2);
        byteArray[i] = (byte) a;                    
    }       
    return byteArray;       
}

public static byte[] unzipByteArray(byte[] file) throws IOException {
    byte[] byReturn = null;

    Inflater oInflate = new Inflater(false);
    oInflate.setInput(file);

    ByteArrayOutputStream oZipStream = new ByteArrayOutputStream();
    try {
        while (! oInflate.finished() ){
            byte[] byRead = new byte[4 * 1024];
            int iBytesRead = oInflate.inflate(byRead);
            if (iBytesRead == byRead.length){
                oZipStream.write(byRead);
            }
            else {
                oZipStream.write(byRead, 0, iBytesRead);
            }
        }
        byReturn = oZipStream.toByteArray();
    }
    catch (DataFormatException ex){
        throw new IOException("Attempting to unzip file that is not zipped.");
    }
    finally {
        oZipStream.close();
    }
    return byReturn;
}

我得到的消息是

java.io.IOException: Attempting to unzip file that is not zipped.
at com.sourcefreak.example.test.TibcoEMSQueueReceiver.unzipByteArray(TibcoEMSQueueReceiver.java:144)
at com.sourcefreak.example.test.TibcoEMSQueueReceiver.main(TibcoEMSQueueReceiver.java:54)

经过检查,二进制消息在传输后没有损坏。请帮助找出问题所在。

4

2 回答 2

0

我终于弄清楚了问题所在。

问题是原始文件是一个 .zip 文件,所以我应该在进一步处理之前使用 zipInputStream 解压缩文件。

public static byte[] unzipByteArray(byte[] file) throws IOException {

    // create a buffer to improve copy performance later.
    byte[] buffer = new byte[2048];
    byte[] content ;

    // open the zip file stream
    InputStream theFile = new ByteArrayInputStream(file);
    ZipInputStream stream = new ZipInputStream(theFile);
    ByteArrayOutputStream output = new ByteArrayOutputStream();

    try
    {

        ZipEntry entry;
        while((entry = stream.getNextEntry())!=null)
        {
            //String s = String.format("Entry: %s len %d added %TD", entry.getName(), entry.getSize(), new Date(entry.getTime()));
            //System.out.println(s);

            // Once we get the entry from the stream, the stream is
            // positioned read to read the raw data, and we keep
            // reading until read returns 0 or less.
            //String outpath = outdir + "/" + entry.getName();

            try
            {
                //output = new FileOutputStream(outpath);

                int len = 0;
                while ((len = stream.read(buffer)) > 0)
                {
                    output.write(buffer, 0, len);
                }
            }
            finally
            {
                // we must always close the output file
                if(output!=null) output.close();                                            
            }
        }            
    }
    finally
    {
        // we must always close the zip file.
        stream.close();            
    }
    content = output.toByteArray();

    return content;     

}

此代码适用于内部包含单个文件的 zip 文件。

于 2014-06-23T02:37:29.983 回答
0

您是否尝试过使用 InflaterInputStream?根据我的经验,直接使用 Inflater 相当棘手。您可以使用它开始:

public static byte[] unzipByteArray(byte[] file) throws IOException {
  InflaterInputStream iis = new InflaterInputStream(new ByteArrayInputStream(file));
  ByteArrayOutputStream baos = new ByteArrayOutputStream();

  byte[] buffer = new byte[512];
  int length = 0;
  while ((length = iis.read(buffer, 0, buffer.length) != 0) {
    baos.write(buffer, 0, length);
  }

  iis.close();
  baos.close();

  return baos.toByteArray();
}
于 2014-06-20T11:24:55.480 回答