Java/File Input Output/File Monoitor

Материал из Java эксперт
Перейти к: навигация, поиск

File Monitor Demo

   <source lang="java">
   

//$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/io/util/FileMonitor.java $ /*---------------- FILE HEADER ------------------------------------------

This file is part of deegree.
Copyright (C) 2001-2008 by:
EXSE, Department of Geography, University of Bonn
http://www.giub.uni-bonn.de/deegree/
lat/lon GmbH
http://www.lat-lon.de
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Contact:
Andreas Poth
lat/lon GmbH
Aennchenstr. 19
53115 Bonn
Germany
E-Mail: poth@lat-lon.de
Prof. Dr. Klaus Greve
Department of Geography
University of Bonn
Meckenheimer Allee 166
53115 Bonn
Germany
E-Mail: greve@giub.uni-bonn.de

---------------------------------------------------------------------------*/

import java.io.File; import java.io.FileNotFoundException; import java.net.URL; import java.util.Hashtable; import java.util.Timer; import java.util.TimerTask; /**

* Replaces inner class Reloader in AbstractOGCServlet.
* 
* @author 
* 
* @author last edited by: $Author: apoth $
* 
* @version 2.0, $Revision: 9342 $, $Date: 2007-12-27 13:32:57 +0100 (Do, 27 Dez 2007) $
* 
* 
* @since 2.0
*/

interface FileChangeListener {

   /**
    * Invoked when a file changes.
    * 
    * @param fileName
    *            name of changed file.
    */
   public void fileChanged(String fileName);

}



 </source>
   
  
 
  



Monitor files for changes

   <source lang="java">

// Copyright (C) 2007 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License.

import java.io.File; import java.util.Hashtable; import java.util.Timer; import java.util.TimerTask; /**

* Monitor files for changes. This singleton class maintains a map of files to
* monitor and objects to notify when something they change.
*/

public class FileMonitor {

 private static final FileMonitor SINGLETON = new FileMonitor();
 private Timer timer;
 private Hashtable<String, TimerTask> timerTasks;
 private FileMonitor() {
   timer = new Timer(true);
   timerTasks = new Hashtable<String, TimerTask>();
 }
 /**
  * Returns the singleton instance of this class.
  * @return the singleton instance
  */
 public static FileMonitor getInstance() {
   return SINGLETON;
 }
 /**
  * Start monitoring a file.
  * 
  * @param listener listener to notify when the file changed.
  * @param fileName name of the file to monitor.
  * @param period polling period in milliseconds.
  */
 public void addFileChangeListener(FileChangeListener listener,
     String fileName, long period) {
   removeFileChangeListener(listener, fileName);
   FileMonitorTask task = new FileMonitorTask(listener, fileName);
   timerTasks.put(fileName + listener.hashCode(), task);
   timer.schedule(task, period, period);
 }
 /**
  * Remove the listener from the notification list.
  * 
  * @param listener the listener to be removed.
  */
 public void removeFileChangeListener(FileChangeListener listener,
     String fileName) {
   FileMonitorTask task = (FileMonitorTask) timerTasks.remove(fileName
       + listener.hashCode());
   if (task != null) {
     task.cancel();
   }
 }
 protected void fireFileChangeEvent(FileChangeListener listener,
     String fileName) {
   listener.fileChanged(fileName);
 }
 class FileMonitorTask extends TimerTask {
   FileChangeListener listener;
   String fileName;
   File monitoredFile;
   long lastModified;
   public FileMonitorTask(FileChangeListener listener, String fileName) {
     this.listener = listener;
     this.fileName = fileName;
     this.lastModified = 0;
     monitoredFile = new File(fileName);
     this.lastModified = getLastModified();
   }
   private long getLastModified() {
     if (monitoredFile.exists()) { 
       return monitoredFile.lastModified();
     } else {
       return -1;
     }
   }
   @Override
   public void run() {
     long lastModified = getLastModified();
     if (lastModified != this.lastModified) {
       this.lastModified = lastModified;
       fireFileChangeEvent(this.listener, this.fileName);
     }
   }
 }
 
 public interface FileChangeListener {
   public void fileChanged(String fileName);
 }

}

 </source>
   
  
 
  



Monitoring a File for changes.

   <source lang="java">

/*******************************************************************************

* Copyright (c) 2007 Pascal Essiembre.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*    Pascal Essiembre - initial API and implementation
******************************************************************************/

import java.io.File; import java.io.FileNotFoundException; import java.net.URL; import java.util.Hashtable; import java.util.Timer; import java.util.TimerTask; /**

* Class monitoring a {@link File} for changes.
* 
* @author Pascal Essiembre
*/

