同步方法会抛出EOF异常吗?

时间:2013-12-02 16:15:55

标签: java exception synchronized

我有一个同步方法,我正在使用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;
    }

2 个答案:

答案 0 :(得分:1)

可用的合同是它返回可用字节数的估计值;如果你尝试读取那么多字节,程序将不会阻塞,但它可能会读取比可用字节更少的字节。如果可用的结果太高,则readFully可能会获得EOF异常。不幸的是,我尝试查看FileInputStream.available的来源以了解它是如何工作的,但它是原生的,所以我无法判断它是否会返回“太大”的值。我只能说,基于javadoc,我不认为你的代码可以保证工作。

要确定这是否真的存在问题,我建议在创建数组后输出程序datainBytes.length,然后根据实际文件大小进行检查。

答案 1 :(得分:0)

  

同步方法会抛出EOF异常吗?

字面意思否。方法中的任何异常都将被捕获并记录。所以它不会传播EOFException。更重要的是,没有throw new EOFException(...)

但是你的方法可以捕获EOFException并记录它吗?我认为答案是肯定的!

如果readFully方法无法填充缓冲区,EOFException方法将抛出available(),并且您已将缓冲区大小设置为available()所说的可读字节数。但请考虑这种情况:

  1. 您的应用程序执行到readFully返回的位置。

  2. 您的应用程序已暂停(例如,通过操作系统调度程序)。

  3. 其他一些应用程序会截断该文件。

  4. 您的应用程序已恢复,并调用isAvailable() ...仅发现有ZERO字节需要读取。

  5. EOFException ...


  6. 这说明了{{1}}的结果只是一个提示。你不能完全依赖它。

    但是,我认为在技术上不可能以不会发生EOFException的方式编写该方法。如果没有某种文件锁定,你肯定无法做到这一点......以防止其他应用程序在您的应用程序读取时截断文件。