cha*_*nce 4 java loops for-loop while-loop
我有一段代码来读取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);
}
Run Code Online (Sandbox Code Playgroud)
它工作,但我不喜欢它,因为变量read是在循环之外声明的,并且read()方法被写入两次.修订版:
for (int read = 0; read != -1; read = in.read(buffer, 0, bufferSize)) {
outStream.write(buffer, 0, read);
}
Run Code Online (Sandbox Code Playgroud)
它看起来更好但不够好,因为第一次迭代对于read = 0来说是无用的(也许是有害的).
你有更好的解决方案吗?
Jon*_*eet 10
就我个人而言,我打破这种事情的正常"无条件副作用"规则:
int bytesRead;
while ((bytesRead = in.read(buffer, 0, bufferSize)) != -1)
{
outStream.write(buffer, 0, bytesRead);
}
Run Code Online (Sandbox Code Playgroud)
编辑:如上所述,它确实涉及read在循环外声明,但它只调用read()一次.我从来没有发现它是一个问题 - 虽然我通常更喜欢用尽可能小的范围声明变量,这更像是一般的清洁事物.如果你想进一步限制范围,你可以把整个东西放在大括号中,或者把它提取到自己的方法,比如Alan的方法.这是我如何实现它:
public static void copyStream(InputStream input, OutputStream output)
throws IOException {
byte[] buffer = new byte[1024 * 16]; // Reasonable general size
int bytesRead;
while ((bytesRead = in.read(buffer, 0, buffer.length)) != -1) {
outStream.write(buffer, 0, bytesRead);
}
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以提供缓冲区长度作为参数.请注意,这现在可以进入实用程序库,您无需再次编写代码.
或者,您可以使用它已在其他实用程序库中可用的事实,例如Guava asByteStreams.copy