從總是樂於助人的CommonsWare中查看這個優秀的示例項目。它可以讓你創建你想在一邊不管的InputStream一個ParcelFileDescriptor管,而在另一側的接收應用程序:
https://github.com/commonsguy/cw-omnibus/tree/master/ContentProvider/Pipe
關鍵部位在openFile
創建管:
public ParcelFileDescriptor openFile(Uri uri, String mode)
throws FileNotFoundException {
ParcelFileDescriptor[] pipe=null;
try {
pipe=ParcelFileDescriptor.createPipe();
AssetManager assets=getContext().getResources().getAssets();
new TransferThread(assets.open(uri.getLastPathSegment()),
new AutoCloseOutputStream(pipe[1])).start();
}
catch (IOException e) {
Log.e(getClass().getSimpleName(), "Exception opening pipe", e);
throw new FileNotFoundException("Could not open pipe for: "
+ uri.toString());
}
return(pipe[0]);
}
然後創建一個線程,保持管道充滿:
static class TransferThread extends Thread {
InputStream in;
OutputStream out;
TransferThread(InputStream in, OutputStream out) {
this.in = in;
this.out = out;
}
@Override
public void run() {
byte[] buf = new byte[8192];
int len;
try {
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.flush();
out.close();
} catch (IOException e) {
Log.e(getClass().getSimpleName(),
"Exception transferring file", e);
}
}
}
是否有計劃包括記憶文件和parcelfiledescriptor在未來?沿着這些線條的東西比用臨時文件具有未知生命時間的文件系統混亂/污染更好。 也許有一些方法可以檢測內容提供者內的流的關閉,這可以提供一種更安全的方式來清理自己? 我擔心發送附件到(gmail/standaed)電子郵件客戶端,雖然我確信還有其他地方可能會出現這些問題。 – hannasm 2010-01-29 03:18:09
是的,MemoryFile.java目前有一個'public ParcelFileDescriptor getParcelFileDescriptor()'方法。這是甜甜圈的一部分,但正如傑夫所說,目前還沒有最終確定。 我已經證實,「概念」至少可以工作,而且目前可以使用反射來完成。這是非常骯髒的,但不建議:) 不幸的是,即使'ParcelFileDescriptor.fromSocket()'不能使用,因爲Memory.isMemoryFile()'拋出一個異常,因爲套接字既不是PFD也不是內存文件。 – Joe 2010-07-03 09:11:47
小心MemoryFile。如果我理解正確,它會將文件的全部內容存儲在內存中,因此不能使用比可用內存大的文件。 – 2013-02-22 19:26:46