假设源文件夹sourcefold中随时可能有新文件加进来, 现在需要把源文件夹中的文件拷贝到目标文件夹descfold中。要求: 用两个线程来实现,一个线程监视源文件夹中是否有新加的文件,当有新文件时,用另一个线程将文件拷贝到目标文件夹中。请给个示范代码,最好能直接跑的,谢谢!

解决方案 »

  1.   

    老的别用了。
    试试jdk1.7的新玩意吧。http://www.oschina.net/question/100896_28983有代码,有解释。 很好很强的。 就是有点长,耐心看完吧。
      

  2.   

    谢谢楼上. 但我还是想用老的, 继承thread或实现runnable的, 因为是老的系统.能不能给个老的例子?
      

  3.   


    package testNew;import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;public class Test {
    public final static Map<String,String> fileMap = new HashMap<String,String>();
    public final static String readFileName = "D:" + File.separator + "hello";
    public final static String writeFileName = "D:" + File.separator + "back";
        public static void main(String[] args) {
         ReadThread read = new ReadThread();
         WriteThread write = new WriteThread();
         read.start();
         write.start();
        }
        /**
         *返回目录下文件 
         */
        public static List<String> printfFile(String fileName){
    File file = new File(fileName);
    String[] fileList  = file.list();//获得该目录下所有文件的名字,包含隐藏文件
    for(String s : fileList){
    System.out.println(s);
    }
    return Arrays.asList(fileList);
    }
        /**
         *拷贝文件 
         */
        public static void copyFile(String fileName,String fileName1) throws IOException {
    File file = new File(fileName);
    File file1 = new File(fileName1);
    FileInputStream fileStream = new FileInputStream(file);
    FileOutputStream fileOutStream = new FileOutputStream(file1);
    byte[] byteArray = new byte[1024];
    int temp = 0;
    while((temp = fileStream.read(byteArray))!=-1){
    fileOutStream.write(byteArray, 0, temp);
    }
    fileStream.read(byteArray);
    fileStream.close();
    fileOutStream.close();
    }
        

    class ReadThread extends Thread{

    public void run() {
    while(true){
    List<String> readList = Test.printfFile(Test.readFileName);
    for(String str : readList){
    if(Test.fileMap.containsKey(str)){
    continue;
    } else
    Test.fileMap.put(str, str);
    }
    try {
    Thread.sleep(5000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }

    }
    class WriteThread extends Thread{

    public void run() {
    while(true){
    try {
    Thread.sleep(5000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    List<String> writeList =Test.printfFile(Test.writeFileName);
    for(Iterator it = Test.fileMap.keySet().iterator();it.hasNext();){
    String  key = (String)it.next();
    boolean flag = false;
    for(String str : writeList){
    if(str.equalsIgnoreCase(key)){
    flag = true;
    break;
    }
    }
    if(!flag){
    try {
    Test.copyFile(Test.readFileName + File.separator + key,Test.writeFileName + File.separator + key);
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
    }
    }
    }
      

  4.   

    基本逻辑是这样的,楼主发现问题,或者可以根据自己需求自己改一改。import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.util.HashSet;
    import java.util.Set;public class FilesListener implements Runnable{ private String fileDir = "d://from";
    private String newFileDir = "d://to";
    private Set<String> oldFiles = new HashSet<String>();

    public FilesListener(){
    File[] files = new File(fileDir).listFiles();
    if(files != null){
    for(File file : files){
    oldFiles.add(file.getName());
    }
    }
    }

    private Set<String> checkNewFiles(){
    Set<String> nowFiles = new HashSet<String>();
    File[] files = new File(fileDir).listFiles();
    if(files != null){
    for(File file : files){
    nowFiles.add(file.getName());
    }
    }

    if(nowFiles.size() > oldFiles.size()){
    Set<String> addFiles = new HashSet<String>();
    addFiles.addAll(nowFiles);
    addFiles.removeAll(oldFiles);

    oldFiles.addAll(addFiles);
    return addFiles;
    }
    return null;
    }

    private void copyFiles(Set<String> addFiles) {

    for (String file : addFiles) {
    try {
    String oldFileName = fileDir + "//" + file;
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(oldFileName));
    String newFileName = newFileDir + "//" + file;
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newFileName));
    byte[] buf = new byte[1024];
    int read = -1;
    while((read = bis.read(buf)) > 0){
    bos.write(buf,0,read);
    } bos.close();
    bis.close();
    System.out.println("复制文件:" + file);
    }
    catch (Exception e) {
    e.printStackTrace();
    }
    } }

    public void run() {
    Set<String> addFiles = checkNewFiles();
    if (addFiles != null) {
    copyFiles(addFiles);
    }
    try {
    Thread.sleep(3000);
    run();
    }
    catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    public static void main(String[] args) {
    FilesListener fl = new FilesListener();
            new Thread(fl).start();
    }
    }
      

  5.   

    楼主这里要求的监听线程,可以一直跑,sleep时间也可以适当放长一点,不一定要几秒。复制文件的线程不用一直跑,监听线程发现有新文件了再去创始一个线程就行了。复制文件线程一直跑着也没有必要。
      

  6.   


    你的问题主要难度在于:“监视源文件夹中是否有新加的文件”老版本Java并不支持借助操作系统来监视文件夹,这就导致必须不断的对该文件夹进行列表查询(类似于命令行的dir),然后再比对哪些文件是新增的,这个过程可以统称为轮询。如果该目录下文件数量众多的话,光这个轮询就可能消耗大量时间。
    而你的第二个需求:“用另一个线程将文件拷贝到目标文件夹”
    这个倒是很容易实现,你可以用Java自带的线程池(线程数随你设置),每次有新文件就new一个Runable的任务增加到线程池中。
    你干脆用Java调用Windows的命令 robocopy 算了,它支持时间戳、自动判断新旧啥的,比你自己写代码高效和安全多了