当另一个应用程序将文件发送到我的应用程序时,我通过intent.getExtras().get(EXTRA_STREAM)
属性获得了一个Uri。然后,我可以使用输入流获取文件的字节:new BufferedInputStream(activity.getContentResolver().openInputStream(uri));
到目前为止,一切都还可以。现在我想向我的用户展示一些进展,但是我不确定如何在不事先读取流的情况下获取文件的总字节数(这会破坏进度条的整个目的) )...
我尝试了ParcelFileDescriptor fileDesc = activity.getContentResolver().openFileDescriptor(uri, "r");
,但这仅适用于file://...
类型的uris。
例如,如果我从Skydrive收到一个文件,我会收到一个content://..
Uri,如:content://com.microsoft.skydrive.content.external/external_property/10C32CC94ECB90C4!155/Sunset.480p.mp4
在这样的Uri上,我(不出所料)得到了“FileNotFoundException:Not a whole file”异常。
获得我将获得的数据流总大小的确定方法?
答案 0 :(得分: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进行了测试。返回的文件大小是正确的。
答案 1 :(得分:1)
除了读取整个流之外,没有获取流大小的通用解决方案。这很容易证明:可以创建一个Web服务器,对于某些URL,它会生成随机时间终止的随机文本流。 (事实上,我确信这些URL存在,无论是否设计:-)在这种情况下,直到最后一个字节生成才知道流的大小,从不心灵收到了。
因此,如果服务器发送了流大小,则必须以特定于应用程序的方式发送。
我从未使用过SkyDrive,但谷歌搜索其API却出现this link,其中有以下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")
?)这样的内容会为您提供文件的大小。