如何从线程只写入一次文件?

Posted

技术标签:

【中文标题】如何从线程只写入一次文件?【英文标题】:How to write only once to file from a thread? 【发布时间】:2015-08-26 03:06:56 【问题描述】:

我想在每次修改文件时在文件末尾写一些东西,我正在使用这段代码:

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); 上变得疯狂

【问题讨论】:

听起来您正在监视文件的更改,当检测到更改时,您将某些内容写入文件末尾,这会导致检测到更改,因此您将某些内容写入文件末尾文件,这会导致检测到更改,因此您在文件末尾写入一些内容,这会导致检测到更改... 如果我正确理解您的要求,如果您只想在更新发生后将数据附加到文件一次,我认为您必须禁用文件观察程序。否则,您的代码会引发 FIleWatcher 捕获的更改,这就是它“疯狂”的原因。 ...与此同时,这些更改可能会与其他线程写入文件的内容交错,除非您对它们进行了独占锁定。 【参考方案1】:

您的线程的写入导致对文件的进一步更改。 自喂循环。

【讨论】:

以上是关于如何从线程只写入一次文件?的主要内容,如果未能解决你的问题,请参考以下文章

使用多线程下载文件思路

在python中使用线程时如何保留文件写入顺序

python如何让程序每天只运行一次

为多个消费者读取一次流

如何在多线程环境中只执行一次代码块?

一次写入一个值