public class FileMonitor {

 private static final FileMonitor instance = new FileMonitor();
 private Timer timer;
 private Hashtable<String, FileMonitorTask> timerEntries;
 /**
  * Gets the file monitor instance.
  * 
  * @return file monitor instance
  */
 public static FileMonitor getInstance() {
   return instance;
 }
 /**
  * Constructor.
  */
 private FileMonitor() {
   // Create timer, run timer thread as daemon.
   timer = new Timer(true);
   timerEntries = new Hashtable<String, FileMonitorTask>();
 }
 /**
  * Adds a monitored file with a {@link FileChangeListener}.
  * 
  * @param listener
  *          listener to notify when the file changed.
  * @param fileName
  *          name of the file to monitor.
  * @param period
  *          polling period in milliseconds.
  */
 public void addFileChangeListener(FileChangeListener listener, String fileName, long period)
     throws FileNotFoundException {
   addFileChangeListener(listener, new File(fileName), period);
 }
 /**
  * Adds a monitored file with a FileChangeListener.
  * 
  * @param listener
  *          listener to notify when the file changed.
  * @param fileName
  *          name of the file to monitor.
  * @param period
  *          polling period in milliseconds.
  */
 public void addFileChangeListener(FileChangeListener listener, File file, long period)
     throws FileNotFoundException {
   removeFileChangeListener(listener, file);
   FileMonitorTask task = new FileMonitorTask(listener, file);
   timerEntries.put(file.toString() + listener.hashCode(), task);
   timer.schedule(task, period, period);
 }
 /**
  * Remove the listener from the notification list.
  * 
  * @param listener
  *          the listener to be removed.
  */
 public void removeFileChangeListener(FileChangeListener listener, String fileName) {
   removeFileChangeListener(listener, new File(fileName));
 }
 /**
  * Remove the listener from the notification list.
  * 
  * @param listener
  *          the listener to be removed.
  */
 public void removeFileChangeListener(FileChangeListener listener, File file) {
   FileMonitorTask task = timerEntries.remove(file.toString() + listener.hashCode());
   if (task != null) {
     task.cancel();
   }
 }
 /**
  * Fires notification that a file changed.
  * 
  * @param listener
  *          file change listener
  * @param file
  *          the file that changed
  */
 protected void fireFileChangeEvent(FileChangeListener listener, File file) {
   listener.fileChanged(file);
 }
 /**
  * File monitoring task.
  */
 class FileMonitorTask extends TimerTask {
   FileChangeListener listener;
   File monitoredFile;
   long lastModified;
   public FileMonitorTask(FileChangeListener listener, File file) throws FileNotFoundException {
     this.listener = listener;
     this.lastModified = 0;
     monitoredFile = file;
     if (!monitoredFile.exists()) { // but is it on CLASSPATH?
       URL fileURL = listener.getClass().getClassLoader().getResource(file.toString());
       if (fileURL != null) {
         monitoredFile = new File(fileURL.getFile());
       } else {
         throw new FileNotFoundException("File Not Found: " + file);
       }
     }
     this.lastModified = monitoredFile.lastModified();
   }
   public void run() {
     long lastModified = monitoredFile.lastModified();
     if (lastModified != this.lastModified) {
       this.lastModified = lastModified;
       fireFileChangeEvent(this.listener, monitoredFile);
     }
   }
 }

} /*******************************************************************************

* Copyright (c) 2007 Pascal Essiembre. All rights reserved. This program and
* the accompanying materials are made available under the terms of the Eclipse
* Public License v1.0 which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
* 
* Contributors: Pascal Essiembre - initial API and implementation
******************************************************************************/

/**

* Listener interested in {@link File} changes.
* 
* @author Pascal Essiembre
*/

interface FileChangeListener {

 /**
  * Invoked when a file changes.
  * 
  * @param fileName
  *          name of changed file.
  */
 public void fileChanged(File file);

}

 </source>
   
  
 
  



Utility class for synchronizing files/directories

   <source lang="java">
   

//$Id: FileHelper.java 15522 2008-11-05 20:06:43Z hardy.ferentschik $ //Revised from hibernate search util import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.channels.FileChannel; import java.util.Arrays; import java.util.HashSet; import java.util.Set;

/**

* Utility class for synchronizing files/directories.
*
* @author Emmanuel Bernard
* @author Sanne Grinovero
* @author Hardy Ferentschik
*/

public abstract class FileHelper {

