2012-04-19 1 views
2

Я начинающий Android-программист, у которого возникла странная проблема с использованием различных методов чтения активов из AssetManager.Несоответствия между различными способами доступа Android к активам через AssetManager

Приведенный ниже пример кода показывает эту проблему. Он читает простой текстовый файл («hello.txt»), который содержит «привет». Я прочитал его как необработанные байты и распечатал шестнадцатеричные значения символов (68 65 6c 6c 6f).

Пути, которые я пробовал (в порядке в коде):

  • открыт AssetFileDescriptor (ФАР), создать InputStream: читает только в первые три байта (68 65 6c FFFFFFFF FFFFFFFF)
  • открытого AFD, получить основной дескриптор файла, создать FileInputStream: полностью неправильные данные (50 4б 3 4 а)
  • открытого InputStream напрямую: правильно (68 65 6c 6c 6f)

Я также повторил то же самое го РЗЭ методы, на этот раз чтение в массив байт первого, который (удивительно!) меняет первый результат, но в противном случае дает те же результаты (повторенные здесь для удобства):

  • открытого AFD, создать InputStream, прочитать в массив байт первый: правильные (68 65 6c 6c 6f)
  • открыт AFD, получить базовый дескриптор файла, создать FileInputStream, считывается в массив байтов первый: полностью неправильные данные (50 4b 3 4 а)
  • открыт InputStream непосредственно, считывается в байте массив: правильный (68 65 6c 6c 6f)

Примечание что, за исключением самого первого случая (когда считываются только три байта), остальные случаи читают ровно 6 байтов (включая новую строку в конце) и впоследствии возвращают -1 после этого, как ожидалось. Сюда относятся те случаи, когда считываются неправильные данные.

Неужели кто-нибудь сталкивался с этим раньше? Это ошибка, или я сделал что-то неправильно?

Спасибо!

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    AssetManager am = getAssets(); 
    StringBuilder sb = new StringBuilder(); 

    try { 
     AssetFileDescriptor afd = am.openFd("hello.txt"); 
     InputStream instream = afd.createInputStream(); 
     sb.append(String.format("afd.createInputStream(): %x %x %x %x %x\n", instream.read(), instream.read(), instream.read(), instream.read(), instream.read())); 
     instream.close(); 
     afd.close(); 
    } 
    catch (IOException e) { 
     throw new RuntimeException(e); 
    } 

    try { 
     AssetFileDescriptor afd = am.openFd("hello.txt"); 
     InputStream instream = new FileInputStream(afd.getFileDescriptor()); 
     sb.append(String.format("new FileInputStream(afd): %x %x %x %x %x\n", instream.read(), instream.read(), instream.read(), instream.read(), instream.read())); 
     instream.close(); 
     afd.close(); 
    } 
    catch (IOException e) { 
     throw new RuntimeException(e); 
    } 

    try { 
     InputStream instream = am.open("hello.txt"); 
     sb.append(String.format("am.open(): %x %x %x %x %x\n", instream.read(), instream.read(), instream.read(), instream.read(), instream.read())); 
     instream.close(); 
    } 
    catch (IOException e) { 
     throw new RuntimeException(e); 
    } 

    try { 
     AssetFileDescriptor afd = am.openFd("hello.txt"); 
     InputStream instream = afd.createInputStream(); 
     byte[] b = new byte[instream.available()]; 
     instream.read(b); 
     sb.append(String.format("afd.createInputStream() -> byte[]: %x %x %x %x %x\n", b[0], b[1], b[2], b[3], b[4])); 
     instream.close(); 
     afd.close(); 
    } 
    catch (IOException e) { 
     throw new RuntimeException(e); 
    } 

    try { 
     AssetFileDescriptor afd = am.openFd("hello.txt"); 
     InputStream instream = new FileInputStream(afd.getFileDescriptor()); 
     byte[] b = new byte[(int) afd.getLength()]; 
     instream.read(b); 
     sb.append(String.format("new FileInputStream(afd) -> byte[]: %x %x %x %x %x\n", b[0], b[1], b[2], b[3], b[4])); 
     instream.close(); 
     afd.close(); 
    } 
    catch (IOException e) { 
     throw new RuntimeException(e); 
    } 

    try { 
     InputStream instream = am.open("hello.txt"); 
     byte[] b = new byte[instream.available()]; 
     instream.read(b); 
     sb.append(String.format("am.open() -> byte[]: %x %x %x %x %x\n", b[0], b[1], b[2], b[3], b[4])); 
     instream.close(); 
    } 
    catch (IOException e) { 
     throw new RuntimeException(e); 
    } 

    // print result 
    TextView textview = (TextView) findViewById(R.id.textview); 
    textview.setText(sb.toString()); 
    Log.d("blah", sb.toString()); 
} 

ответ

0

Получите InputStream из BaseContext приложения. Пример ниже демонстрирует получение txt-файла из папки активов и печать его содержимого на консоли.

try { 
     InputStream in = getBaseContext().getResources().getAssets().open("sample.txt"); 
     InputStreamReader is = new InputStreamReader(in); 
     BufferedReader br = new BufferedReader(is); 
     String read=br.readLine(); 

     while(read != null) { 
      System.out.println(read); 
      read = br.readLine(); 
     } 

    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
+0

Эй, Майк, спасибо за ответ. Я считаю, что метод, который вы предлагаете, - это тот, который я пробовал, который последовательно работает (метод, который я называю «открытием InputStream напрямую»). Однако мой вопрос заключается не столько в том, какой путь является лучшим способом, а в том, почему другие способы (которые, как я считаю, также должны работать в теории), похоже, не работают. – bacchuswng

Смежные вопросы