假设源文件夹sourcefold中随时可能有新文件加进来, 现在需要把源文件夹中的文件拷贝到目标文件夹descfold中。要求: 用两个线程来实现,一个线程监视源文件夹中是否有新加的文件,当有新文件时,用另一个线程将文件拷贝到目标文件夹中。请给个示范代码,最好能直接跑的,谢谢!
假设源文件夹sourcefold中随时可能有新文件加进来, 现在需要把源文件夹中的文件拷贝到目标文件夹descfold中。要求: 用两个线程来实现,一个线程监视源文件夹中是否有新加的文件,当有新文件时,用另一个线程将文件拷贝到目标文件夹中。请给个示范代码,最好能直接跑的,谢谢!
试试jdk1.7的新玩意吧。http://www.oschina.net/question/100896_28983有代码,有解释。 很好很强的。 就是有点长,耐心看完吧。
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();
}
}
}
}
}
}
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();
}
}
你的问题主要难度在于:“监视源文件夹中是否有新加的文件”老版本Java并不支持借助操作系统来监视文件夹,这就导致必须不断的对该文件夹进行列表查询(类似于命令行的dir),然后再比对哪些文件是新增的,这个过程可以统称为轮询。如果该目录下文件数量众多的话,光这个轮询就可能消耗大量时间。
而你的第二个需求:“用另一个线程将文件拷贝到目标文件夹”
这个倒是很容易实现,你可以用Java自带的线程池(线程数随你设置),每次有新文件就new一个Runable的任务增加到线程池中。
你干脆用Java调用Windows的命令 robocopy 算了,它支持时间戳、自动判断新旧啥的,比你自己写代码高效和安全多了