在处理C:\Users\Shivam\Desktop\gradle\gradle-3.4.1-all\gradle-3.4.1\bin>gradle wrapper
Starting a Gradle Daemon (subsequent builds will be faster)
:wrapper FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Some problems were found with the configuration of task ':wrapper'.
> Cannot write to file 'C:\Users\Shivam\Desktop\gradle\gradle-3.4.1-all\gradle-3.4.1\bin\gradle\wrapper\gradle-wrapper.properties' specified for property 'propertiesFile', as ancestor 'C:\Users\Shivam\Desktop\gradle\gradle-3.4.1-all\gradle-3.4.1\bin\gradle' is not a directory.
> Cannot write to file 'C:\Users\Shivam\Desktop\gradle\gradle-3.4.1-all\gradle-3.4.1\bin\gradle\wrapper\gradle-wrapper.jar' specified for property 'jarFile', as ancestor 'C:\Users\Shivam\Desktop\gradle\gradle-3.4.1-all\gradle-3.4.1\bin\gradle' is not a directory.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
时发现,当我们在关闭流后写入时,它不会抛出BufferedOutputStream
。
为了验证我的结果,我检查了IOException
,一旦我们在关闭它之后尝试写入FileOutputStream
,就会发现它IOException
。
public class Test {
public static void main(String[] args) {
try {
// Created a byte[] barry1 barry2
byte[] barry1 = { '1', '3' };
byte[] barray2 = { '2', '4' };
OutputStream os = new BufferedOutputStream(
new FileOutputStream("abc.txt", false));
// Writing to stream
os.write(barry1);
os.close();
os.write(barray2); // this suceeds - bug
os = new FileOutputStream("abc.txt", true);
//Writing to stream
os.write(barry1);
os.close();
os.write(barray2); // crashes here, correct.
} catch (Exception e) {
e.printStackTrace();
}
}
}
有人可以帮助我,为什么这种行为有所不同?
答案 0 :(得分:5)
在处理BufferedOutputStream时,发现在关闭流后我们写入它时不会抛出IOException。
BufferedOutputStream
代码没有那种检查 - 但FileOutputStream
也没有。在这两种情况下,只有当IO实际写入磁盘时,操作系统才会“抛出”IOException
。检测到流已关闭的Java代码不是。顺便说一句,这可能意味着一些本机实现根本不会抛出。
FileOutputStream
抛出os.write(...)
上的异常而不是BufferedOutputStream
的原因是它立即将IO写入底层本机层。如果您在os.flush()
之后向BufferedOutputStream
添加os.write()
调用,那么您将看到相同的异常,因为这会强制写出其内部缓冲区。
OutputStream os = new BufferedOutputStream(new FileOutputStream("abc.txt", false));
os.write(barry1);
os.close();
os.write(barray2); // this suceeds – unfortunate behavior
os.flush(); // adding this line throws an IOException
在查看BufferedOutputStream
的{{1}}方法(实际上在close()
基类中)时,您可以看到输出流未设置为FilterOutputStream
或任何东西:
null
我也不喜欢它在这里忽略IOExceptions的事实。哇。这告诉我,我们应该始终在public void close() throws IOException {
try {
flush();
} catch (IOException ignored) {
}
out.close();
}
之前手动调用flush()
,这是我特别不做的模式。
现在将该代码与close()
:
BufferedWriter.close()
public void close() throws IOException {
synchronized (lock) {
if (out == null) {
return;
}
try {
flushBuffer();
} finally {
out.close();
out = null; // good doggie
cb = null;
}
}
}
不会占用该例外,并将委派的BufferedWriter.close()
设置为Writer
。更好的IMO。
答案 1 :(得分:0)
因为BufferedOutputStream
将字节写入内部字节缓冲区,所以在调用时会写入底层输出流,因此如果在{{1}之后调用flush它将抛出异常,但是在这里你尝试在文件流关闭后直接写入文件流,因此例外,这里不足为奇
答案 2 :(得分:0)
在检查JDK代码后发现ensureOpen()
方法抛出IOException并且详细消息为"流已关闭"在BufferedOutputStream中丢失。根据我的理解,这必须在那里。