Android - переход от Uri к InputStream в массив байтов?
Я пытаюсь перейти с Android Uri в массив байтов.
У меня есть следующий код, но он продолжает говорить мне, что массив байтов имеет длину 61 байт, хотя файл довольно большой - поэтому я думаю, что он может превратить строку Uri в массив байтов, а не файл: (
Log.d(LOG_TAG, "fileUriString = " + fileUriString);
Uri tempuri = Uri.parse(fileUriString);
InputStream is = cR.openInputStream(tempuri);
String str=is.toString();
byte[] b3=str.getBytes();
Log.d(LOG_TAG, "len of data is " + imageByteArray.length
+ " bytes");
Пожалуйста, помогите мне разобраться, что делать?
Вывод: "fileUriString = content://media/external/video/media/53" и "len of data is 61 bytes".
Спасибо!
Ответы
Ответ 1
is.toString()
предоставит вам строковое представление экземпляра InputStream, а не его содержимое.
Вам нужно прочитать() байты из InputStream в свой массив. Здесь два метода чтения: read(), который читает один байт за раз, а read (byte [] bytes), который считывает байты из InputStream в массив байтов, который вы передаете ему.
Обновление: чтобы прочитать байты, учитывая, что InputStream не имеет длины как таковой, вам нужно прочитать байты, пока ничего не останется. Я предлагаю создать для себя метод, подобный этому, является простой простой отправной точкой (так я бы сделал это на Java по крайней мере).
public byte[] readBytes(InputStream inputStream) throws IOException {
// this dynamically extends to take the bytes you read
ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
// this is storage overwritten on each iteration with bytes
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
// we need to know how may bytes were read to write them to the byteBuffer
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
byteBuffer.write(buffer, 0, len);
}
// and then we can return your byte array.
return byteBuffer.toByteArray();
}
Ответ 2
С Apache Commons вы можете прочитать все байты из Stream
благодаря IOUtils.toByteArray(InputStream)
следующим образом:
byte[] recordData = IOUtils.toByteArray(inStream);
скачать jar:
http://commons.apache.org/io/download_io.cgi
Ответ 3
while ((len = inputStream.read(buffer)) != -1)
должен быть
while (inputStream.available() >0 && (len = inputStream.read(buffer)) != -1)
Этот способ чтения не будет блокироваться, если поток не имеет доступных байтов, как описано в этом ответе.
Ответ 4
Котлин путь:
@Throws(IOException::class)
private fun readBytes(context: Context, uri: Uri): ByteArray? =
context.contentResolver.openInputStream(uri)?.buffered()?.use { it.readBytes() }
В Kotlin они добавили удобные функции расширения для InputStream
такие как buffered
, use
и readBytes
.
-
buffered
украшает входной поток как BufferedInputStream
-
use
ручки, закрывающие поток -
readBytes
выполняет основную работу по чтению потока и записи в байтовый массив
Случаи ошибки:
-
IOException
может произойти во время процесса (как в Java) -
openInputStream
может возвращать null
. Если вы вызываете метод в Java, вы можете легко это контролировать. Подумайте, как вы хотите справиться с этим делом.
Ответ 5
С помощью Google Guava вы можете использовать ByteStreams.toByteArray(InputStream)
, чтобы получить все байты во входном потоке:
InputStream is = ...;
byte[] bytes = ByteStream.toByteArray(is);
Ответ 6
Обмен моей идеей: D
private static byte[] getStringFromInputStream(InputStream is)
{
BufferedReader br = null;
StringBuilder sb = new StringBuilder();
byte[] bReturn = new byte[0];
String line;
try
{
br = new BufferedReader(new InputStreamReader(is, "Big5"));
while ((line = br.readLine()) != null)
{
sb.append(line);
}
String sContent = sb.toString();
bReturn = sContent.getBytes();
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
if (br != null)
{
try
{
br.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
return bReturn;
}
Ответ 7
Если у вас есть Uri, вместо обычного имени файла вы должны использовать Content Resolver.
Android: Получение URI файла из URI содержимого?
Я пробовал это, и он работает.
Ури-ури;//это что-то, я получил от выбора файла. Конечно, я должен быть уверен, что uri указывает на имя файла, и это не изображение, звук или что-то еще...
InputStream is=getContentResolver().openInputStream(uri);
InputStreamReader ir=new InputStreamReader(is);
bu=new BufferedReader(ir);
String s;
while ((s=bu.readLine())!=null){
//do something with the line...
}
bu.close();
Я пропустил некоторый try-catch-finally из кода, но самые важные вещи здесь.
Во-первых, если у вас есть uri, вы не можете использовать стандартный считыватель файлов.