当前位置: 首页 > 知识库问答 >
问题:

使用ByteArrayInputStream进行“正确”标记/重置行为的危险/保证

松阳泽
2023-03-14

这个问题可能是泛泛的,但我试图理解这里的主要含义。

我正在尝试使用BCEL库进行一些字节码工程,部分工作流程要求我多次读取同一字节码文件(从一开始)。流程如下

// 1. Get Input Stream

// 2. Do some work

// 3. Finish

// 4. Do some other work.

在第4步中,我需要重置标记或获取流,就像它是从一开始的一样。我知道以下选择。

1)使用BufferedInputStream包装流-有机会获得“重置为无效标记”IOException

2)使用ByteArrayInputStream包装它-即使一些在线研究表明它是错误的,它仍然有效?

3) 如果需要再次读取流,只需html" target="_blank">调用getInputStream()。

我正在努力了解哪种选择对我来说更好。我不想使用BufferedInputStream,因为我不知道调用最后一个标记的位置,因此调用更高的标记位置将导致IOException。我更喜欢使用ByteArrayInputStream,因为它对我来说需要最少的代码更改,但是有人能建议选项2还是选项3更好吗?

我知道JDK中的ByteArrayInputStreamBufferedInputStream的mark()和reset()的实现是不同的。

当做

共有1个答案

洪捷
2023-03-14

mark/重置的问题不仅在于您必须事先知道在这些调用之间读取的最大数据量,还必须知道您委托给的代码是否会在内部使用该功能,从而使您的标记过时。使用mark/重置的代码不可能为调用者记住和恢复以前的标记。

因此,虽然可以通过将总文件大小指定为最大读取限制来解决最大问题,但在将InputStream传递给未明确说明从不在内部使用标记重置功能的任意库函数时,永远不能依赖工作标记。

此外,BufferedInputStream获得与总文件大小匹配的readlimited不会比包装包含整个文件的数组的ByteArrayInputStream更有效,因为两者最终都会维护相同大小的缓冲区。

最好的解决方案是将整个类文件读入一个数组,然后直接使用该数组,例如,对于您控制的代码或当您可以选择库时(例如,ASM的ClassReader支持使用字节数组而不是InputStream)。

如果您必须将InputStream提供给坚持使用它的库函数,例如BCEL,然后在需要时将字节数组包装到ByteArrayInputStream中,但每次必须重新解析类文件时都会创建一个新的ByteArrayInputStream。构建新的ByteArrayInputStream不需要任何成本,因为它是一个轻量级的包装器并且是可靠的,因为它不以任何方式依赖于旧输入流的状态。您甚至可以让多个ByteArrayInputStream实例同时读取同一个数组。

再次调用getInputStream()将是一种选择,如果您必须处理缓冲全部内容不是选项的非常大的文件,但是,类文件并非如此。

 类似资料:
  • 我试图刮一个页面与美丽的汤,有

  • 问题内容: 我现在正在开发应用程序,并进行全局切换。我想包装起来以方便使用。 然后,我在Firefox控制台中得到此结果。 如果我想使用被呼叫的行号登录该怎么办? 问题答案: 这是一个古老的问题,提供的所有答案都太过分了,存在跨浏览器的重大问题,并且没有提供任何超级有用的东西。该解决方案可在每种浏览器中使用,并完全按需报告所有控制台数据。无需黑客,只需一行代码即可签出codepen。 像这样创建开

  • 我对保险库使用默认令牌身份验证方法。同时在Spring Boot应用程序中集成了vault和spring cloud config server。根令牌有超级用户访问,这使得能够为应用程序读/写机密,但我需要创建一个非根令牌,它只登录到保险库,不读/写任何机密。这样就不会强制使用vault,并且应用程序使用vault启动。当用户特别想使用vault时,可以提供自己的令牌和访问秘密。

  • 问题内容: 使用git“标记”构建时,jenkins上有一个选项。 这是做什么用的,我该如何使用?我假设我可以在该版本中标记构建,但是我正在努力寻找如何推送该标记的方法-除非我可以按下该标签,否则它不会那么有用。 问题答案: 您并不总是希望推送 所有 构建标记,因为根据构建周期的不同,可能会有很多构建标记。 但是,任何任务调度程序(例如Jenkins)都将标记构建,以防您想返回到特定代码并对其进行

  • 问题内容: 为什么这么危险? 为什么建议改为使用? 我知道已弃用。还有什么使它不安全的? 有什么地方可以使用方法吗?如果是这样,请举一个例子。 问题答案: 为什么Thread.stop()如此危险? 此处详细描述了这些问题:http : //download.oracle.com/javase/6/docs/technotes/guides/concurrency/threadPrimitiveD

  • 我正在开发一个解决方案,允许在远程服务器上使用p12证书进行签名。 首先,我有一个服务器上计算的文档摘要,然后我把它发送到另一个服务器上签名。 这里是PDF文件,你会发现两个PDF版本。“CURRENT_SIGNATURE.pdf”文件是我使用下面的代码得到的结果。“targetr_SIGNATUREPDF.pdf”是我想要的目标。正如您所看到的,目标文件显示“签名中嵌入的证书撤销列表”另一方面,