Android - как добраться от Uri до InputStream в байтовый массив? - PullRequest
30 голосов
/ 13 марта 2010

Я пытаюсь добраться от 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» и «длина данных составляет 61 байт».

Спасибо!

Ответы [ 7 ]

66 голосов
/ 13 марта 2010

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();
}
10 голосов
/ 15 мая 2012

С Apache Commons , вы можете прочитать все байты из Stream благодаря IOUtils.toByteArray(InputStream) следующим образом:

byte[] recordData = IOUtils.toByteArray(inStream);

скачать банку: http://commons.apache.org/io/download_io.cgi

2 голосов
/ 17 января 2019

Путь Котлина:

@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, вы можете легко это контролировать. Подумайте, как вы хотите справиться с этим делом.
2 голосов
/ 26 января 2012
while ((len = inputStream.read(buffer)) != -1)

должно быть

while (inputStream.available() >0 && (len = inputStream.read(buffer)) != -1)

Этот способ чтения не будет блокироваться, если поток не имеет доступных байтов, как объяснено в этом ответе .

1 голос
/ 20 мая 2014

В Google Guava вы можете использовать ByteStreams.toByteArray(InputStream), чтобы получить все байты во входном потоке:

InputStream is = ...;
byte[] bytes = ByteStream.toByteArray(is);
0 голосов
/ 13 сентября 2015

если у вас есть 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, вы не можете использовать стандартную программу чтения файлов.

0 голосов
/ 12 мая 2013

Делюсь своей идеей: 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...