2015-06-10 58 views
6

我想每一次寫東西到文件末尾的文件被修改,我使用此代碼:如何只從一個線程寫入一次文件?

public class Main { 

    public static final String DIRECTORY_TO_WATCH = "D:\\test"; 

    public static void main(String[] args) { 
     Path toWatch = Paths.get(DIRECTORY_TO_WATCH); 
     if (toWatch == null) { 
      throw new UnsupportedOperationException(); 
     } 
     try { 
      WatchService myWatcher = toWatch.getFileSystem().newWatchService(); 
      FileWatcher fileWatcher = new FileWatcher(myWatcher); 
      Thread t = new Thread(fileWatcher, "FileWatcher"); 
      t.start(); 
      toWatch.register(myWatcher, StandardWatchEventKinds.ENTRY_MODIFY); 
      t.join(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

    } 
} 

和線程類:

public class FileWatcher implements Runnable{ 
    private WatchService myWatcher; 
    private Path toWatch; 
    String content = "Dong\n"; 
    int counter = 0; 

    public FileWatcher (WatchService myWatcher, Path toWatch) { 
    this.myWatcher = myWatcher; 
    this.toWatch = toWatch; 
} 
    @Override 
    public void run() { 
     try { 
      WatchKey key = myWatcher.take(); 
      while (key != null) { 
       for (WatchEvent event : key.pollEvents()) { 
        //System.out.printf("Received %s event for file: %s\n", event.kind(), event.context()); 
        //System.out.println(counter); 
        myWatcher = null; 
        File file = new File(Main.DIRECTORY_TO_WATCH + "\\" + event.context()); 
        FileWriter fw = new FileWriter(file.getAbsoluteFile(), true); 
        fw.write(counter + content); 
        fw.close(); 
        counter++; 
        myWatcher = toWatch.getFileSystem().newWatchService(); 
        toWatch.register(myWatcher, StandardWatchEventKinds.ENTRY_MODIFY); 
//     BufferedWriter bwWriter = new BufferedWriter(fw); 
//     bwWriter.write(content); 
//     bwWriter.close(); 
       } 
       key.reset(); 
       key = myWatcher.take(); 
      } 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

    } 

} 

我想在文件是這樣的:

acasc 0dong 
dwqcacesv 1dong 
terert 2dong 

不過,現在我得到這個,因爲它在文件中寫入次數過多:

acasc 0dong 
1dong 
... 
50123dong 

如果我使用System.out.println(counter);它的作品,因爲我想(打印的文件更改正確的數量),但它在fw.write(counter + content);

+16

聽起來好像你正在監視一個文件的變化,當檢測到變化時,你在文件末尾寫了一些東西,這會導致檢測到變化,所以你在文件末尾寫了一些東西,這會導致變化被檢測到,所以你寫的東西到文件的末尾,這會導致檢測到的變化... –

+1

我想你必須禁用文件觀察器,如果你想在數據更新發生後只附加數據到文件一次,如果我正確理解你的要求。否則,您的代碼會引發FIleWatcher捕獲的更改,這就是爲什麼它正在「瘋狂......」 –

+0

...並且與此同時,這些更改可能會與其他線程寫入文件的內容交錯,除非您擁有獨家鎖定他們。 – biziclop

回答

0

你的線程寫去野外是造成該文件進一步修改。 自動循環。