package org.araqne.logdb;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import org.araqne.logdb.query.command.IoHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LocalFileMover implements FileMover {
private final Logger logger = LoggerFactory.getLogger(LocalFileMover.class);
private boolean overwrite;
public LocalFileMover() {
this(false);
}
public LocalFileMover(boolean overwrite) {
this.overwrite = overwrite;
}
@Override
public void move(String from, String to) throws IOException {
File fromFile = new File(from);
File toFile = new File(to);
if (!fromFile.exists())
throw new IOException("file not found: " + from);
if (toFile.exists()) {
if (overwrite) {
if (!toFile.delete())
throw new IOException("cannot overwrite file: " + toFile.getAbsolutePath());
} else {
throw new IOException("file already exist: " + to);
}
}
boolean moved = fromFile.renameTo(toFile);
boolean copied = false;
if (moved) {
logger.debug("araqne logdb: moved file from [{}] to [{}]", fromFile.getAbsolutePath(), toFile.getAbsolutePath());
} else {
FileInputStream fis = null;
FileOutputStream fos = null;
FileChannel fromChannel = null;
FileChannel toChannel = null;
try {
toFile.getParentFile().mkdirs();
fis = new FileInputStream(fromFile);
fos = new FileOutputStream(toFile);
fromChannel = fis.getChannel();
toChannel = fos.getChannel();
ensureTransferTo(fromChannel, toChannel, fromChannel.size());
copied = true;
} finally {
IoHelper.close(fromChannel);
IoHelper.close(toChannel);
IoHelper.close(fis);
IoHelper.close(fos);
if (copied) {
boolean deleted = fromFile.delete();
if (!deleted) {
logger.debug("araqne logdb: delete [{}] failed after copy", fromFile.getAbsolutePath());
}
}
}
}
}
private void ensureTransferTo(FileChannel srcChannel, FileChannel dstChannel, long length) throws IOException {
long copied = 0;
while (copied < length) {
copied += srcChannel.transferTo(copied, length - copied, dstChannel);
}
}
}