从总是乐于助人的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