公共 API 方法应该返回 InputStream 还是 byte[]

Posted

技术标签:

【中文标题】公共 API 方法应该返回 InputStream 还是 byte[]【英文标题】:Should a public API method return InputStream or byte[] 【发布时间】:2012-03-12 07:05:15 【问题描述】:

我正在为以字节流形式检索数据的服务客户端设计 API。 使用

有什么好处
InputStream getData(String param1, String param2);

结束

byte[] getData(String param1, String param2);

返回输入流的方法让我很困扰,因为

    现在我的代码必须依赖外部代码才能关闭输入流。我知道最好只关闭您打开的资源,所以这似乎是错误的。 输入流不可重复。一旦我的代码的客户端读取流,字节就会丢失 我的实现中的流实际上是通过网络(套接字)。当我使用连接池并监控它以摆脱过期连接等时,我觉得能够关闭我自己打开的资源可能会更好。

设计这个的最佳方式是什么?我什至考虑过使用

void writeData(String param, String param, OutputStream os);

但这使得方法名称不直观。

【问题讨论】:

数据的平均大小是多少? 数据最多以 Kbs 为单位,有时以 100 Kbs 为单位,在极少数情况下,它会是一些 Mb……数据并不是很大。主要是文本,有时是图像,很少是视频跨度> 客户端可以对部分数据(因为它正在流入)做任何有用的事情,还是他们需要等待整个数据? 不,他们需要等待整个数据,因为它通常是需要显示的内容.. 好吧,我认为 byte 更好,因为否则你必须关闭流。如果您出于性能原因需要流,我认为具有“危险”名称的方法应该更好,也许 getDataUnsafe,不知道。 【参考方案1】:

byte[] 有两个可能的缺点:

您必须一次将所有内容存储在内存中 - 如果您要处理大量数据,这可能会出现问题。 您班级的用户将不得不等待所有数据可用 - 无法在某些数据可用时立即开始处理。如果网络速度很慢,这可能是一个很大的缺点。

使用 Stream 可以解决这些问题。这取决于您要返回的数据以及您希望用户如何处理这些数据。

【讨论】:

我主要希望用户接受并显示它,但我们想构建一个不特定于当前用例的通用 api 你考虑过提供两种方法吗? 是的...但是我必须给它们起不同的名字,因为当它们实际上做同样的事情时,它们的返回类型是不同的【参考方案2】:

我会返回类似 Guava 的 InputSupplier<InputStream>,它允许您请求多个不同的输入流。

此外,Guava 提供了许多方法,它们接受 InputSupplier<InputStream>,打开输入流,执行一些全流操作,然后关闭它,而无需让您记住关闭输入流或其他任何操作。

即使您不想直接使用 Guava,它也是一种很好的技术,它可以让客户端程序决定如何处理它。

【讨论】:

是的,这是一个很好的技术,我可以用一个类包装输入流,当它到达末尾时记得关闭它 InputSupplier 现在是deprecated。 Guava 从版本 14 开始提供 ByteSourceCharSource,而不是已弃用的 InputSupplier

以上是关于公共 API 方法应该返回 InputStream 还是 byte[]的主要内容,如果未能解决你的问题,请参考以下文章

私有类作为公共方法的返回类型

我应该在我的公共 API 中使用 UUID 来获取资源吗?

Beego 公共方法返回JSON

如何保护公共 API(无凭据)不被利用?

公共和私有端点是不是应该有单独的 API? [关闭]

为啥 InputStream#read() 返回一个 int 而不是一个字节?