code: private void detachFile(int namespaceId, File file, Block b) throws IOException {
      File tmpFile = blockDataFile.volume.createDetachFile(namespaceId, b, file.getName());
      try {
        IOUtils.copyBytes(new FileInputStream(file),
                          new FileOutputStream(tmpFile),
                          16*1024, true);
        if (file.length() != tmpFile.length()) {
          throw new IOException("Copy of file " + file + " size " + file.length()+
                                " into file " + tmpFile +
                                " resulted in a size of " + tmpFile.length());
        }
        FileUtil.replaceFile(tmpFile, file);
      } catch (IOException e) {
        boolean done = tmpFile.delete();
        if (!done) {
          DataNode.LOG.info("detachFile failed to delete temporary file " +
                            tmpFile);
        }
        throw e;
      }
    }
docs: Copy specified file into a temporary file. Then rename the
  temporary file to the original name. This will cause any
  hardlinks to the original file to be removed. The temporary
  files are created in the detachDir. The temporary files will
  be recovered (especially on Windows) on datanode restart.