我有一个同步方法,我正在使用datainputstream.readfully()。它向我扔了“EOF异常”。为什么真正的方法在同步方法中仍然会抛出EOF?以下是参考代码
private static synchronized String getTransactionId() {
try {
String txnId_fname = SiteConfiguration.getInstance().getProperty("TRANSACTION.INFO_FILE", //
LaneProcessor.DEFAULT_TRANSACTION_ID_FILE_NAME);
File tmpFile = new File(txnId_fname);
if (!tmpFile.exists()) {
tmpFile.createNewFile();
}
else {
long sz = tmpFile.length();
if ( 12 == sz ) {
// read the transaction id from the file, the ID must be 12 bytes long to be valid.
DataInputStream dis = new DataInputStream(new FileInputStream(tmpFile));
byte[] datainBytes = new byte[dis.available()];
dis.readFully(datainBytes);
transactionIdLog = new String(datainBytes, 0, datainBytes.length);
if ( Stringer.isNumeric(transactionIdLog))
{
transactionId = Long.valueOf(transactionIdLog);
}
dis.close();
//log.debug("transaction id from the existing file"+transactionId);
}
}
transactionId = ConvertUtils.incrementLong(transactionId);
transactionIdLog = Long.toString(transactionId);
transactionIdLog = Stringer.zpad(transactionIdLog, 12);
_out = new FileOutputStream(tmpFile);
_out.write(transactionIdLog.getBytes());
_out.flush();
_out.close();
}
catch (Exception e) {
log.error("Error in transaction id generation" + e.getMessage(), e);
}
return transactionIdLog;
}
答案 0 :(得分:1)
可用的合同是它返回可用字节数的估计值;如果你尝试读取那么多字节,程序将不会阻塞,但它可能会读取比可用字节更少的字节。如果可用的结果太高,则readFully
可能会获得EOF异常。不幸的是,我尝试查看FileInputStream.available
的来源以了解它是如何工作的,但它是原生的,所以我无法判断它是否会返回“太大”的值。我只能说,基于javadoc,我不认为你的代码可以保证工作。
要确定这是否真的存在问题,我建议在创建数组后输出程序datainBytes.length
,然后根据实际文件大小进行检查。
答案 1 :(得分:0)
同步方法会抛出EOF异常吗?
字面意思否。方法中的任何异常都将被捕获并记录。所以它不会传播EOFException
。更重要的是,没有throw new EOFException(...)
。
但是你的方法可以捕获EOFException
并记录它吗?我认为答案是肯定的!
如果readFully
方法无法填充缓冲区,EOFException
方法将抛出available()
,并且您已将缓冲区大小设置为available()
所说的可读字节数。但请考虑这种情况:
您的应用程序执行到readFully
返回的位置。
您的应用程序已暂停(例如,通过操作系统调度程序)。
其他一些应用程序会截断该文件。
您的应用程序已恢复,并调用isAvailable()
...仅发现有ZERO字节需要读取。
EOFException ...
这说明了{{1}}的结果只是一个提示。你不能完全依赖它。
但是,我认为在技术上不可能以不会发生EOFException的方式编写该方法。如果没有某种文件锁定,你肯定无法做到这一点......以防止其他应用程序在您的应用程序读取时截断文件。