@Override
  public void close() throws IOException {
    boolean triedToClose = false, success = false;
    try {
      flush();
      ((FileOutputStream)out).getChannel().force(true);

      triedToClose = true;
      super.close();
      success = true;
    } finally {
      if (success) {
        boolean renamed = tmpFile.renameTo(origFile);
        if (!renamed) {
          // On windows, renameTo does not replace.
          if (origFile.exists()) {
            try {
              Files.delete(origFile.toPath());
            } catch (IOException e) {
              throw new IOException("Could not delete original file " + origFile, e);
            }
          }
          try {
            NativeIO.renameTo(tmpFile, origFile);
          } catch (NativeIOException e) {
            throw new IOException("Could not rename temporary file " + tmpFile
              + " to " + origFile + " due to failure in native rename. "
              + e.toString());
          }
        }
      } else {
        if (!triedToClose) {
          // If we failed when flushing, try to close it to not leak an FD
          IOUtils.closeStream(out);
        }
        // close wasn't successful, try to delete the tmp file
        if (!tmpFile.delete()) {
          LOG.warn("Unable to delete tmp file " + tmpFile);
        }
      }
    }
  }
@Test
  public void testFailToFlush() throws IOException {
    // Create a file at destination
    FileOutputStream fos = new FileOutputStream(DST_FILE);
    fos.write(TEST_STRING_2.getBytes());
    fos.close();
    
    OutputStream failingStream = createFailingStream();
    failingStream.write(TEST_STRING.getBytes());
    try {
      failingStream.close();
      fail("Close didn't throw exception");
    } catch (IOException ioe) {
      // expected
    }
    
    // Should not have touched original file
    assertEquals(TEST_STRING_2, DFSTestUtil.readFile(DST_FILE));
    
    assertEquals("Temporary file should have been cleaned up",
        DST_FILE.getName(), Joiner.on(",").join(TEST_DIR.list()));
  }