Header Ads Widget

Responsive Advertisement

File monitoring if have any changes reloaded the file





Monitoring a file for changes during runtime in Java can be accomplished by using the WatchService API, which is part of the java.nio.file package. This API allows you to watch for changes in a directory, such as file modifications, deletions, or creations.

Here is an example of how to use WatchService to monitor a file for changes:

Step-by-Step Implementation

  1. Setup the WatchService: Create a WatchService and register the directory containing the file you want to monitor.
  2. Monitor for Changes: Continuously monitor the directory for events such as file modification, creation, or deletion.
  3. Handle the Event: Once an event is detected, check if it pertains to the file you're interested in.

Example Code

java

import java.io.IOException;

import java.nio.file.*;

import static java.nio.file.StandardWatchEventKinds.*;

 

public class FileMonitor {

 

    public static void main(String[] args) {

        // Path of the directory containing the file to monitor

        Path path = Paths.get("path/to/your/directory");

 

        // File name to monitor

        String fileName = "file-to-monitor.txt";

 

        try {

            WatchService watchService = FileSystems.getDefault().newWatchService();

            path.register(watchService, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);

 

            System.out.println("Monitoring the directory for changes...");

 

            while (true) {

                WatchKey key;

                try {

                    key = watchService.take(); // Wait for an event

                } catch (InterruptedException ex) {

                    return;

                }

 

                for (WatchEvent<?> event : key.pollEvents()) {

                    WatchEvent.Kind<?> kind = event.kind();

 

                    // The filename is the context of the event.

                    WatchEvent<Path> ev = (WatchEvent<Path>) event;

                    Path filePath = ev.context();

 

                    // Check if the event is related to our specific file

                    if (filePath.toString().equals(fileName)) {

                        System.out.println("Event detected: " + kind + " on file " + filePath);

                        if (kind == ENTRY_MODIFY) {

                            System.out.println("The file " + filePath + " has been modified.");

                        } else if (kind == ENTRY_CREATE) {

                            System.out.println("The file " + filePath + " has been created.");

                        } else if (kind == ENTRY_DELETE) {

                            System.out.println("The file " + filePath + " has been deleted.");

                        }

                    }

                }

 

                // Reset the key -- this step is critical to receive further watch events.

                boolean valid = key.reset();

                if (!valid) {

                    break;

                }

            }

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

}

 

 

How It Works

Ø  WatchService: This is the key class used to monitor file system changes.

Ø  Path: Represents the path to the directory where the file resides.

Ø  register: Registers the directory with the WatchService to listen for specific types of events (creation, deletion, modification).

Ø  while (true): Keeps the application running, continuously monitoring for changes.

Ø  pollEvents: Retrieves and processes all pending events for the WatchKey.

Notes

  1. Directory Monitoring: The WatchService monitors the directory, not individual files. However, by checking the filename in the event, you can monitor specific files.
  2. Resetting the WatchKey: After processing the events, it's crucial to reset the WatchKey so that it can receive further events.
  3. Performance: This solution is efficient for monitoring directories or a small number of files. For large directories or multiple files, consider optimizing the code.

This approach should work well for monitoring file changes in real-time during the runtime of your Java application.



Approach 2 using Thread

 

If you want to monitor a file for changes using only Java threads (without relying on the WatchService API), you can manually check the file's last modified timestamp at regular intervals in a separate thread. This approach is simpler but less efficient and flexible compared to using WatchService.

Here’s how you can implement this:

Example Code

java

import java.io.File;

 

public class FileMonitorThread {

   

    private static class FileWatcher implements Runnable {

        private final File file;

        private long lastModifiedTime;

 

        public FileWatcher(String filePath) {

            this.file = new File(filePath);

            if (file.exists()) {

                this.lastModifiedTime = file.lastModified();

            } else {

                System.out.println("File does not exist initially.");

                this.lastModifiedTime = 0;

            }

        }

 

        @Override

        public void run() {

            while (!Thread.currentThread().isInterrupted()) {

                if (file.exists()) {

                    long currentModifiedTime = file.lastModified();

                    if (currentModifiedTime != lastModifiedTime) {

                        lastModifiedTime = currentModifiedTime;

                        System.out.println("The file " + file.getName() + " has been modified at " + lastModifiedTime);

                    }

                } else {

                    System.out.println("File has been deleted or does not exist.");

                    break;

                }

 

                try {

                    Thread.sleep(1000); // Check every second

                } catch (InterruptedException e) {

                    System.out.println("File monitoring thread interrupted.");

                    Thread.currentThread().interrupt();

                }

            }

        }

    }

 

    public static void main(String[] args) {

        // File path to monitor

        String filePath = "path/to/your/file.txt";

 

        // Create and start the file monitoring thread

        Thread fileWatcherThread = new Thread(new FileWatcher(filePath));

        fileWatcherThread.start();

 

        // Main program logic continues here...

        System.out.println("Main program is running...");

 

        // Simulate doing something else in the main thread

        try {

            Thread.sleep(10000); // Main thread sleeps for 10 seconds

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

 

        // If you want to stop the monitoring, interrupt the thread

        fileWatcherThread.interrupt();

        System.out.println("Main program has finished.");

    }

}

 

Explanation

  1. FileWatcher Class:

ü  The FileWatcher class implements Runnable and is responsible for monitoring a specific file.

ü  It keeps track of the last modified time of the file (lastModifiedTime).

ü  In the run method, it checks if the file's lastModified timestamp has changed compared to the stored lastModifiedTime.

  1. Thread Creation:

ü  In the main method, an instance of FileWatcher is created with the path to the file you want to monitor.

ü  A new Thread is created with this FileWatcher as its task and then started using fileWatcherThread.start().

  1. Checking for Changes:

ü  The thread repeatedly checks the file's last modified time every second (using Thread.sleep(1000)).

ü  If a change is detected, it updates the stored timestamp and prints a message indicating that the file has been modified.

  1. Handling File Deletion:

ü  The code checks if the file exists. If it doesn't, the thread prints a message and stops monitoring.

  1. Interrupting the Thread:

ü  You can interrupt the monitoring thread from the main thread using fileWatcherThread.interrupt() to stop it when necessary.

Usage Notes

Ø  Polling Interval: The polling interval (1 second in this example) can be adjusted depending on how frequently you want to check for file changes. A shorter interval checks more frequently but uses more resources.

Ø  Performance: This method is not as efficient as using WatchService, especially if you need to monitor multiple files or directories. It continuously polls the file system, which can be resource-intensive.

Ø  Thread Safety: If you are dealing with multiple threads accessing the file, you may need to ensure thread safety depending on your application's requirements.

This approach is simple and works well for small-scale scenarios where you only need to monitor one or a few files and where the inefficiencies of polling are acceptable.

 




Real Life Example using thread:

 

First Download some jar file

com.fasterxml.jackson.databind.jar

jackson-annotations-2.1.2.jar

jackson-core-2.8.1.jar

 

 

java

MongoCluster

package com.kartik.beans;

 

import java.util.List;

 

public class MongoCluster {

 

 private List<ClusterNode> cluster;

 private String dbName;

 private String dbType;

 private List<Long> cobrand;

 

 /**

  * @return the cluster

  */

 public List<ClusterNode> getCluster() {

  return cluster;

 }

 

 /**

  * @param cluster

  *            the cluster to set

  */

 public void setCluster(List<ClusterNode> cluster) {

  this.cluster = cluster;

 }

 

 /**

  * @return the dbName

  */

 public String getDbName() {

  return dbName;

 }

 

 /**

  * @param dbName

  *            the dbName to set

  */

 public void setDbName(String dbName) {

  this.dbName = dbName;

 }

 

 /**

  * @return the dbType

  */

 public String getDbType() {

  return dbType;

 }

 

 /**

  * @param dbType

  *            the dbType to set

  */

 public void setDbType(String dbType) {

  this.dbType = dbType;

 }

 

 /**

  * @return the cobrand

  */

 public List<Long> getCobrand() {

  return cobrand;

 }

 

 /**

  * @param cobrand

  *            the cobrand to set

  */

 public void setCobrand(List<Long> cobrand) {

  this.cobrand = cobrand;

 }

 

 /*

  * (non-Javadoc)

  *

  * @see java.lang.Object#toString()

  */

 @Override

 public String toString() {

  return "MongoCluster [cluster=" + cluster + ", dbName=" + dbName

    + ", dbType=" + dbType + ", cobrand=" + cobrand + "]";

 }

 

 /*

  * (non-Javadoc)

  *

  * @see java.lang.Object#hashCode()

  */

 @Override

 public int hashCode() {

  final int prime = 31;

  int result = 1;

  result = prime * result + ((cluster == null) ? 0 : cluster.hashCode());

  result = prime * result + ((cobrand == null) ? 0 : cobrand.hashCode());

  result = prime * result + ((dbName == null) ? 0 : dbName.hashCode());

  result = prime * result + ((dbType == null) ? 0 : dbType.hashCode());

  return result;

 }

 

 /*

  * (non-Javadoc)

  *

  * @see java.lang.Object#equals(java.lang.Object)

  */

 @Override

 public boolean equals(Object obj) {

  if (this == obj)

   return true;

  if (obj == null)

   return false;

  if (getClass() != obj.getClass())

   return false;

  MongoCluster other = (MongoCluster) obj;

  if (cluster == null) {

   if (other.cluster != null)

    return false;

  } else if (!cluster.equals(other.cluster))

   return false;

  if (cobrand == null) {

   if (other.cobrand != null)

    return false;

  } else if (!cobrand.equals(other.cobrand))

   return false;

  if (dbName == null) {

   if (other.dbName != null)

    return false;

  } else if (!dbName.equals(other.dbName))

   return false;

  if (dbType == null) {

   if (other.dbType != null)

    return false;

  } else if (!dbType.equals(other.dbType))

   return false;

  return true;

 }

 

}

 

java

package com.kartik.beans;

 

import java.util.List;

 

public class MongoPool {

 private List<MongoCluster> databases;

 

 /**

  * @return the databases

  */

 public List<MongoCluster> getDatabases() {

  return databases;

 }

 

 /**

  * @param databases

  *            the databases to set

  */

 public void setDatabases(List<MongoCluster> databases) {

  this.databases = databases;

 }

 

 /*

  * (non-Javadoc)

  *

  * @see java.lang.Object#toString()

  */

 @Override

 public String toString() {

  return "MongoPool [databases=" + databases + "]";

 }

 

 /*

  * (non-Javadoc)

  *

  * @see java.lang.Object#hashCode()

  */

 @Override

 public int hashCode() {

  final int prime = 31;

  int result = 1;

  result = prime * result

    + ((databases == null) ? 0 : databases.hashCode());

  return result;

 }

 

 /*

  * (non-Javadoc)

  *

  * @see java.lang.Object#equals(java.lang.Object)

  */

 @Override

 public boolean equals(Object obj) {

  if (this == obj)

   return true;

  if (obj == null)

   return false;

  if (getClass() != obj.getClass())

   return false;

  MongoPool other = (MongoPool) obj;

  if (databases == null) {

   if (other.databases != null)

    return false;

  } else if (!databases.equals(other.databases))

   return false;

  return true;

 }

}

 

java

package com.kartik.file.iread;

 

import java.io.File;

 

import com.kartik.beans.MongoPool;

 

public interface IFileRead {

 MongoPool jsonToObject(File fileName);

 MongoPool fileMonitor();

}

 

java

package com.kartik.file.iread.impl;

 

import java.io.File;

import java.io.IOException;

import java.util.ArrayList;

import java.util.List;

 

import com.fasterxml.jackson.core.JsonGenerationException;

import com.fasterxml.jackson.databind.JsonMappingException;

import com.fasterxml.jackson.databind.ObjectMapper;

import com.kartik.beans.ClusterNode;

import com.kartik.beans.MongoCluster;

import com.kartik.beans.MongoPool;

import com.kartik.file.iread.IFileRead;

 

public class IFileReadImpl implements IFileRead{

 @Override

 public MongoPool jsonToObject(File fileName) {

  ObjectMapper mapper = new ObjectMapper();

  try {

   MongoPool mm=createDummyObject();

   String jsonInString = mapper.writeValueAsString(mm);

   System.out.println(jsonInString);

   MongoPool mapObject = mapper.readValue(fileName, MongoPool.class);

  

   /*List<MongoPool> mapObject = mapper.readValue(fileName,

     new TypeReference<ArrayList<MongoPool>>() {

     });*/

   System.out.println("Java object created from JSON String :");

   //Convert Map to JSON

           String json = mapper.writeValueAsString(mapObject);

            //Print JSON output

            System.out.println(json);

            return mapObject;

   

  } catch (JsonGenerationException ex) {

   ex.printStackTrace();

  } catch (JsonMappingException ex) {

   ex.printStackTrace();

  } catch (IOException ex) {

   ex.printStackTrace();

  }

  return null;

 }

 

 /*@Override

 public boolean fileMonitor() {

  // Create the monitor

  FileMonitor monitor = new FileMonitor(1000);

  // Add some files to listen for

  monitor.addFile(new File("d:\\book.txt"));

  // monitor.addFile(new File("d:\\cobrand.txt"));

  // Add a dummy listener

  return monitor.addListener(monitor.new TestListener());

 

  // Avoid program exit

  //while (!false);

 }*/

 @Override

 public MongoPool fileMonitor() {

  File fileName =new File("d:\\book.txt");

  return jsonToObject(fileName);

 }

 

 private MongoPool createDummyObject() {

  List<MongoCluster> mn=new ArrayList<MongoCluster>();

  MongoPool mmm=new MongoPool();

  MongoCluster staff = new MongoCluster();

  List<ClusterNode> ll=new ArrayList<ClusterNode>();

  ClusterNode cl=new ClusterNode();

  cl.setHost("localhost");

  cl.setPort(7373);

  ll.add(cl);

  ClusterNode cll=new ClusterNode();

  cll.setHost("123.02.10.22");

  cll.setPort(7373);

  ll.add(cll);

  staff.setDbName("accdb");

  staff.setCluster(ll);

  staff.setDbType("oltp");

  List<Long> abc=new ArrayList<Long>();

  abc.add(12345L);

  abc.add(5342L);

  staff.setCobrand(abc);

  mn.add(staff);

  mmm.setDatabases(mn);

  return mmm;

 

 }

}

 

 

Java

package com.kartik.file.monitor;

 

import java.io.File;

 

public interface FileChangeListener {

 /**

    * Invoked when a file changes.

    *

    * @param fileName

    *          name of changed file.

    */

   public boolean fileChanged(File file);

}

 

Java

package com.kartik.file.monitor;

 

import java.io.File;

import java.io.IOException;

import java.util.HashMap;

 

 

import com.kartik.beans.MongoPool;

import com.kartik.file.iread.impl.IFileReadImpl;

 

public class FileMonitor implements Runnable{

 private static final long SLEEP_TIME = 1000l;//one second

 private HashMap<File, Long> filesMap;

 public static MongoPool map = null;

 @Override

 public void run() {

  final String fileName = "d:\\book.txt";

  while(true){  

   try {

    long currentModifiedTime = checkForModification(fileName);

    File file=new File(fileName);

    long lastModifiedTime =0l;

    if(filesMap==null){

      filesMap =new  HashMap<File, Long>();

    }else{

     lastModifiedTime = ((Long) filesMap.get(file)).longValue();

    }

    if (currentModifiedTime != lastModifiedTime){

     IFileReadImpl im=new IFileReadImpl();

     map=im.fileMonitor();

     filesMap.put(file, new Long(currentModifiedTime));

    

    }

    Thread.sleep(SLEEP_TIME);

   } catch (InterruptedException ignore) {

   

   } catch (IOException e) {

    throw new FileMonitorException("Scanfile Error", e);   

   }

  } 

 }

 

 private long checkForModification(String fileName) throws IOException{

  File scanFile = new File(fileName);

  if (!scanFile.exists()){

   scanFile.createNewFile();

   return 0l;

  } else if (!scanFile.canRead()){

   throw new FileMonitorException("Scan file can not be read.");

  } else if (!scanFile.isFile()){

   throw new FileMonitorException("Invalid scan file.");

  } else {

   return scanFile.lastModified();

  }

 }

 

public FileMonitor(){

 

}

 

 

public FileMonitor(MongoPool map){

 this.setMap(map);

}

 /**

  * @return the map

  */

 public static MongoPool getMap() {

  return map;

 }

 

 /**

  * @param map the map to set

  */

 public static void setMap(MongoPool map) {

  FileMonitor.map = map;

 }

 

}

 

 

Java

package com.kartik.file.monitor;

 

public class FileMonitorException extends RuntimeException{

 

 private static final long serialVersionUID = -1122954555834923178L;

 

 public FileMonitorException(String msg, Throwable t) {

  super(msg, t);

 }

 

 public FileMonitorException(String msg) {

  super(msg);

 }

 

}

 

 

Java

package com.kartik.main.demo;

 

import java.io.File;

 

import com.kartik.beans.MongoPool;

import com.kartik.file.iread.impl.IFileReadImpl;

import com.kartik.file.monitor.FileMonitor;

 

public class Main {

 public static MongoPool map = null;

 public static void main(String[] args) {

    System.out.println("Befor Hash Map data");

 IFileReadImpl im=new IFileReadImpl();

 File fileName=new File("d:\\book.txt");

 map=im.jsonToObject(fileName);

 FileMonitor fm=new FileMonitor();

 Thread t = new Thread(fm);

    t.start();

    map=fm.getMap();

    System.out.println("wrwrer");

   

 }

 

}

 

 

Book.txt file

{

  "databases":[

   {

    "cluster":[

     {"host":"localhost","port":27017}

     ],

    "dbName":"documenttorage",

    "dbType":"oltp",

    "brandName":[123497,534294]

   },

   {

    "cluster":[

     {"host":"localhost","port":27017}

     ],

    "dbName":"test",

    "dbType":"ycc",

    " brandName":[35436,465629]

   }

  ]

 }

 



File monitoring if have any changes reloaded the file
File monitoring if have any changes reloaded the file










Post a Comment

0 Comments