Подтвердить что ты не робот

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".

Спасибо!

4b9b3361

Ответ 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();
}

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