private void copyPath(File src, TachyonURI dstPath) throws IOException { try { if (!src.isDirectory()) { // If the dstPath is a directory, then it should be updated to be the path of the file where // src will be copied to TachyonFile fd = mTfs.openIfExists(dstPath); if (fd != null) { FileInfo tFile = mTfs.getInfo(fd); if (tFile.isFolder) { dstPath = dstPath.join(src.getName()); } } Closer closer = Closer.create(); FileOutStream os = null; try { os = closer.register(mTfs.getOutStream(dstPath, OutStreamOptions.defaults())); FileInputStream in = closer.register(new FileInputStream(src)); FileChannel channel = closer.register(in.getChannel()); ByteBuffer buf = ByteBuffer.allocate(8 * Constants.MB); while (channel.read(buf) != -1) { buf.flip(); os.write(buf.array(), 0, buf.limit()); } } catch (IOException e) { // Close the out stream and delete the file, so we don't have an incomplete file lying // around if (os != null) { os.cancel(); fd = mTfs.openIfExists(dstPath); if (fd != null) { mTfs.delete(fd); } } throw e; } finally { closer.close(); } } else { mTfs.mkdir(dstPath); List<String> errorMessages = Lists.newArrayList(); String[] fileList = src.list(); for (String file : fileList) { TachyonURI newPath = new TachyonURI(dstPath, new TachyonURI(file)); File srcFile = new File(src, file); try { copyPath(srcFile, newPath); } catch (IOException e) { errorMessages.add(e.getMessage()); } } if (errorMessages.size() != 0) { if (errorMessages.size() == fileList.length) { // If no files were created, then delete the directory TachyonFile f = mTfs.openIfExists(dstPath); if (f != null) { mTfs.delete(f); } } throw new IOException(Joiner.on('\n').join(errorMessages)); } } } catch (TachyonException e) { throw new IOException(e.getMessage()); } }