7

当另一个应用程序向我的应用程序发送文件时,我通过该intent.getExtras().get(EXTRA_STREAM)属性获得了一个 Uri。然后我可以使用输入流获取文件的字节:new BufferedInputStream(activity.getContentResolver().openInputStream(uri));

一切都很好,到目前为止工作正常。现在我想向我的用户展示某种进展,但我不确定如何在不事先完全读取流的情况下获取文件的总字节数(这会破坏进度条的全部目的) ...

我试过ParcelFileDescriptor fileDesc = activity.getContentResolver().openFileDescriptor(uri, "r");了,但这仅适用于 uri 类型file://...

例如,如果我从 Skydrive 收到一个文件,我会得到一个content://..Uri,如下所示:content://com.microsoft.skydrive.content.external/external_property/10C32CC94ECB90C4!155/Sunset.480p.mp4

在这样的 Uri 上,我得到(不出所料)“FileNotFoundException:不是整个文件”异常。

任何确定的方法来获得我将获得的数据流的总大小?

4

2 回答 2

9

尽管InputStream.available()(几乎)从不推荐获取文件大小的方法,但在您的情况下它可能是一个可行的解决方案。

内容已在本地可用。不涉及服务器。因此,以下应返回确切的文件大小:

try {

    InputStream inputStream = getContentResolver().openInputStream(uri);

    Log.i("TEST", "File Size: " + inputStream.available());

} catch (FileNotFoundException fnfe) {

    fnfe.printStackTrace();

} catch (IOException ioe) {

    ioe.printStackTrace();

}

我用 SkyDrive 和 Dropbox 对此进行了测试。返回的文件大小是正确的。

于 2013-09-12T23:47:14.987 回答
1

除了读取整个流之外,没有通用的解决方案来获取流的大小。这很容易证明:可以创建一个 Web 服务器,对于某些 URL,它会生成一个随机文本流,该文本流在随机时间终止。(事实上​​,我确信这样的 URL 存在,无论是设计与否 :-) 在这种情况下,直到最后一个字节生成后,流的大小才知道,更不用说收到了

因此,如果流大小是由服务器发送的,则必须以特定于应用程序的方式发送。

我从来没有使用过 SkyDrive,但是谷歌搜索它的 API 时发现了这个链接,它有以下 Android Java 应用程序示例:

public void readFile() {
    String fileId =  "file.a6b2a7e8f2515e5e.A6B2A7E8F2515E5E!141";
       client.getAsync(fileId, new LiveOperationListener() {
        public void onError(LiveOperationException exception, LiveOperation operation) {
               resultTextView.setText("Error reading file: " + exception.getMessage());
           }
           public void onComplete(LiveOperation operation) {
            JSONObject result = operation.getResult();
            String text = "File info:" +
                "\nID = " + result.optString("id") +
                "\nName = " + result.optString("name");
               resultTextView.setText(text);
           }
       });
}

根据该页面上的其他示例,我猜想result.optString("size")(或者可能?)之类的东西result.optInt("size")会给你文件的大小。

于 2013-09-12T14:18:46.450 回答