将大文件作为流发送到 process.getOutputStream

2024-02-27

我在 Windows 机器中使用 gzip 实用程序。我压缩了一个文件并作为 blob 存储在数据库中。当我想使用 gzip 实用程序解压缩此文件时,我将此字节流写入 process.getOutputStream。但超过30KB后,就无法读取该文件了。它挂在那里。

尝试使用内存参数、读取和刷新逻辑。但如果我尝试将相同的数据写入文件,速度会非常快。

 OutputStream stdin = proc.getOutputStream();
 Blob blob = Hibernate.createBlob(inputFileReader);
 InputStream source = blob.getBinaryStream();
 byte[] buffer = new byte[256];
 long readBufferCount = 0;
 while (source.read(buffer) > 0)
 {
  stdin.write(buffer);
  stdin.flush();
  log.info("Reading the file - Read bytes: " + readBufferCount);
  readBufferCount = readBufferCount + 256;
 }
 stdin.flush();

问候, 马尼·库马尔·阿达里。


我怀疑问题是外部进程(连接到proc) 或者是

  • 不读取其标准输入,或者
  • 它正在向其标准输出写入 Java 应用程序未读取的内容。

请记住,Java 使用一对“管道”与外部进程通信,并且这些管道的缓冲量有限。如果超出管道的缓冲容量,写入进程将被阻止写入管道,直到读取进程从管道读取足够的数据以腾出空间。如果读取器不读取,则管道将锁定。

如果您提供更多上下文(例如启动 gzip 进程的应用程序部分),我将能够更加明确。

FOLLOWUP

gzip.exe 是我们使用的 Windows 中的一个 UNIX 实用程序。命令提示符下的 gzip.exe 工作正常。但java程序不行。有什么方法可以增加 java 写入管道的缓冲大小。我目前关心的是输入部分。

在 UNIX 上,gzip 实用程序通常使用以下两种方式之一:

  • gzip file压缩file把它变成file.gz.
  • ... | gzip | ...(或类似的东西)将其标准输入的压缩版本写入其标准输出。

我怀疑你正在做与后者相同的事情,用java应用程序作为源gzip命令的输入及其输出的目的地。如果 java 应用程序没有正确实现,这正是可能锁定的场景。例如:

    Process proc = Runtime.exec(...);  // gzip.exe pathname.
    OutputStream out = proc.getOutputStream();
    while (...) {
        out.write(...);
    }
    out.flush();
    InputStream in = proc.getInputStream();
    while (...) {
        in.read(...);
    }

如果上面应用程序的写入阶段写入了太多数据,那么肯定会锁定。

java应用程序之间的通信gzip是通过两个管道。正如我上面所说,管道将缓冲一定量的数据,但该量相对较小,并且肯定是有限的。这就是锁机的原因。发生的情况如下:

  1. The gzip进程是通过一对将其连接到 Java 应用程序进程的管道创建的。
  2. Java 应用程序将数据写入其out stream
  3. The gzip进程从其标准输入读取数据,对其进行压缩并写入其标准输出。
  4. 步骤2.和3.重复几次,直到最后gzip进程尝试写入其标准输出块。

正在发生的事情是gzip一直在写入其输出管道,但没有从其中读取任何内容。最终,我们到达了耗尽输出管道的缓冲区容量并且写入管道的时间点。

与此同时,Java 应用程序仍在写入out流式传输,再进行几轮后,这也会阻塞,因为我们已经填充了另一个管道。

唯一的解决方案是Java应用程序读写同时。执行此操作的简单方法是创建第二个线程,并从一个线程写入外部进程并从另一个线程中的进程读取。

