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