更好的 Java 循环?
我有一段代码来读取 InputStream
并将内容写入 OutputStream
:
BufferedInputStream in = new BufferedInputStream(...);
FileOutputStream outStream = new FileOutputStream outStream(...);
int read = in.read(buffer, 0, bufferSize);
while (read != -1) {
outStream.write(buffer, 0, read);
read = in.read(buffer, 0, bufferSize);
}
它可以工作,但我不喜欢它,因为变量 read< /code> 被声明为循环外,并且
read()
方法被写入两次。
修改后的版本:
for (int read = 0; read != -1; read = in.read(buffer, 0, bufferSize)) {
outStream.write(buffer, 0, read);
}
它看起来更好,但还不够好,因为第一次迭代在 read=0 时是无用的(而且可能是有害的)。
您有更好的解决方案吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
就我个人而言,我打破了这种事情的正常“条件下无副作用”规则:
编辑:如上所述,它确实涉及在循环外部声明
read
,但是它只调用read()
一次。我从来没有发现这是一个问题——虽然我通常更喜欢声明范围尽可能小的变量,但这更多的是一个一般的清洁问题。如果您想进一步限制范围,您可以将整个内容放在大括号中,或者将其提取到自己的方法中,就像艾伦的方法一样。以下是我实现它的方法:或者,您可以提供缓冲区长度作为参数。请注意,现在可以将其放入实用程序库中,并且您无需再次编写代码。
或者,您也可以利用它已在其他实用程序库中使用的事实,例如 Guava 作为
ByteStreams.copy
Personally I break the normal "no side-effect in a condition" rule for this sort of thing:
EDIT: As noted, it does involve declaring
read
outside the loop, but it only callsread()
once. I've never found it to be a problem - while I generally prefer to declare variables with as small a scope as possible, that's more a general cleanliness thing. If you want to limit the scope further you can put the whole thing in braces, or extract it to its own method, like Alan's approach. Here's how I'd implement it though:Alternatively you could provide the buffer length as a parameter. Note that this can now go off into a utility library, and you need never write the code again.
Alternatively, you could use the fact that it's already available in other utility libraries, such as Guava as
ByteStreams.copy
您可以这样做:
不过,它使用
break
。有些人说break
是不好/不太好的风格。You can do it this way:
It uses a
break
, though. Some people saybreak
is bad/not so good style.这并不出色,但是通过一个简单的块,您可以阻止稍后在方法中访问
read
变量:...但我同意,我也经常想要一个 while 循环,其中值要测试的内容在循环内初始化。据我所知,这是不可能的。
另一种方法是使用提取方法设计模式将该循环提取到完全独立的方法,即
It's not brilliant, but with a simple block, you can stop the
read
variable from being accessed later in the method:...but I agree, I've also often wanted a while loop where the value to be tested is initialized inside the loop. As far as I know, it's not possible.
Another way to do it is to use the extract method design pattern to pull out that loop in to a completely separate method, i.e.
这种形式相当常见:
但在我看来,不太清晰。
This form is rather usual:
but not so good for clarity IMO.