Android-从Uri到InputStream再到字节数组?
我正在尝试从Android Uri获取字节数组 我有以下代码,但它一直告诉我字节数组是61字节长的,即使文件相当大——因此我认为它可能将Uri字符串转换为字节数组,而不是文件:( 有人能帮我想一想怎么办吗 输出为“fileUriString=content://media/external/video/media/53和“数据长度为61字节” 谢谢!Android-从Uri到InputStream再到字节数组?,android,Android,我正在尝试从Android Uri获取字节数组 我有以下代码,但它一直告诉我字节数组是61字节长的,即使文件相当大——因此我认为它可能将Uri字符串转换为字节数组,而不是文件:( 有人能帮我想一想怎么办吗 输出为“fileUriString=content://media/external/video/media/53和“数据长度为61字节” 谢谢!是。toString()将为您提供InputStream实例的字符串表示,而不是其内容 您需要将()字节从InputStream读取到数组中。有两种
是。toString()
将为您提供InputStream实例的字符串表示,而不是其内容
您需要将()字节从InputStream读取到数组中。有两种读取方法,一次读取一个字节,另一种从InputStream读取字节到您传递给它的字节数组中
更新:如果InputStream本身没有长度,那么要读取字节,您需要读取字节,直到没有剩余的字节。我建议您自己创建一个类似这样的方法,这是一个很好的简单起点(至少在Java中是这样做的) 应该是
while (inputStream.available() >0 && (len = inputStream.read(buffer)) != -1)
如中所述,如果流没有可用字节,这种读取方式将不会阻止。使用Apache Commons,您可以从
流中读取所有字节,这要感谢as next:
下载jar:
分享我的想法: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;
}
使用Google Guava,您可以使用获取输入流中的所有字节:
InputStream is = ...;
byte[] bytes = ByteStream.toByteArray(is);
如果您有一个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,就不能使用标准文件读取器。Kotlin way:
@Throws(IOException::class)
private fun readBytes(context: Context, uri: Uri): ByteArray? =
context.contentResolver.openInputStream(uri)?.buffered()?.use { it.readBytes() }
在Kotlin中,他们为输入流
添加了方便的扩展功能,如缓冲
、使用
和读取字节
buffered
将输入流装饰为BufferedInputStream
使用
句柄关闭流
readBytes
的主要工作是读取流并写入字节数组
错误案例:
IOException
可能在该过程中发生(如在Java中)
openInputStream
可以返回null
。如果您在Java中调用该方法,您可以很容易地监督这一点。请考虑如何处理这种情况
谢谢。但这并不能解决问题,因为我必须指定字节[]的长度数组,而我不能从InputStream中得到它。知道我如何计算给定Uri的数据长度吗?你不必事先知道文件大小。建议的解决方案可以处理任何流长度。为什么我们需要声明缓冲区大小?可以计算任何长度吗?如果是的话,是否无法将整个长度立即使用ents?@AP257我不确定它是否有帮助,但要从输入流中读取字节数,可以调用。available()
methodInputStreamReader使用Big5编码格式,因为我的内容有中文字符,所以可以使用UTF-8什么是cR
?您询问如何“从Uri到InputStream”但是你已经得到了一个InputStream
,没有说明你是如何得到它的。@Vince如果你只收到了一半的文件,那么cR
是ContentResolver类阻塞的一个实例是正确的行为。检查可用性是检查文件结尾的可怕替代方法。
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;
}
InputStream is = ...;
byte[] bytes = ByteStream.toByteArray(is);
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();
@Throws(IOException::class)
private fun readBytes(context: Context, uri: Uri): ByteArray? =
context.contentResolver.openInputStream(uri)?.buffered()?.use { it.readBytes() }