Java/File Input Output/File Monoitor — различия между версиями
Admin (обсуждение | вклад) м (1 версия) |
|
(нет различий)
|
Текущая версия на 06:03, 1 июня 2010
Содержание
File Monitor Demo
//$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);
}
Monitor files for changes
// 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);
}
}
Monitoring a File for changes.
/*******************************************************************************
* 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);
}
Utility class for synchronizing files/directories
//$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 );
}
}
}
}