2010-03-12 15 views
23

Próbuję uzyskać z Androida Uri do tablicy bajtów.Android - przechodzenie z Uri do InputStream do tablicy bajtów?

Mam następujący kod, ale powtarza mi, że tablica bajtów ma długość 61 bajtów, mimo że plik jest dość duży - tak myślę, że może to być przekręcenie Uri ciąg do tablicy bajtów, raczej niż plik :(

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"); 

Proszę może ktoś mi pomóc wypracować co robić

wyjście jest "fileUriString = zawartość: // media/zewnętrzna/wideo/media/53?" i „len danych to 61 bajtów. "

Dzięki!

+0

co to jest 'cR'? Pytasz, jak przejść "z Uri do InputStream", ale masz już 'InputStream', nie mówiąc o tym, jak to zrobiłeś. – Vince

+0

@Korzystanie z 'cR' jest instancją klasy ContentResolver – mbelsky

Odpowiedz

57

is.toString() Poda ci reprezentację String instancji InputStream, a nie jej zawartość.

Musisz odczytywać() bajty z InputStream do swojej tablicy. Są to dwie metody odczytu: read(), które czyta pojedynczy bajt na raz, i read(byte[] bytes), który odczytuje bajty z InputStream do tablicy bajtów, którą do niej przechodzisz.


Aktualizacja: czytać bajtów podanych że InputStream nie mają długość jako takiego, trzeba czytać bajtów, dopóki nie ma nic. Sugeruję, aby stworzyć metodę dla siebie, coś takiego jest miłym, prostym punktem wyjścia (tak właśnie zrobiłbym to w Javie).

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(); 
} 
+0

Dziękuję. To jednak nie rozwiązuje problemu, ponieważ muszę podać długość tablicy bajtów [] zanim ją dostarczę i nie mogę uzyskać tego z InputStream. Masz pomysł, jak mogę ustalić długość danych, biorąc pod uwagę Uri? – AP257

+0

Niestety, nie jest to możliwe – user1324936

+0

Nie musisz znać rozmiaru pliku z góry. Proponowane rozwiązanie będzie działać z dowolną długością strumienia. –

2
while ((len = inputStream.read(buffer)) != -1) 

powinny być

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

ten sposób odczytu nie będzie blokować, jeśli nie ma dostępnych strumień bajtów, jak wyjaśniono w this answer.

+0

Blokowanie to prawidłowe zachowanie, jeśli otrzymałeś tylko połowę pliku. Sprawdzanie dostępności jest przerażającą alternatywą dla sprawdzania końca pliku. –

0

Udostępnianie mój pomysł: 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; 
} 
+0

InputStreamReader używa formatu kodowania Big5, ponieważ moje treści mają chiński charakter, możesz używać UTF-8 – user2374654

1

Z Google Guava możesz użyć numeru ByteStreams.toByteArray(InputStream) uzyskanie wszystkich bajtów w strumieniu wejściowym:

InputStream is = ...; 
byte[] bytes = ByteStream.toByteArray(is); 
0

Jeśli masz uri, zamiast zwykłej nazwy pliku, należy użyć zawartość Resolver. Android: Getting a file URI from a content URI?

Próbowałem tego i działa. Uri uri; // to jest coś, co otrzymałem z selektora plików. Oczywiście, muszę mieć pewność, że uri wskazuje na nazwę pliku, a nie jest obrazem, dźwiękiem ani czymś innym ...

Pominąłem niektóre try-catch-finally z kodu, ale najważniejsze rzeczy są tutaj. Po pierwsze, jeśli masz urządzenie URI, nie możesz użyć standardowego czytnika plików.

Powiązane problemy