在尝试处理之前,如何validation文件是否已完成写入?

很难给我的问题一个好的标题,但它是如下。 首先,我在Windows上这样做,它可能会在Linux上使用,所以我需要修复在这两个系统上工作。 我正在监视新文件的目录。 我基本上看目录的文件,并反复比较,只处理新的文件。 问题是在我尝试处理之前,我不断收到文件没有写完的错误。

public class LiveDetectionsProvider extends DetectionsProvider { protected LiveDetectionsProvider.MonitorDirectory monitorDirectory = null; protected TimeModel timeModel = null; private ArrayList<String> loaded = new ArrayList(); private File topLayerFolder = null; public LiveDetectionsProvider(String directory, String id) { super(directory, id); timeModel = super.timeModel; } /** * Initialize the data provider. */ public void initialize() { try { topLayerFolder = new File(directory); File[] dir = topLayerFolder.listFiles(); for (File file : dir) { loaded.add(file.getName()); } monitorDirectory = new MonitorDirectory(); monitorDirectory.execute(); } catch (Exception ex) { Logger.getLogger(LiveDetectionsProvider.class.getName()).log(Level.SEVERE, "Failed to read detection\n{0}", ex.getMessage()); } super.initialize(); } /** * Un-initialize the data provider. */ public void uninitialize() { super.uninitialize(); if (monitorDirectory != null) { monitorDirectory.continuing = false; } } /** * The class that is used to load the detection points in a background * thread. */ protected class MonitorDirectory extends SwingWorker<Void, Void> { public boolean continuing = true; /** * The executor service thread pool. */ private ExecutorService executor = null; /** * The completion service that reports the completed threads. */ private CompletionService<Object> completionService = null; @Override protected Void doInBackground() throws Exception { int count = 0; executor = Executors.newFixedThreadPool(1); completionService = new ExecutorCompletionService<>(executor); while (continuing && topLayerFolder != null) { File[] dir = topLayerFolder.listFiles(); Thread.sleep(10); ArrayList<File> filesToLoad = new ArrayList(); for (File file : dir) { if (!loaded.contains(file.getName())) { long filesize = 0; boolean cont = true; while (cont) { if (file.length() == filesize) { cont = false; Thread.sleep(3); filesToLoad.add(file); } else { filesize = file.length(); Thread.sleep(3); } } Thread.sleep(3); } } for (File file : filesToLoad) { timeModel.setLoadingData(LiveDetectionsProvider.this.hashCode(), true); completionService.submit(Executors.callable(new ReadDetection(file, false))); while (completionService.take() == null) { Thread.sleep(2); } loaded.add(file.getName()); count++; Logger.getLogger(LiveDetectionsProvider.class.getName()).log(Level.SEVERE, "Detection Message Count:" + count); } detectionsModel.fireStateChanged(DetectionsModel.CHANGE_EVENT_DETECTIONS); timeModel.setLoadingData(LiveDetectionsProvider.this.hashCode(), false); } return null; } } } 

该文件是在与行处理

 completionService.submit(Executors.callable(new ReadDetection(file, false))); 

这个文件还没有写完,就失败了。 我试过睡觉我的线程减慢,我已经尝试validation文件大小没有改变。 我的testing用例是解压缩包含大量1,000 KB文件的tar文件。

Solutions Collecting From Web of "在尝试处理之前,如何validation文件是否已完成写入?"

通常我通过在写文件的时候创建一个临时文件来解决这个问题。 一旦完成,我重命名文件,只有重命名的文件可以进行处理。

使用“标志文件”:一旦file.txt“完成”,通过创建一个文件来表明这一点。消费过程应该等待.flg出现。

首先是编译看看我发布的解决方案在我的问题。 你替换

 For(File file: dir){ while(!file.renameTo(file)){ Thread.sleep(1) } // In my code I check to see if the file name is already in the list which // contains files that have been previously loaded if its not I add it to a list // of files to be processed } 

在…中

  for (File file : dir) { if (!loaded.contains(file.getName())) { long filesize = 0; boolean cont = true; while (cont) { if (file.length() == filesize) { cont = false; Thread.sleep(3); filesToLoad.add(file); } else { filesize = file.length(); Thread.sleep(3); } } Thread.sleep(3); } } 

对不起,我忘了把评论标签/ /在线说,做你需要做的每一件事。

它所做的是查看目录中的每个文件,并检查是否可以重命名它,如果重命名失败,它会睡觉,并继续检查,直到它能够重命名,在这一点上,你可以做什么,你需要与文件在我的情况下是在for循环被替换之后的所有东西。 我很好奇为什么我的awnser被视为sub par删除和锁定。 这个解决方案可以解决我的问题,并且会有其他人遇到同样的问题,试图处理一个仍然被写入或者复制到一个被监视目录的文件。