Строка base64, декодированная без gziped от младшего байтового 4-байтового int до java int - PullRequest
1 голос
/ 16 июля 2010

Я пытаюсь внедрить файлы TMX в Android, и я надеялся, что кто-то может помочь. На основании TMX Guide , чтобы получить GID, мне нужно

сначала base64 декодирует строку, затем распаковывает результирующие данные, если для атрибута сжатия установлено значение "gzip", как в приведенном выше примере. Наконец, вы можете прочитать 4 байта за раз для каждого GID от начала потока данных до конца.

Мне кажется, я понял, что такое декодирование base64 и «gunzip», но результат из кода ниже повторяется 27,0,0,0. Я думаю, что выход должен быть

(0,0) (1,0) (2,0) (3,0) (0,1) (1,1) (2,1) (3,1) (0,2) (1) , 2) (2,2) (3,2)

Спасибо!

 public static void main( String[] args )
 {
 String myString = "H4sIAAAAAAAAAO3NoREAMAgEsLedAfafE4+s6l0jolNJiif18tt/Fj8AAMC9ARtYg28AEAAA";

 byte[] decode = Base64.decodeBase64(myString);

 ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(decode); 
 GZIPInputStream gzipInputStream;

 int read;
 try
 {
      gzipInputStream = new GZIPInputStream(byteArrayInputStream);

      InputStreamReader inputStreamReader = new InputStreamReader(gzipInputStream);
      BufferedReader bufferedReader = new BufferedReader(inputStreamReader, 4);

      while ( ( read = bufferedReader.read() ) != -1 )
      {
           System.out.println("read :" + read);
      }
 }
 catch (IOException e)
 {
      e.printStackTrace();
 }
 }

Ответы [ 2 ]

1 голос
/ 16 июля 2010

Не используйте Reader s ни для чего, кроме символьных данных!

Используйте DataInput для чтения целых чисел. Украсьте свой GZIPInputStream DataInputStream и используйте readInt.

Если целые числа имеют младший порядок, вам необходимо изменить порядок байтов для типа. Java использует сетевой порядок байтов (big-endian). Для целых чисел это можно сделать с помощью Integer.reverseBytes .

Вы можете распечатать шестнадцатеричные значения, используя:

System.out.format("%08x", (int) n);

Как прочитать все int значения из потока произвольной длины:

Одним из механизмов будет использование метода available(), который оценивает количество оставшихся байтов:

byte[] ints = {0x00, 0x00, 0x00, (byte) 0xFF,
               (byte) 0xAA, (byte) 0xBB, (byte) 0xEE, (byte) 0xFF};
ByteArrayInputStream array = new ByteArrayInputStream(ints);
DataInputStream data = new DataInputStream(array);
while(data.available() > 0) {
  int reversed = Integer.reverseBytes(data.readInt());
  System.out.format("%08x%n", reversed);
}

В общем случае available() не является надежным механизмом. Но вы можете увеличить поток с помощью буфера для проверки доступности данных:

  public static void main(String[] args) throws IOException {
    byte[] ints = {0x00, 0x00, 0x00, (byte) 0xFF,
                    (byte) 0xAA, (byte) 0xBB, (byte) 0xEE, (byte) 0xFF};
    ByteArrayInputStream array = new ByteArrayInputStream(ints);
    BufferedInputStream buffer = new BufferedInputStream(array);
    DataInputStream data = new DataInputStream(buffer);
    while(hasData(data)) {
      int reversed = Integer.reverseBytes(data.readInt());
      System.out.format("%08x%n", reversed);
    }
  }

  public static boolean hasData(InputStream in) throws IOException {
    in.mark(1);
    try {
      return in.read() != -1;
    } finally {
      in.reset();
    }
  }
0 голосов
/ 16 июля 2010
    public static void main( String[] args )
{
    String myString = "H4sIAAAAAAAAA+3X2QrCMBAF0OKbSwWrCC4vdV/+w///JKeQgWFIatJ0SfE+HJDGonfaTJI8y7IlORkLkotrZ3I0SjUux2zfCSX/h/7tX/T9/5jjQl7kalSfb4nk2JAJ2Y78eUzJjMwjcnAtQnHt2sixIgVZR+TgWtjca8a4dvy+viNyaE1ycC2kh+WaZqvdUDmeppYxQp5DV313KG3n2JE9OYw8R2m5rw+638WuHzw/mrzjMWS/81k/ZM6U5ofsdz7rh8yZ0vxw9VtX361yfkzOlOZHSC/Xa4NtDgw1PwAgDvdSre/eGot7aV1PHgPbWTW1/a5vDn1WTW1f4ptDn1Vd+5KUyf1IkdXvS1LmOqti7wEAAAAAAAAAAF37AlFWzCEQJwAA";

    byte[] decode = Base64.decodeBase64(myString);

    ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(decode); 

    int read;
    try
    {
        GZIPInputStream gzipInputStream = new GZIPInputStream(byteArrayInputStream);

        DataInputStream dataInputStream = new DataInputStream(gzipInputStream);

        for ( int i = 0; i < decode.length; i++ )
        {
            read = dataInputStream.readInt();
            int rRead = Integer.reverseBytes(read);
            System.out.println("read :" + rRead);

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