我正在开发一个项目,当前的结构可以发挥最大作用
意义是将 1.2MB 文件发送到托管 ARM 进程的标准输入。
在Java中,这个进程是用ProcessBuilder
创建的,
并尝试写入进程的输出流
os.write(buf)
结果
以下堆栈跟踪表明写入
导致进程/管道终止。
此写入一直适用于较小的缓冲区
100 个字节。
我尝试过使用 Apache 的 IOUtils、BufferedOutputStream、 和 OutputStreamWriter,但它们都会导致进程终止。
我尝试将写入分块以发送 1k 字节 时间如以下代码 fragment 所示。
int chunkSize = 1000, sentBytes = 0, i = 0;
while (sentBytes < b.length) {
Log.d(TAG, "Writing chunk " + i);
int sz = sentBytes+chunkSize > b.length ? b.length % chunkSize : chunkSize;
os.write(b, i*chunkSize, sz);
os.flush();
sentBytes += chunkSize; i++;
}
但是,这在崩溃之前只能发送 68k 字节。 我已经运行了多次并且代码始终崩溃 在写入 block 68 时。
我尝试制作一个最小的工作示例 here尝试 来隔离这个问题。然而,这段代码完全 尝试写入 1MB 数据时挂起。 当写入 100 个字节时,此代码可以正确运行。
我不确定我是否正在寻找正确的术语,但是 以下是我找到的一些相关帖子,没有涉及 这个问题。
- Sending Large files as stream to process.getOutputStream
- write (byte[] b) optim usage for large byte array
那么,如何正确地将大(1.2MB)文件写入OutputStream
Android Java 中管理的进程
?
我还可以尝试哪些其他方法?
我的备份计划是修改子进程以不读取这么多数据
来自stdin
,但这种修改并不理想。
最佳答案
先说第二个问题。默认情况下,ProcessBuilder
将安排您的子进程的 stdin
和 stdout
连接到您的程序。您的测试程序生成 cat
并将 1 MB 数据写入其 stdin
。但是 cat
的工作是将其 stdin
复制到其 stdout
,而您永远不会从其 stdout
中读取数据!一旦内核的管道缓冲区填满,cat
将在尝试写入时阻塞。由于它被阻止,它不再从其 stdin
读取数据,因此您的程序会依次阻塞。
您的原始程序有一个不同的问题:EPIPE
上的写入失败,而不是挂起。正如您所指出的,这意味着您的子进程已终止(或至少已关闭其 stdin
)。您的帮助程序进程不知道也不关心您正在使用哪个 Java API:它只是从管道中读取数据,并且 POSIX 管道机制中没有任何内容可以导致管道读取器退出。 (另一方面,如果最后一个读取器消失,则可以通过 SIGPIPE
杀死写入者。)您是否排除了数据内容中的某些内容您'重新发送会导致您的帮助进程退出吗?
关于java - 将大字节数组通过管道传输到 Android 应用程序中的 Process,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26083731/