(更改 Java 缓冲或 Java 读/写大小不会有帮助。重要的缓冲是在管道的操作系统实现中,并且没有办法从纯 Java 中更改它(如果有的话)。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将大文件作为流发送到 process.getOutputStream 的相关文章

随机推荐

  • java.lang.IllegalStateException:片段已添加

    我在使用目标 SDK 4 3 编译和运行的 Android 应用程序时遇到问题 该应用程序有两个 Activity 一个 MainActivity 也是启动器 Activity 和一个 SecondActivity 两者都使用 Fragme
  • 结构体末尾的空数组是C标准吗?

    我注意到在开源项目中经常使用结构末尾的空数组 typedef struct A void arr A 我想知道这是C标准吗 或者只适合 gcc 编译器 从 C99 开始 它现已成为 C 标准 C99 之前的编译器可能不支持它 旧的方法是声明
  • 为什么聚合物的 flex 属性/类不起作用?

    浏览器 Firefox v35 操作系统 Linux Ubuntu 14 Polymer v1 4 正在关注 Rob Dodson 的 Polycasts 大多数视频都提到使用 flex flexbox 来实现响应式设计 然而 我很难让它发
  • 如何使用 jQuery 将表格中的制表符顺序从水平重新分配为垂直?

    如何使用 jQuery 设置带有输入元素的表格的 Tab 键顺序 以便 Tab 键顺序为垂直 每列下方 而不是默认的水平方法 下面的数字代表我想要的跳位顺序 我希望 jQuery 代码能够独立于表中的行数和列数工作 示例表 不幸的是呈现为图
  • 通过IdHTTP读取并保存部分文件流

    我想通过文件流从 HTTP 服务器下载文件 并且只读取 并保存到文件 前几行 例如 100 行 读取前 100 行后 文件流必须结束 所以我不想下载或阅读整个文件 您可以在下面找到我到目前为止所拥有的内容 该网站只是一个例子 有人可以引导我
  • 使用numpy.数字或替代数组上的binary_repr - Python

    使用以下代码我尝试将数字列表转换为二进制数但出现错误 import numpy as np lis np array 1 2 3 4 5 6 7 8 9 a np binary repr lis width 32 运行程序后的错误是 回溯
  • r 包插入符号-使用并行时打印迭代

    无论如何 我们可以在使用时打印迭代caret train并行功能 我知道有一个名为 verbose 的选项 但如果我使用多核 它似乎不会打印任何内容 我找到了解决方案 我们需要的只是通过 makeCluster 函数注册核心 library
  • C# 中的 System.Threading.Timer 似乎不起作用。每3秒运行速度非常快

    我有一个计时器对象 我希望它每分钟运行一次 具体来说 它应该运行一个OnCallBack方法并在 a 时变得不活动OnCallBack方法正在运行 一旦OnCallBack方法完成后 它 aOnCallBack 重新启动计时器 这是我现在所
  • 如何在cmake中使用调试符号构建依赖共享库?

    我的代码是这样组织的 cpp main cpp 从调用代码dataStructures and common CMakeLists txt topmostCMakeLists 文件 build common CMakeLists txt 应
  • Android Java - 创建 Cronjob

    我想要制作一个在后端运行的 Cronjob 并启动一个方法 30 分钟 如果函数返回 true 或其他 Cronjob 将创建一个状态栏通知 在 Android 中这可能吗 如果是的话 用哪个函数 非常感谢 安卓系统报警管理器 http d
  • 如何让 CreateProcess/CreateProcessW 在路径 > MAX_PATH 字符中执行进程

    我试图让 CreateProcess 或 CreateProcessW 执行名称 http msdn microsoft com en us library ms682425 aspx http msdn microsoft com en
  • 限制可排序的容器/父级

    好的 我又来了 和 RubaXa 一起玩Sortable http rubaxa github io Sortable 插件 希望他就在这附近 因为这个插件相当复杂 一些发现 我花了一些时间才完全理解这个机制 但我认为我是对的 Case 1
  • Windows 命令提示符中的别名

    我已经添加了notepad exe到我的环境变量中的路径 现在在命令提示符下 notepad exe filename txt打开filename txt 但我想做的只是np filename txt打开文件 我尝试使用DOSKEY np
  • intel avx2 中是否有 movemask 指令的逆指令?

    movemask 指令采用 m256i 并返回 int32 其中每个位 前 4 8 或所有 32 位 具体取决于输入向量元素类型 是相应向量元素的最高有效位 我想做相反的事情 取 32 其中只有 4 8 或 32 个最低有效位有意义 并获得
  • 冒泡排序有什么用? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何自定义App Designer人物的背景?

    我想附加徽标或更改应用程序设计器的整个背景uifigure 如何才能做到这一点 如果你想设置一个整个图的纯色背景色 那里存在有记录的方式 https www mathworks com help matlab ref uifigureapp
  • 验证在部分视图中不起作用

    我有一个索引页面 其中有两个部分视图 登录和注册 我正在使用数据模型验证 登录 cshtml model Project ViewModel UserModel div using Html BeginForm Login account
  • 从 Ada 访问 c 常量

    我有一个带有这样类型定义的头文件 ifndef SETSIZE define SETSIZE 32 endif typedef struct set unsigned array SETSIZE set t 要使用相应的 C 函数 我需要在
  • jquery 获取之前输入的文本

    我有以下 html div class active string div
  • 将大文件作为流发送到 process.getOutputStream

    我在 Windows 机器中使用 gzip 实用程序 我压缩了一个文件并作为 blob 存储在数据库中 当我想使用 gzip 实用程序解压缩此文件时 我将此字节流写入 process getOutputStream 但超过30KB后 就无法