Строка base64, декодированная без gzip-преобразования из 4-байтового int с младшим порядком байтов в java int

StackOverflow https://stackoverflow.com/questions/3262348

Вопрос

Я пытаюсь реализовать файлы TMX в Android и надеялся, что кто-нибудь сможет помочь.Основанный на Руководство по TMX, чтобы получить 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();
 }
 }
Это было полезно?

Решение

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

Используйте DataInput чтобы прочитать целые числа.Украсьте свой GZIPInputStream с помощью DataInputStream и использовать readInt.

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

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

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();
    }
  }

Другие советы

    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();
    }
}
.
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top