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 asBufferedInputStream
use
handles closing the streamreadBytes
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 returnnull
. 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.
精彩评论