Android-从Uri到InputStream再到字节数组?

Android-从Uri到InputStream再到字节数组?,android,Android,我正在尝试从Android Uri获取字节数组 我有以下代码,但它一直告诉我字节数组是61字节长的,即使文件相当大——因此我认为它可能将Uri字符串转换为字节数组,而不是文件:( 有人能帮我想一想怎么办吗 输出为“fileUriString=content://media/external/video/media/53和“数据长度为61字节” 谢谢!是。toString()将为您提供InputStream实例的字符串表示,而不是其内容 您需要将()字节从InputStream读取到数组中。有两种

我正在尝试从Android Uri获取字节数组

我有以下代码,但它一直告诉我字节数组是61字节长的,即使文件相当大——因此我认为它可能将Uri字符串转换为字节数组,而不是文件:(

有人能帮我想一想怎么办吗

输出为“fileUriString=content://media/external/video/media/53和“数据长度为61字节”

谢谢!

是。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() }