问题
I have an app that shows GIF images. It all works fine if image is saved in drawable, and I access it like this
is=context.getResources().openRawResource(R.drawable.mygif);
movie = Movie.decodeStream(is);
But I need to download image from internet, so I'm saving it to CacheDir, that works fine. I tried the following to read it.
try
{
is = new BufferedInputStream(new FileInputStream(new File(context.getCacheDir(), "mygif.gif")));
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
movie = Movie.decodeStream(is);
And this
movie = Movie.decodeFile(new File(context.getCacheDir(), "mygif.gif").getPath());
But no matter what, it ends with
java.io.IOException
at java.io.InputStream.reset(InputStream.java:218)
at android.graphics.Movie.decodeStream(Native Method)
at android.graphics.Movie.decodeTempStream(Movie.java:74)
at android.graphics.Movie.decodeFile(Movie.java:59)
or
java.io.IOException: Mark has been invalidated.
at java.io.BufferedInputStream.reset(BufferedInputStream.java:350)
at android.graphics.Movie.decodeStream(Native Method)
I think it's a very simple error, but I can't get over it. Manifest has:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
回答1:
suggestion:
1.try move the download location to another folder like: sdcard
, or the app another folder except the cache
.
2.when init the inputstream
, try use: init with a buffer size
int buffersize = 16*1024;
InputStream is = new BufferedInputStream(xxx,buffersize);
3.to check the file existed in your folder
update: change the code like this and dont use Movie.decodeFile
InputStream is = null;
try {
is = new BufferedInputStream(new FileInputStream(new File(getCacheDir(), "mygif.gif")), 16 * 1024);
is.mark(16 * 1024);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
movie = Movie.decodeStream(is);
no exception throw, and the movie
is not null.
Also, although your code will throw the exception, the movie
is also not null.
回答2:
I know is a really old post, but I was having the same issue
Copying the InputStream to a byte array and calling Movie.decodeByteArray worked for me, even on Samsung Devices
回答3:
My answer is based on the BeNeXuS's answer.
The file size may not always be known, see:
File file = ...;
InputStream inputStream = new FileInputStream(file);
or
InputStream inputStream = getContext().getContentResolver().openInputStream(uri);
After getting the inputStream:
BufferedInputStream bis = new BufferedInputStream(inputStream);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte buffer[] = new byte[1024];
int len;
while ((len = bis.read(buffer, 0, buffer.length)) > 0) {
baos.write(buffer, 0, len);
}
bis.close();
byte[] imageData = baos.toByteArray();
baos.close();
Bitmap bitmap = BitmapFactory.decodeByteArray(imageData, 0, imageData.length);
回答4:
Android up to 4.4 fails to decode Movie from File and Stream in case of internal IOException in InputStream.reset() method. But decoding from bytes works well on all versions of Android. Here is quite minimal version of code to do this:
int size = (int) imageFile.length();
byte[] buffer = new byte[size];
FileInputStream inputStream = new FileInputStream(imageFile);
int readLength = inputStream.read(buffer);
inputStream.close();
Movie movie = Movie.decodeByteArray(buffer, 0, readLength);
来源:https://stackoverflow.com/questions/10240042/ioexception-cannot-load-file