private int copyPath(File src, TachyonFileSystem tachyonClient, TachyonURI dstPath) throws IOException { 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 try { TachyonFile fd = tachyonClient.open(dstPath); if (fd != null) { FileInfo tFile = tachyonClient.getInfo(fd); if (tFile.isFolder) { dstPath = dstPath.join(src.getName()); } } } catch (TachyonException e) { throw new IOException(e); } Closer closer = Closer.create(); try { FileOutStream os = closer.register(tachyonClient.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 (TachyonException e) { throw new IOException(e); } finally { closer.close(); } return 0; } else { try { tachyonClient.mkdir(dstPath); } catch (TachyonException e) { throw new IOException(e); } for (String file : src.list()) { TachyonURI newPath = new TachyonURI(dstPath, new TachyonURI(file)); File srcFile = new File(src, file); if (copyPath(srcFile, tachyonClient, newPath) == -1) { return -1; } } } return 0; }
/** Tests that reading a file consisting of more than one block from the underfs works */ @Test public void readMultiBlockFile() throws IOException, TachyonException { String uniqPath = PathUtils.uniqPath(); int blockSizeByte = 10; int numBlocks = 10; FileOutStream os = mTfs.getOutStream(new TachyonURI(uniqPath), mWriteUnderStore); for (int i = 0; i < numBlocks; i++) { for (int j = 0; j < blockSizeByte; j++) { os.write((byte) (i * blockSizeByte + j)); } } os.close(); TachyonFile f = mTfs.open(new TachyonURI(uniqPath)); FileInStream is = mTfs.getInStream(f, mReadCache); for (int i = 0; i < blockSizeByte * numBlocks; i++) { Assert.assertEquals((byte) i, is.read()); } is.close(); Assert.assertTrue(mTfs.getInfo(f).getInMemoryPercentage() == 100); }
@Override public void write(byte[] b) throws IOException { Preconditions.checkArgument(b != null, PreconditionMessage.ERR_WRITE_BUFFER_NULL); write(b, 0, b.length); }
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()); } }