 private static final int FAT_PRECISION = 2000;
 public static final long DEFAULT_COPY_BUFFER_SIZE = 16 * 1024 * 1024; // 16 MB
 public static boolean areInSync(File source, File destination) throws IOException {
   if ( source.isDirectory() ) {
     if ( !destination.exists() ) {
       return false;
     }
     else if ( !destination.isDirectory() ) {
       throw new IOException(
           "Source and Destination not of the same type:"
               + source.getCanonicalPath() + " , " + destination.getCanonicalPath()
       );
     }
     String[] sources = source.list();
     Set<String> srcNames = new HashSet<String>( Arrays.asList( sources ) );
     String[] dests = destination.list();
     // check for files in destination and not in source
     for ( String fileName : dests ) {
       if ( !srcNames.contains( fileName ) ) {
         return false;
       }
     }
     boolean inSync = true;
     for ( String fileName : sources ) {
       File srcFile = new File( source, fileName );
       File destFile = new File( destination, fileName );
       if ( !areInSync( srcFile, destFile ) ) {
         inSync = false;
         break;
       }
     }
     return inSync;
   }
   else {
     if ( destination.exists() && destination.isFile() ) {
       long sts = source.lastModified() / FAT_PRECISION;
       long dts = destination.lastModified() / FAT_PRECISION;
       return sts == dts;
     }
     else {
       return false;
     }
   }
 }
 public static void synchronize(File source, File destination, boolean smart) throws IOException {
   synchronize( source, destination, smart, DEFAULT_COPY_BUFFER_SIZE );
 }
 public static void synchronize(File source, File destination, boolean smart, long chunkSize) throws IOException {
   if ( chunkSize <= 0 ) {
     System.out.println("Chunk size must be positive: using default value." );
     chunkSize = DEFAULT_COPY_BUFFER_SIZE;
   }
   if ( source.isDirectory() ) {
     if ( !destination.exists() ) {
       if ( !destination.mkdirs() ) {
         throw new IOException( "Could not create path " + destination );
       }
     }
     else if ( !destination.isDirectory() ) {
       throw new IOException(
           "Source and Destination not of the same type:"
               + source.getCanonicalPath() + " , " + destination.getCanonicalPath()
       );
     }
     String[] sources = source.list();
     Set<String> srcNames = new HashSet<String>( Arrays.asList( sources ) );
     String[] dests = destination.list();
     //delete files not present in source
     for ( String fileName : dests ) {
       if ( !srcNames.contains( fileName ) ) {
         delete( new File( destination, fileName ) );
       }
     }
     //copy each file from source
     for ( String fileName : sources ) {
       File srcFile = new File( source, fileName );
       File destFile = new File( destination, fileName );
       synchronize( srcFile, destFile, smart, chunkSize );
     }
   }
   else {
     if ( destination.exists() && destination.isDirectory() ) {
       delete( destination );
     }
     if ( destination.exists() ) {
       long sts = source.lastModified() / FAT_PRECISION;
       long dts = destination.lastModified() / FAT_PRECISION;
       //do not copy if smart and same timestamp and same length
       if ( !smart || sts == 0 || sts != dts || source.length() != destination.length() ) {
         copyFile( source, destination, chunkSize );
       }
     }
     else {
       copyFile( source, destination, chunkSize );
     }
   }
 }
 private static void copyFile(File srcFile, File destFile, long chunkSize) throws IOException {
   FileInputStream is = null;
   FileOutputStream os = null;
   try {
     is = new FileInputStream( srcFile );
     FileChannel iChannel = is.getChannel();
     os = new FileOutputStream( destFile, false );
     FileChannel oChannel = os.getChannel();
     long doneBytes = 0L;
     long todoBytes = srcFile.length();
     while ( todoBytes != 0L ) {
       long iterationBytes = Math.min( todoBytes, chunkSize );
       long transferredLength = oChannel.transferFrom( iChannel, doneBytes, iterationBytes );
       if ( iterationBytes != transferredLength ) {
         throw new IOException(
             "Error during file transfer: expected "
                 + iterationBytes + " bytes, only " + transferredLength + " bytes copied."
         );
       }
       doneBytes += transferredLength;
       todoBytes -= transferredLength;
     }
   }
   finally {
     if ( is != null ) {
       is.close();
     }
     if ( os != null ) {
       os.close();
     }
   }
   boolean successTimestampOp = destFile.setLastModified( srcFile.lastModified() );
   if ( !successTimestampOp ) {
     System.out.println("Could not change timestamp for {}. Index synchronization may be slow. " + destFile );
   }
 }
 public static void delete(File file) {
   if ( file.isDirectory() ) {
     for ( File subFile : file.listFiles() ) {
       delete( subFile );
     }
   }
   if ( file.exists() ) {
     if ( !file.delete() ) {
       System.out.println( "Could not delete {}" + file );
     }
   }
 }

}



 </source>