Java 并行读取windows共享目录中的文件
我有一个服务器,它从windows共享目录中读取文本文件列表,并在开始接受用户消息之前将其内容保存到db中。此服务器将同时在多台计算机上运行 我看到,当我在多台机器上运行服务器时,开始处理文件的服务器首先处理所有文件,而其他服务器一直在等待访问该目录中的文件 我的代码执行此操作-(由于安全策略,无法发布代码)Java 并行读取windows共享目录中的文件,java,windows,file,process,parallel-processing,Java,Windows,File,Process,Parallel Processing,我有一个服务器,它从windows共享目录中读取文本文件列表,并在开始接受用户消息之前将其内容保存到db中。此服务器将同时在多台计算机上运行 我看到,当我在多台机器上运行服务器时,开始处理文件的服务器首先处理所有文件,而其他服务器一直在等待访问该目录中的文件 我的代码执行此操作-(由于安全策略,无法发布代码) 获取共享目录中所有文件的列表 按修改日期排序(保存时间序列数据) While(true)直到目录中存在更多文件 获取列表中的第一个文件,并将其移动到InProges文件夹并读取 将内容保存
if(files exist on disk){
LOGGER.info("Files exist on disk. Lets process them up first....");
while (true) {
File dir = new File(directory);
List<File> fileList = new LinkedList<File>(Arrays.asList(dir.listFiles((FileFilter)FileFileFilter.FILE)));
LOGGER.info("No of files in this process: "+ sortedFileList.size());
if (fileList.size() > 0) {
Collections.sort(fileList, new Server().new FileComparator());
File file = fileList.get(0);
//If I cannot rename the file in the same directory, the file maybe open and I move to the next file
if(!file.renameTo(file.getAbsoluteFile())) {
LOGGER.info("Read next file...");
continue;
}
LOGGER.info("Get file handle...");
if (file.exists()) {
File inprogressFile = new File(dataDirName + FileBackupOnDisk.INPROGRESS + fileName);
saveToDB(inprogressFile);
if (savedToDB)
if(inprogressFile.renameTo(new File(dataDirName+ARCHIVE+fileName)))
LOGGER.info("Moved file to archive - " + fileName);
else
LOGGER.error("Move file " + fileName + " to failed directory!");
}
}
}
}
if(磁盘上存在文件){
info(“文件存在于磁盘上。让我们先处理它们…”);
while(true){
文件目录=新文件(目录);
List fileList=newlinkedlist(Arrays.asList(dir.listFiles((FileFilter)FileFilter.FILE));
LOGGER.info(“此过程中的文件数:+sortedFileList.size());
如果(fileList.size()>0){
Collections.sort(fileList,new Server().new FileComparator());
File File=fileList.get(0);
//如果我无法重命名同一目录中的文件,该文件可能会打开,我将移动到下一个文件
如果(!file.renameTo(file.getAbsoluteFile())){
info(“读取下一个文件…”);
继续;
}
info(“获取文件句柄…”);
if(file.exists()){
File inprogressFile=新文件(dataDirName+FileBackupOnDisk.INPROGRESS+fileName);
saveToDB(inprogressFile);
if(savedToDB)
if(inprogressFile.renameTo(新文件(dataDirName+ARCHIVE+fileName)))
info(“将文件移动到存档-”+文件名);
其他的
LOGGER.error(“将文件“+fileName+”移动到失败的目录!”);
}
}
}
}
这是我的文件比较器代码。无法打开文件-
final Map<File, Long> staticLastModifiedTimes = new HashMap<File,Long>();
for(final File f : sortedFileList) {
staticLastModifiedTimes.put(f, f.lastModified());
}
Collections.sort(sortedFileList, new Comparator<File>() {
@Override
public int compare(final File f1, final File f2) {
return
staticLastModifiedTimes.get(f1).compareTo(staticLastModifiedTimes.get(f2));
}
});
final Map staticLastModifiedTimes=new HashMap();
对于(最终文件f:sortedFileList){
staticLastModifiedTime.put(f,f.lastModified());
}
Collections.sort(sortedFileList,new Comparator(){
@凌驾
公共整数比较(最终文件f1,最终文件f2){
返回
staticLastModifiedTimes.get(f1).compareTo(staticLastModifiedTimes.get(f2));
}
});
如何确保在不同机器上运行的两台服务器/多台服务器都能够并行直接访问共享服务器。现在看起来像是第二个进程发现文件存在于dir中,但在等待获得文件句柄时挂起
让我知道以前是否有人这样做过,以及是如何做的?我发现我的上述解决方案工作得非常好!!!! 只是从我的eclipse运行一个实例,从网络中的m/c运行另一个实例导致了延迟问题。 如果我在同一网络中的两台机器上运行该程序,它工作正常。只是我的电脑慢了。这两个实例都会在能够处理文件时读取文件。
谢谢大家的帮助 问题是,当代码无法打开一个文件时,它会一直尝试,直到可以打开为止,当然,在文件已经被处理之前,这不会发生。代码需要跳过任何它无法打开的文件,直到找到一个它可以打开的文件。它不会超出从第二个开始的过程中的排序点。即使我注释了行
code
Collections.sort(fileList,new Server().new FileComparator())code
,之后它不会执行这些行。我可以在部件中输入code
继续code
如果file.exists()不是真的,但它永远不会越过这一点。我猜您正在FileComparator
中打开文件?无论如何,你的逻辑中一定有个bug。Windows不阻止多台计算机同时从同一目录读取文件。如果您可以确定代码中等待文件句柄的位置,这可能会有所帮助,因为此时它根本不应该尝试打开文件。(可能无论您使用什么Java API来检索修改日期,都会打开该文件?)。。。我想Java运行时在调用File.listFiles()时可能正在打开文件,但这是一个相当大的设计错误,似乎不太可能被忽略。这是我的文件比较程序代码。这不能打开文件-code
protectedclass文件比较器实现比较器{public int compare(File x,File y){try{return new Long(x.lastModified()).compareTo(new Long(y.lastModified());}catch(异常e){e.printStackTrace();}返回0;}code