2012-02-17 12 views
5

Próbowałem utworzyć obiekt RandomAccessFile z pliku zasobów surowych w katalogu zasobów Androida bez powodzenia.RandomAccessFile w pliku surowego zasobu systemu Android

Jestem w stanie uzyskać obiekt wejściowy z pliku zasobów surowych.

getResources().openRawResource(R.raw.file); 

Czy jest możliwe utworzenie obiektu RandomAccessFile z pliku zasobów surowych lub Czy muszę trzymać się strumienia wejściowego?

+2

Nie sądzę, ponieważ plik zasobów będą nadal przechowywane w skompresowanym pliku APK, więc InputStream ciebie Otrzymywanie to prawdopodobnie ZipEntryInputStream. A ponieważ jest skompresowany, musisz go odczytać jako strumień. Szukanie różnych pozycji w pliku prawdopodobnie nie jest czymś, co potrafi RandomAccessFile. – Brigham

+0

"Plik dostępu losowego" ... i mówisz, że poszukiwanie nie jest możliwe? – fabspro

+0

Musisz skopiować plik na kartę SD (zobacz http://stackoverflow.com/questions/4447477/android-how-to-copy-files-in-assets-to-sdcard), a następnie możesz użyć na tym pliku RandomAccessFile . – ron

Odpowiedz

1

Po prostu nie można wyszukiwać do przodu i do tyłu w strumieniu wejściowym bez buforowania wszystkiego pomiędzy pamięciami. To może być bardzo kosztowne i nie jest skalowalnym rozwiązaniem do odczytu pliku (binarnego) o dowolnym rozmiarze.

Masz rację: najlepiej użyć wartości RandomAccessFile, ale odczyt z zasobów zapewnia zamiast tego strumień wejściowy. Sugestia wspomniana w powyższych komentarzach polega na wykorzystaniu strumienia wejściowego do zapisania pliku na karcie SD i losowego uzyskania dostępu do pliku z tego miejsca. Można rozważyć pisanie plik do katalogu tymczasowego, czytając ją i usuwając go po użyciu:

String file = "your_binary_file.bin"; 
AssetFileDescriptor afd = null; 
FileInputStream fis = null; 
File tmpFile = null; 
RandomAccessFile raf = null; 
try { 
    afd = context.getAssets().openFd(file); 
    long len = afd.getLength(); 
    fis = afd.createInputStream(); 
    // We'll create a file in the application's cache directory 
    File dir = context.getCacheDir(); 
    dir.mkdirs(); 
    tmpFile = new File(dir, file); 
    if (tmpFile.exists()) { 
     // Delete the temporary file if it already exists 
     tmpFile.delete(); 
    } 
    FileOutputStream fos = null; 
    try { 
     // Write the asset file to the temporary location 
     fos = new FileOutputStream(tmpFile); 
     byte[] buffer = new byte[1024]; 
     int bufferLen; 
     while ((bufferLen = fis.read(buffer)) != -1) { 
      fos.write(buffer, 0, bufferLen); 
     } 
    } finally { 
     if (fos != null) { 
      try { 
       fos.close(); 
      } catch (IOException e) {} 
     } 
    } 
    // Read the newly created file 
    raf = new RandomAccessFile(tmpFile, "r"); 
    // Read your file here 
} catch (IOException e) { 
    Log.e(TAG, "Failed reading asset", e); 
} finally { 
    if (raf != null) { 
     try { 
      raf.close(); 
     } catch (IOException e) {} 
    } 
    if (fis != null) { 
     try { 
      fis.close(); 
     } catch (IOException e) {} 
    } 
    if (afd != null) { 
     try { 
      afd.close(); 
     } catch (IOException e) {} 
    } 
    // Clean up 
    if (tmpFile != null) { 
     tmpFile.delete(); 
    } 
} 
+3

Czy to naprawdę jedyny sposób? Wygląda na strasznie okrężną. Nie ma sposobu, aby po prostu uzyskać swobodny dostęp do pliku zasobów w katalogu raw? – Fra

Powiązane problemy