如何停止java正在上传的文件_如何在java中实现可停止和可取消的文件夹同步?...

我有两个目录结构,需要将它们同步,即将源文件夹中新增或更改的文件和文件夹复制到目标文件夹中,并删除源中不存在的目标文件和文件夹。然而,这个过程需要有一个“取消”按钮,这将停止执行并回滚所有的更改。我四处搜索,发现了这个代码,但我对它的实际工作原理的理解充其量是朦胧的。如何在java中实现可停止和可取消的文件夹同步?

//$Id: FileHelper.java 15522 2008-11-05 20:06:43Z hardy.ferentschik $

//Revised from hibernate search util

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.nio.channels.FileChannel;

import java.util.Arrays;

import java.util.HashSet;

import java.util.Set;

/**

* Utility class for synchronizing files/directories.

*

* @author Emmanuel Bernard

* @author Sanne Grinovero

* @author Hardy Ferentschik

*/

public abstract class FileHelper {

private static final int FAT_PRECISION = 2000;

public static final long DEFAULT_COPY_BUFFER_SIZE = 16 * 1024 * 1024; // 16 MB

public static boolean areInSync(File source, File destination) throws IOException {

if (source.isDirectory()) {

if (!destination.exists()) {

return false;

}

else if (!destination.isDirectory()) {

throw new IOException(

"Source and Destination not of the same type:"

+ source.getCanonicalPath() + " , " + destination.getCanonicalPath()

);

}

String[] sources = source.list();

Set srcNames = new HashSet(Arrays.asList(sources));

String[] dests = destination.list();

// check for files in destination and not in source

for (String fileName : dests) {

if (!srcNames.contains(fileName)) {

return false;

}

}

boolean inSync = true;

for (String fileName : sources) {

File srcFile = new File(source, fileName);

File destFile = new File(destination, fileName);

if (!areInSync(srcFile, destFile)) {

inSync = false;

break;

}

}

return inSync;

}

else {

if (destination.exists() && destination.isFile()) {

long sts = source.lastModified()/FAT_PRECISION;

long dts = destination.lastModified()/FAT_PRECISION;

return sts == dts;

}

else {

return false;

}

}

}

public static void synchronize(File source, File destination, boolean smart) throws IOException {

synchronize(source, destination, smart, DEFAULT_COPY_BUFFER_SIZE);

}

public static void synchronize(File source, File destination, boolean smart, long chunkSize) throws IOException {

if (chunkSize <= 0) {

System.out.println("Chunk size must be positive: using default value.");

chunkSize = DEFAULT_COPY_BUFFER_SIZE;

}

if (source.isDirectory()) {

if (!destination.exists()) {

if (!destination.mkdirs()) {

throw new IOException("Could not create path " + destination);

}

}

else if (!destination.isDirectory()) {

throw new IOException(

"Source and Destination not of the same type:"

+ source.getCanonicalPath() + " , " + destination.getCanonicalPath()

);

}

String[] sources = source.list();

Set srcNames = new HashSet(Arrays.asList(sources));

String[] dests = destination.list();

//delete files not present in source

for (String fileName : dests) {

if (!srcNames.contains(fileName)) {

delete(new File(destination, fileName));

}

}

//copy each file from source

for (String fileName : sources) {

File srcFile = new File(source, fileName);

File destFile = new File(destination, fileName);

synchronize(srcFile, destFile, smart, chunkSize);

}

}

else {

if (destination.exists() && destination.isDirectory()) {

delete(destination);

}

if (destination.exists()) {

long sts = source.lastModified()/FAT_PRECISION;

long dts = destination.lastModified()/FAT_PRECISION;

//do not copy if smart and same timestamp and same length

if (!smart || sts == 0 || sts != dts || source.length() != destination.length()) {

copyFile(source, destination, chunkSize);

}

}

else {

copyFile(source, destination, chunkSize);

}

}

}

private static void copyFile(File srcFile, File destFile, long chunkSize) throws IOException {

FileInputStream is = null;

FileOutputStream os = null;

try {

is = new FileInputStream(srcFile);

FileChannel iChannel = is.getChannel();

os = new FileOutputStream(destFile, false);

FileChannel oChannel = os.getChannel();

long doneBytes = 0L;

long todoBytes = srcFile.length();

while (todoBytes != 0L) {

long iterationBytes = Math.min(todoBytes, chunkSize);

long transferredLength = oChannel.transferFrom(iChannel, doneBytes, iterationBytes);

if (iterationBytes != transferredLength) {

throw new IOException(

"Error during file transfer: expected "

+ iterationBytes + " bytes, only " + transferredLength + " bytes copied."

);

}

doneBytes += transferredLength;

todoBytes -= transferredLength;

}

}

finally {

if (is != null) {

is.close();

}

if (os != null) {

os.close();

}

}

boolean successTimestampOp = destFile.setLastModified(srcFile.lastModified());

if (!successTimestampOp) {

System.out.println("Could not change timestamp for {}. Index synchronization may be slow. " + destFile);

}

}

public static void delete(File file) {

if (file.isDirectory()) {

for (File subFile : file.listFiles()) {

delete(subFile);

}

}

if (file.exists()) {

if (!file.delete()) {

System.out.println("Could not delete {}" + file);

}

}

}

}

代码功能为标榜,但我不能确定的是:

我将如何实现取消?我能想到的最好的方法是引入一个synchronizationCancelled布尔变量,在按下取消按钮时将设置为true,并将synchronized()与检查相关联,如果检测结果为false,则会停止执行。

我该如何实现回滚?我可以想到的最好的办法是将更改/删除/新文件复制到一边,然后在取消后将它们复制回原来的位置。

都是我的猜测实际上做了正确的方式,还有一些注意事项给那些我不知道的,还是应该取消和回退可以在这种情况下完全不同实现的?

2016-01-14

Sargon1

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值