2012-04-20 29 views
6

Tôi có một ứng dụng hiển thị hình ảnh GIF. Tất cả đều hoạt động tốt nếu hình ảnh được lưu trong drawable, và tôi truy cập vào nó như thế nàyIOException - Không thể tải tệp

is=context.getResources().openRawResource(R.drawable.mygif); 
movie = Movie.decodeStream(is); 

Nhưng tôi cần phải tải hình ảnh từ internet, vì vậy tôi lưu nó vào CacheDir, mà hoạt động tốt. Tôi đã thử những điều sau đây để đọc nó.

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

Và đây

movie = Movie.decodeFile(new File(context.getCacheDir(), "mygif.gif").getPath()); 

Nhưng không có vấn đề gì, nó kết thúc với

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) 

hoặc

java.io.IOException: Mark has been invalidated. 
at java.io.BufferedInputStream.reset(BufferedInputStream.java:350) 
at android.graphics.Movie.decodeStream(Native Method) 

Tôi nghĩ rằng đó là một lỗi rất đơn giản, nhưng tôi có thể không vượt qua nó. Manifest có:

<uses-permission android:name="android.permission.INTERNET"/> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 
+0

Bạn nên kiểm tra xem phần tải xuống và lưu có làm hỏng tệp hay không. Sau khi ứng dụng tải xuống tệp, bạn có thể kéo nó ra khỏi trình mô phỏng hoặc thiết bị bằng cách sử dụng 'adb pull '. Sau đó, bạn có thể kiểm tra xem đó là chính xác những gì trên máy chủ. –

+0

Tôi kéo nó ra giả lập, và nó là tốt. Hình ảnh là 13kB nếu bằng cách nào đó là quan trọng –

+0

Bạn đã thử 'Movie.decodeFile (tệp mới (context.getCacheDir()," mygif.gif "). GetAbsolutePath())'? –

Trả lời

13

gợi ý:

1.try di chuyển vị trí tải về vào thư mục khác như: sdcard, hoặc ứng dụng thư mục khác ngoại trừ cache.

2.when init inputstream, hãy thử sử dụng: init với một kích thước bộ đệm

int buffersize = 16*1024; 
InputStream is = new BufferedInputStream(xxx,buffersize); 

3.to kiểm tra các tập tin tồn tại trong thư mục của bạn

update: thay đổi mã như thế này và không sử dụng 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); 

không có ngoại lệ ném và movie không phải là rỗng.

Ngoài ra, mặc dù mã của bạn sẽ ném ngoại lệ, movie cũng không phải là rỗng.

+0

1. Không có sự khác biệt; 2. Không có sự khác biệt; 3. Nó tồn tại và không bị hỏng –

+0

cập nhật câu trả lời, vui lòng kiểm tra. – idiottiger

+0

Cảm ơn bạn, mã bên dưới thực hiện công việc! mark() bị thiếu. Cảm ơn rất nhiều –

2

tôi biết là một bài thực sự cũ, nhưng tôi đã có cùng một vấn đề

Sao chép InputStream để một mảng byte và gọi Movie.decodeByteArray làm việc cho tôi, ngay cả trên Samsung Devices

0

câu trả lời của tôi là dựa trên câu trả lời của BeNeXuS.

Kích thước tập tin có thể không luôn luôn được biết đến, xem:

File file = ...; 
InputStream inputStream = new FileInputStream(file); 

hoặc

InputStream inputStream = getContext().getContentResolver().openInputStream(uri); 

Sau khi nhận được 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); 
0

Android lên đến 4,4 thất bại trong việc giải mã Movie từ Tệp và Luồng trong trường hợp IOException bên trong trong phương thức InputStream.reset(). Nhưng giải mã từ byte hoạt động tốt trên tất cả các phiên bản của Android.Dưới đây là phiên bản khá nhỏ của mã để làm điều này:

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); 
Các vấn đề liên quan