Guava的Files.move()会移动文件或复制文件

时间:2017-06-20 20:54:12

标签: java multithreading file guava

我必须将大量文件(每个大约60 MB)从文件夹A移动到文件夹B.文件夹B是用于Spring计划任务的i / p文件夹。它选择这些文件并开始并行处理。我正在使用Guava的文件实用程序方法来移动文件。

Files.move(sourceFile,targetFile,Charsets.UTF_8);

我在TaskScheduler类中看到错误,该文件不在那里阅读

  

at org.apache.commons.io.FileUtils.openInputStream(FileUtils.java:299)〜[commons-io-2.4.jar:2.4]   在org.apache.commons.io.FileUtils.lineIterator(FileUtils.java:1856)〜[commons-io-2.4.jar:2.4]   在com.varun.processor.readFile(Processor.java:342)〜[classes /:?]

我的预感是文件处于复制状态,因此Spring预定的线程无法获取锁定来读取它。根据Guava的文档,它说它的移动方法在unix上的行为类似于mv命令但我看到代码作为番石榴罐中的副本。

enter image description here

任何人都可以建议更好的方法从spring app移动unix系统上的文件o / p目录是另一个下游进程的i / p。

1 个答案:

答案 0 :(得分:0)

使用Guava移动文件工作正常。你必须继续尝试阅读文件,直到成功为止。

我测试了移动大小为525 MB的文件,Guava在不到1秒的时间内移动了它。

请参阅下面的示例(我在移动文件之前故意添加了延迟,因此文件处理器将尝试在移动文件之前和之后打开文件):

import com.google.common.io.ByteSource;
import com.google.common.io.Files;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;


/**
 * <dependency>
 * <groupId>com.google.guava</groupId>
 * <artifactId>guava</artifactId>
 * <version>22.0</version>
 * </dependency>
 */
public class GuavaFileMoveExample {

    private static final Logger LOGGER = Logger.getLogger("GuavaFileMoveExample");

    public static void main(String[] args) throws IOException, InterruptedException {
        GuavaFileMoveExample a = new GuavaFileMoveExample();
        a.doTheWork();
    }

    private void doTheWork() throws InterruptedException {

        ExecutorService executorService = Executors.newFixedThreadPool(2);
        executorService.submit(new FileMover());
        executorService.submit(new FileProcessor());
        executorService.shutdown();
        executorService.awaitTermination(10, TimeUnit.SECONDS);


    }
}

class FileMover implements Callable<Void> {

    private static final Logger LOGGER = Logger.getLogger("FileMover");

    @Override
    public Void call() throws Exception {
        Thread.sleep(1000);
        moveFile();
        return null;
    }

    private void moveFile() {
        final File sourceFile = new File("/tmp/origin/ideaIU-2016.3-no-jdk.tar.gz");
        final File targetFile = new File("/tmp/destination/ideaIU-2016.3-no-jdk.tar.gz");

        try {
            LOGGER.log(Level.INFO, "started moving file");
            Files.move(sourceFile, targetFile);
            LOGGER.log(Level.INFO, "finished moving file");
        } catch (IOException e) {
            LOGGER.log(Level.WARNING, "ioexception while moving file ", e);
        }

    }
}

class FileProcessor implements Callable<Void> {

    private static final Logger LOGGER = Logger.getLogger("FileProcessor");

    @Override
    public Void call() throws Exception {
        readBinaryFile("/tmp/destination/ideaIU-2016.3-no-jdk.tar.gz");

        return null;
    }

    private byte[] readBinaryFile(String aFileName) {
        File file = new File(aFileName);
        ByteSource source = Files.asByteSource(file);


        byte[] result = null;
        while (result == null) {
            try {
                LOGGER.log(Level.INFO, "started reading file");
                result = source.read();
                LOGGER.log(Level.INFO, "finished reading file. size: " + result.length);
            } catch (FileNotFoundException e) {
                // expected if file is not yet at destination
            } catch (IOException e) {
                LOGGER.log(Level.SEVERE, "error reading file", e);
                break;
            }
        }

        return result;
    }
}