ObjectInputStream readObject EOFException

Я попытался использовать ответ на этот вопрос, чтобы получить работающую реализацию, но я получаю различные ошибки, и теперь я получаю исключение EOFException, и при отладке кажется, что файл не записывается.

Цель состоит в том, чтобы загрузить изображение с URL-адреса, сохранить его во внутреннем кэше, а затем извлечь его из этого кэша для отображения. Где я ошибся? EOFException выдается в CachedImage.java на строке, которая читает byte[] data = (byte[]) ois.readObject();

CachedImage.java

package com.example.droid;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;

import android.graphics.Bitmap;

public class CachedImage implements Serializable {
  private static final long serialVersionUID = -12345678987654321L;
  private transient Bitmap _bmp;

  public CachedImage(Bitmap bmp) {
    this._bmp = bmp;
  }

  public void writeObject(ObjectOutputStream oos) throws IOException {
    oos.defaultWriteObject();

    if (this._bmp != null) {
      int bytes = this._bmp.getWidth() * this._bmp.getHeight() * 4;

      ByteBuffer buffer = ByteBuffer.allocate(bytes);
      this._bmp.copyPixelsToBuffer(buffer);

      if (buffer.hasArray()) {
        try {
          String configName = this._bmp.getConfig().name();

          byte[] array = buffer.array();

          oos.writeObject(array);
          oos.writeInt(this._bmp.getWidth());
          oos.writeInt(this._bmp.getHeight());
          oos.writeObject(configName);
        } catch (BufferUnderflowException e) {
        }
      }
    } else {
      oos.writeObject(null);
    }
  }

  private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
    ois.defaultReadObject();

    byte[] data = (byte[]) ois.readObject();
    if (data != null) {
      int w = ois.readInt();
      int h = ois.readInt();
      String configName = (String) ois.readObject();

      Bitmap.Config configBmp = Bitmap.Config.valueOf(configName);
      Bitmap bitmap_tmp = Bitmap.createBitmap(w, h, configBmp);
      ByteBuffer buffer = ByteBuffer.wrap(data);

      bitmap_tmp.copyPixelsFromBuffer(buffer);

      this._bmp = bitmap_tmp.copy(configBmp, true);

      bitmap_tmp.recycle();
    } else {
      this._bmp = null;
    }
  }
  public Bitmap getBitmap() {
    return this._bmp;
  }
}

И вот сегменты кода, которые запускают вызовы:

Функция асинхронного обратного вызова, когда изображение извлекается из URL-адреса для записи изображения во внутренний файл:

@Override
protected void onPostExecute(Bitmap result) {
  if (result != null) {
      FileOutputStream output = null;
      ObjectOutputStream oos = null;
      try {
        output = ICEApplication.getAppContext().openFileOutput(filename, Context.MODE_PRIVATE);
        oos = new ObjectOutputStream(output);
        CachedImage cachedImage = new CachedImage(result);
        oos.writeObject(cachedImage);
      } catch (Exception e) {
        Log.d("DEBUG", "Exception: " + e.getMessage());
      } finally {
        if (output != null) {
          try {
            oos.close();
            output.close();
          } catch (IOException e) {
          }
        }
      }
    }
  }

Код для чтения образа с диска после загрузки и сохранения:

Bitmap image = null;
FileInputStream input = null;
ObjectInputStream ois = null;
try {
  input = ICEApplication.getAppContext().openFileInput(urldisplay);
  ois = new ObjectInputStream(input);
  CachedImage cachedImage = (CachedImage)ois.readObject();

  image = cachedImage.getBitmap();
} catch (Exception e) {
  Log.d("DEBUG", "Exception: " + e.getMessage());
  return null;
} finally {
  if (input != null) {
    try {
      ois.close();
      input.close();
    } catch (IOException e) {

    }
  }
}

1 ответ

Решение

Я прочитал с http://www.javablogging.com/what-are-writeobject-and-readobject-customizing-the-serialization-process/

ObjectOutputStream использует отражение, чтобы узнать, объявлены ли эти методы. Он использует getPrivateMethod, поэтому эти методы должны быть объявлены закрытыми, чтобы их использовал ObjectOutputStream

Итак, измените метод writeObject метода CachedImage на private(потому что вы опубликовали его как открытый).

Другие вопросы по тегам