开发者

Android - getting from a Uri to an InputStream to a byte array?

开发者 https://www.devze.com 2022-12-23 05:59 出处:网络
I\'m trying to get from an Android Uri to a byte array. I have the following code, but it keeps telling me that the byte array is 61 bytes long, even though the file is quite large - so I think it m

I'm trying to get from an Android Uri to a byte array.

I have the following code, but it keeps telling me that the byte array is 61 bytes long, even though the file is quite large - so I think it may be turning the Uri string into a byte array, rather than the file :(

  Log.d(LOG_TAG, "fileUriString = " + fileUriString);
  Uri tempuri = Uri.parse(fileUri开发者_运维技巧String);
  InputStream is = cR.openInputStream(tempuri);
  String str=is.toString();
  byte[] b3=str.getBytes();
  Log.d(LOG_TAG, "len of data is " + imageByteArray.length
     + " bytes");

Please can someone help me work out what to do?

The output is "fileUriString = content://media/external/video/media/53" and "len of data is 61 bytes".

Thanks!


is.toString() will give you a String representation of the InputStream instance, not its content.

You need to read() bytes from the InputStream into your array. There's two read methods to do that, read() which reads a single byte at a time, and read(byte[] bytes) which reads bytes from the InputStream into the byte array you pass to it.


Update: to read the bytes given that an InputStream does not have a length as such, you need to read the bytes until there is nothing left. I suggest creating a method for yourself something like this is a nice simple starting point (this is how I would do it in Java at least).

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


With Apache Commons, you can read all the bytes from a Stream thanks to IOUtils.toByteArray(InputStream) as next:

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

download jar: http://commons.apache.org/io/download_io.cgi


Kotlin way:

@Throws(IOException::class)
private fun readBytes(context: Context, uri: Uri): ByteArray? = 
    context.contentResolver.openInputStream(uri)?.buffered()?.use { it.readBytes() }

In Kotlin, they added convenient extension functions for InputStream like buffered, use, and readBytes.

  • buffered decorates the input stream as BufferedInputStream
  • use handles closing the stream
  • readBytes does the main job of reading the stream and writing into a byte array

Error cases:

  • IOException can occur during the process (like in Java)
  • openInputStream can return null. If you call the method in Java you can easily oversee this. Think about how you want to handle this case.


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

should be

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

This way read will not block if stream has no available bytes as explained in this answer.


With Google Guava, you can use ByteStreams.toByteArray(InputStream) to get all the bytes in the input stream:

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


Sharing my idea :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;
}


if You have an Uri, instead of a regular file name, you should use Content Resolver. Android: Getting a file URI from a content URI?

I tried this, and it works. Uri uri; // it is something, I've got from a file chooser. Of course, I must be sure, that the uri points to a filename, and it is not an image, or audio, or something else...

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

I've omitted some try-catch-finally from the code, but the most important things are here. The first thing is, that if you have an uri, you cannot use the standard file reader.

0

精彩评论

暂无评论...
验证码 换一张
取 消