@Override public HttpResponseOutputStream<Void> write(final Path file, final TransferStatus status, final ConnectionCallback callback) { final FileBuffer buffer = new FileBuffer(); return new HttpResponseOutputStream<Void>(new BufferOutputStream(buffer) { @Override
@Override public synchronized int write(final byte[] chunk, final Long offset) throws IOException { final RandomAccessFile file = random(); file.seek(offset); file.write(chunk, 0, chunk.length); length = Math.max(length, file.length()); return chunk.length; }
@Override public void close() throws IOException { try { // Reset offset in transfer status because data was already streamed // through StreamCopier when writing to buffer final TransferStatus range = new TransferStatus(status).length(buffer.length()).append(false); if(0L == buffer.length()) { new GraphTouchFeature(session).touch(file, new TransferStatus()); } else { final HttpResponseOutputStream<Void> out = new GraphWriteFeature(session).write(file, range, callback); IOUtils.copy(new BufferInputStream(buffer), out); out.close(); log.info(String.format("Completed upload for %s with status %s", file, range)); } super.close(); } catch(BackgroundException e) { throw new IOException(e); } } }) {
@Override public void truncate(final Long length) { this.length = length; if(temporary.exists()) { try { final RandomAccessFile file = random(); if(length < file.length()) { // Truncate current file.setLength(length); } } catch(IOException e) { log.warn(String.format("Failure truncating file %s to %d", temporary, length)); } } }
@Override public synchronized int read(final byte[] chunk, final Long offset) throws IOException { final RandomAccessFile file = random(); if(offset < file.length()) { file.seek(offset); if(chunk.length + offset > file.length()) { return file.read(chunk, 0, (int) (file.length() - offset)); } else { return file.read(chunk, 0, chunk.length); } } else { final NullInputStream nullStream = new NullInputStream(length); if(nullStream.available() > 0) { nullStream.skip(offset); return nullStream.read(chunk, 0, chunk.length); } else { return IOUtils.EOF; } } }