Трудно дать хороший заголовок моей проблеме, но это так. Сначала я делаю это на окнах, и его можно использовать и в ящике 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)));
Файл на этом этапе еще не закончил писать и, таким образом, не работает. Я пробовал спящий мой поток, чтобы замедлить его, и я попытался проверить размер файла, который не изменился. Мой тестовый пример: я разархивирую tar файл, содержащий тысячи файлов размером 1000 КБ.
Сначала да, компилирует, посмотри решение, которое я разместил по отношению к коду. В моем вопросе. Вы заменяете
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
}
in для
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.txt укажите это, создав файл .flg - процесс потребления должен ждать появления .flg.