<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://www.jexp.ru/index.php?action=history&amp;feed=atom&amp;title=Java%2FFile_Input_Output%2FFile_Monoitor</id>
		<title>Java/File Input Output/File Monoitor - История изменений</title>
		<link rel="self" type="application/atom+xml" href="http://www.jexp.ru/index.php?action=history&amp;feed=atom&amp;title=Java%2FFile_Input_Output%2FFile_Monoitor"/>
		<link rel="alternate" type="text/html" href="http://www.jexp.ru/index.php?title=Java/File_Input_Output/File_Monoitor&amp;action=history"/>
		<updated>2026-04-21T18:45:46Z</updated>
		<subtitle>История изменений этой страницы в вики</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://www.jexp.ru/index.php?title=Java/File_Input_Output/File_Monoitor&amp;diff=6181&amp;oldid=prev</id>
		<title>Admin: 1 версия</title>
		<link rel="alternate" type="text/html" href="http://www.jexp.ru/index.php?title=Java/File_Input_Output/File_Monoitor&amp;diff=6181&amp;oldid=prev"/>
				<updated>2010-06-01T06:03:41Z</updated>
		
		<summary type="html">&lt;p&gt;1 версия&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr style=&quot;vertical-align: top;&quot; lang=&quot;ru&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;← Предыдущая&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;Версия 06:03, 1 июня 2010&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; style=&quot;text-align: center;&quot; lang=&quot;ru&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(нет различий)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>http://www.jexp.ru/index.php?title=Java/File_Input_Output/File_Monoitor&amp;diff=6180&amp;oldid=prev</id>
		<title> в 18:01, 31 мая 2010</title>
		<link rel="alternate" type="text/html" href="http://www.jexp.ru/index.php?title=Java/File_Input_Output/File_Monoitor&amp;diff=6180&amp;oldid=prev"/>
				<updated>2010-05-31T18:01:43Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== File Monitor Demo ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
  &amp;lt;!-- start source code --&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
//$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/io/util/FileMonitor.java $&lt;br /&gt;
/*----------------    FILE HEADER  ------------------------------------------&lt;br /&gt;
 This file is part of deegree.&lt;br /&gt;
 Copyright (C) 2001-2008 by:&lt;br /&gt;
 EXSE, Department of Geography, University of Bonn&lt;br /&gt;
 http://www.giub.uni-bonn.de/deegree/&lt;br /&gt;
 lat/lon GmbH&lt;br /&gt;
 http://www.lat-lon.de&lt;br /&gt;
 This library is free software; you can redistribute it and/or&lt;br /&gt;
 modify it under the terms of the GNU Lesser General Public&lt;br /&gt;
 License as published by the Free Software Foundation; either&lt;br /&gt;
 version 2.1 of the License, or (at your option) any later version.&lt;br /&gt;
 This library is distributed in the hope that it will be useful,&lt;br /&gt;
 but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU&lt;br /&gt;
 Lesser General Public License for more details.&lt;br /&gt;
 You should have received a copy of the GNU Lesser General Public&lt;br /&gt;
 License along with this library; if not, write to the Free Software&lt;br /&gt;
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA&lt;br /&gt;
 Contact:&lt;br /&gt;
 Andreas Poth&lt;br /&gt;
 lat/lon GmbH&lt;br /&gt;
 Aennchenstr. 19&lt;br /&gt;
 53115 Bonn&lt;br /&gt;
 Germany&lt;br /&gt;
 E-Mail: poth@lat-lon.de&lt;br /&gt;
 Prof. Dr. Klaus Greve&lt;br /&gt;
 Department of Geography&lt;br /&gt;
 University of Bonn&lt;br /&gt;
 Meckenheimer Allee 166&lt;br /&gt;
 53115 Bonn&lt;br /&gt;
 Germany&lt;br /&gt;
 E-Mail: greve@giub.uni-bonn.de&lt;br /&gt;
 &lt;br /&gt;
 ---------------------------------------------------------------------------*/&lt;br /&gt;
&lt;br /&gt;
import java.io.File;&lt;br /&gt;
import java.io.FileNotFoundException;&lt;br /&gt;
import java.net.URL;&lt;br /&gt;
import java.util.Hashtable;&lt;br /&gt;
import java.util.Timer;&lt;br /&gt;
import java.util.TimerTask;&lt;br /&gt;
/**&lt;br /&gt;
 * Replaces inner class Reloader in AbstractOGCServlet.&lt;br /&gt;
 * &lt;br /&gt;
 * @author &lt;br /&gt;
 * &lt;br /&gt;
 * @author last edited by: $Author: apoth $&lt;br /&gt;
 * &lt;br /&gt;
 * @version 2.0, $Revision: 9342 $, $Date: 2007-12-27 13:32:57 +0100 (Do, 27 Dez 2007) $&lt;br /&gt;
 * &lt;br /&gt;
 * &lt;br /&gt;
 * @since 2.0&lt;br /&gt;
 */&lt;br /&gt;
interface FileChangeListener {&lt;br /&gt;
    /**&lt;br /&gt;
     * Invoked when a file changes.&lt;br /&gt;
     * &lt;br /&gt;
     * @param fileName&lt;br /&gt;
     *            name of changed file.&lt;br /&gt;
     */&lt;br /&gt;
    public void fileChanged(String fileName);&lt;br /&gt;
}&lt;br /&gt;
   &lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
   &lt;br /&gt;
  &amp;lt;!-- end source code --&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Monitor files for changes ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
  &amp;lt;!-- start source code --&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
// Copyright (C) 2007 Google Inc.&lt;br /&gt;
//&lt;br /&gt;
// Licensed under the Apache License, Version 2.0 (the &amp;quot;License&amp;quot;);&lt;br /&gt;
// you may not use this file except in compliance with the License.&lt;br /&gt;
// You may obtain a copy of the License at&lt;br /&gt;
//&lt;br /&gt;
// http://www.apache.org/licenses/LICENSE-2.0&lt;br /&gt;
//&lt;br /&gt;
// Unless required by applicable law or agreed to in writing, software&lt;br /&gt;
// distributed under the License is distributed on an &amp;quot;AS IS&amp;quot; BASIS,&lt;br /&gt;
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&lt;br /&gt;
// See the License for the specific language governing permissions and&lt;br /&gt;
// limitations under the License.&lt;br /&gt;
&lt;br /&gt;
import java.io.File;&lt;br /&gt;
import java.util.Hashtable;&lt;br /&gt;
import java.util.Timer;&lt;br /&gt;
import java.util.TimerTask;&lt;br /&gt;
/**&lt;br /&gt;
 * Monitor files for changes. This singleton class maintains a map of files to&lt;br /&gt;
 * monitor and objects to notify when something they change.&lt;br /&gt;
 */&lt;br /&gt;
public class FileMonitor {&lt;br /&gt;
  private static final FileMonitor SINGLETON = new FileMonitor();&lt;br /&gt;
  private Timer timer;&lt;br /&gt;
  private Hashtable&amp;lt;String, TimerTask&amp;gt; timerTasks;&lt;br /&gt;
  private FileMonitor() {&lt;br /&gt;
    timer = new Timer(true);&lt;br /&gt;
    timerTasks = new Hashtable&amp;lt;String, TimerTask&amp;gt;();&lt;br /&gt;
  }&lt;br /&gt;
  /**&lt;br /&gt;
   * Returns the singleton instance of this class.&lt;br /&gt;
   * @return the singleton instance&lt;br /&gt;
   */&lt;br /&gt;
  public static FileMonitor getInstance() {&lt;br /&gt;
    return SINGLETON;&lt;br /&gt;
  }&lt;br /&gt;
  /**&lt;br /&gt;
   * Start monitoring a file.&lt;br /&gt;
   * &lt;br /&gt;
   * @param listener listener to notify when the file changed.&lt;br /&gt;
   * @param fileName name of the file to monitor.&lt;br /&gt;
   * @param period polling period in milliseconds.&lt;br /&gt;
   */&lt;br /&gt;
  public void addFileChangeListener(FileChangeListener listener,&lt;br /&gt;
      String fileName, long period) {&lt;br /&gt;
    removeFileChangeListener(listener, fileName);&lt;br /&gt;
    FileMonitorTask task = new FileMonitorTask(listener, fileName);&lt;br /&gt;
    timerTasks.put(fileName + listener.hashCode(), task);&lt;br /&gt;
    timer.schedule(task, period, period);&lt;br /&gt;
  }&lt;br /&gt;
  /**&lt;br /&gt;
   * Remove the listener from the notification list.&lt;br /&gt;
   * &lt;br /&gt;
   * @param listener the listener to be removed.&lt;br /&gt;
   */&lt;br /&gt;
  public void removeFileChangeListener(FileChangeListener listener,&lt;br /&gt;
      String fileName) {&lt;br /&gt;
    FileMonitorTask task = (FileMonitorTask) timerTasks.remove(fileName&lt;br /&gt;
        + listener.hashCode());&lt;br /&gt;
    if (task != null) {&lt;br /&gt;
      task.cancel();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  protected void fireFileChangeEvent(FileChangeListener listener,&lt;br /&gt;
      String fileName) {&lt;br /&gt;
    listener.fileChanged(fileName);&lt;br /&gt;
  }&lt;br /&gt;
  class FileMonitorTask extends TimerTask {&lt;br /&gt;
    FileChangeListener listener;&lt;br /&gt;
    String fileName;&lt;br /&gt;
    File monitoredFile;&lt;br /&gt;
    long lastModified;&lt;br /&gt;
    public FileMonitorTask(FileChangeListener listener, String fileName) {&lt;br /&gt;
      this.listener = listener;&lt;br /&gt;
      this.fileName = fileName;&lt;br /&gt;
      this.lastModified = 0;&lt;br /&gt;
      monitoredFile = new File(fileName);&lt;br /&gt;
      this.lastModified = getLastModified();&lt;br /&gt;
    }&lt;br /&gt;
    private long getLastModified() {&lt;br /&gt;
      if (monitoredFile.exists()) { &lt;br /&gt;
        return monitoredFile.lastModified();&lt;br /&gt;
      } else {&lt;br /&gt;
        return -1;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    @Override&lt;br /&gt;
    public void run() {&lt;br /&gt;
      long lastModified = getLastModified();&lt;br /&gt;
      if (lastModified != this.lastModified) {&lt;br /&gt;
        this.lastModified = lastModified;&lt;br /&gt;
        fireFileChangeEvent(this.listener, this.fileName);&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  public interface FileChangeListener {&lt;br /&gt;
    public void fileChanged(String fileName);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
   &lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
   &lt;br /&gt;
  &amp;lt;!-- end source code --&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Monitoring a File for changes. ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
  &amp;lt;!-- start source code --&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
/*******************************************************************************&lt;br /&gt;
 * Copyright (c) 2007 Pascal Essiembre.&lt;br /&gt;
 * All rights reserved. This program and the accompanying materials&lt;br /&gt;
 * are made available under the terms of the Eclipse Public License v1.0&lt;br /&gt;
 * which accompanies this distribution, and is available at&lt;br /&gt;
 * http://www.eclipse.org/legal/epl-v10.html&lt;br /&gt;
 *&lt;br /&gt;
 * Contributors:&lt;br /&gt;
 *    Pascal Essiembre - initial API and implementation&lt;br /&gt;
 ******************************************************************************/&lt;br /&gt;
import java.io.File;&lt;br /&gt;
import java.io.FileNotFoundException;&lt;br /&gt;
import java.net.URL;&lt;br /&gt;
import java.util.Hashtable;&lt;br /&gt;
import java.util.Timer;&lt;br /&gt;
import java.util.TimerTask;&lt;br /&gt;
/**&lt;br /&gt;
 * Class monitoring a {@link File} for changes.&lt;br /&gt;
 * &lt;br /&gt;
 * @author Pascal Essiembre&lt;br /&gt;
 */&lt;br /&gt;
public class FileMonitor {&lt;br /&gt;
  private static final FileMonitor instance = new FileMonitor();&lt;br /&gt;
  private Timer timer;&lt;br /&gt;
  private Hashtable&amp;lt;String, FileMonitorTask&amp;gt; timerEntries;&lt;br /&gt;
  /**&lt;br /&gt;
   * Gets the file monitor instance.&lt;br /&gt;
   * &lt;br /&gt;
   * @return file monitor instance&lt;br /&gt;
   */&lt;br /&gt;
  public static FileMonitor getInstance() {&lt;br /&gt;
    return instance;&lt;br /&gt;
  }&lt;br /&gt;
  /**&lt;br /&gt;
   * Constructor.&lt;br /&gt;
   */&lt;br /&gt;
  private FileMonitor() {&lt;br /&gt;
    // Create timer, run timer thread as daemon.&lt;br /&gt;
    timer = new Timer(true);&lt;br /&gt;
    timerEntries = new Hashtable&amp;lt;String, FileMonitorTask&amp;gt;();&lt;br /&gt;
  }&lt;br /&gt;
  /**&lt;br /&gt;
   * Adds a monitored file with a {@link FileChangeListener}.&lt;br /&gt;
   * &lt;br /&gt;
   * @param listener&lt;br /&gt;
   *          listener to notify when the file changed.&lt;br /&gt;
   * @param fileName&lt;br /&gt;
   *          name of the file to monitor.&lt;br /&gt;
   * @param period&lt;br /&gt;
   *          polling period in milliseconds.&lt;br /&gt;
   */&lt;br /&gt;
  public void addFileChangeListener(FileChangeListener listener, String fileName, long period)&lt;br /&gt;
      throws FileNotFoundException {&lt;br /&gt;
    addFileChangeListener(listener, new File(fileName), period);&lt;br /&gt;
  }&lt;br /&gt;
  /**&lt;br /&gt;
   * Adds a monitored file with a FileChangeListener.&lt;br /&gt;
   * &lt;br /&gt;
   * @param listener&lt;br /&gt;
   *          listener to notify when the file changed.&lt;br /&gt;
   * @param fileName&lt;br /&gt;
   *          name of the file to monitor.&lt;br /&gt;
   * @param period&lt;br /&gt;
   *          polling period in milliseconds.&lt;br /&gt;
   */&lt;br /&gt;
  public void addFileChangeListener(FileChangeListener listener, File file, long period)&lt;br /&gt;
      throws FileNotFoundException {&lt;br /&gt;
    removeFileChangeListener(listener, file);&lt;br /&gt;
    FileMonitorTask task = new FileMonitorTask(listener, file);&lt;br /&gt;
    timerEntries.put(file.toString() + listener.hashCode(), task);&lt;br /&gt;
    timer.schedule(task, period, period);&lt;br /&gt;
  }&lt;br /&gt;
  /**&lt;br /&gt;
   * Remove the listener from the notification list.&lt;br /&gt;
   * &lt;br /&gt;
   * @param listener&lt;br /&gt;
   *          the listener to be removed.&lt;br /&gt;
   */&lt;br /&gt;
  public void removeFileChangeListener(FileChangeListener listener, String fileName) {&lt;br /&gt;
    removeFileChangeListener(listener, new File(fileName));&lt;br /&gt;
  }&lt;br /&gt;
  /**&lt;br /&gt;
   * Remove the listener from the notification list.&lt;br /&gt;
   * &lt;br /&gt;
   * @param listener&lt;br /&gt;
   *          the listener to be removed.&lt;br /&gt;
   */&lt;br /&gt;
  public void removeFileChangeListener(FileChangeListener listener, File file) {&lt;br /&gt;
    FileMonitorTask task = timerEntries.remove(file.toString() + listener.hashCode());&lt;br /&gt;
    if (task != null) {&lt;br /&gt;
      task.cancel();&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  /**&lt;br /&gt;
   * Fires notification that a file changed.&lt;br /&gt;
   * &lt;br /&gt;
   * @param listener&lt;br /&gt;
   *          file change listener&lt;br /&gt;
   * @param file&lt;br /&gt;
   *          the file that changed&lt;br /&gt;
   */&lt;br /&gt;
  protected void fireFileChangeEvent(FileChangeListener listener, File file) {&lt;br /&gt;
    listener.fileChanged(file);&lt;br /&gt;
  }&lt;br /&gt;
  /**&lt;br /&gt;
   * File monitoring task.&lt;br /&gt;
   */&lt;br /&gt;
  class FileMonitorTask extends TimerTask {&lt;br /&gt;
    FileChangeListener listener;&lt;br /&gt;
    File monitoredFile;&lt;br /&gt;
    long lastModified;&lt;br /&gt;
    public FileMonitorTask(FileChangeListener listener, File file) throws FileNotFoundException {&lt;br /&gt;
      this.listener = listener;&lt;br /&gt;
      this.lastModified = 0;&lt;br /&gt;
      monitoredFile = file;&lt;br /&gt;
      if (!monitoredFile.exists()) { // but is it on CLASSPATH?&lt;br /&gt;
        URL fileURL = listener.getClass().getClassLoader().getResource(file.toString());&lt;br /&gt;
        if (fileURL != null) {&lt;br /&gt;
          monitoredFile = new File(fileURL.getFile());&lt;br /&gt;
        } else {&lt;br /&gt;
          throw new FileNotFoundException(&amp;quot;File Not Found: &amp;quot; + file);&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      this.lastModified = monitoredFile.lastModified();&lt;br /&gt;
    }&lt;br /&gt;
    public void run() {&lt;br /&gt;
      long lastModified = monitoredFile.lastModified();&lt;br /&gt;
      if (lastModified != this.lastModified) {&lt;br /&gt;
        this.lastModified = lastModified;&lt;br /&gt;
        fireFileChangeEvent(this.listener, monitoredFile);&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
/*******************************************************************************&lt;br /&gt;
 * Copyright (c) 2007 Pascal Essiembre. All rights reserved. This program and&lt;br /&gt;
 * the accompanying materials are made available under the terms of the Eclipse&lt;br /&gt;
 * Public License v1.0 which accompanies this distribution, and is available at&lt;br /&gt;
 * http://www.eclipse.org/legal/epl-v10.html&lt;br /&gt;
 * &lt;br /&gt;
 * Contributors: Pascal Essiembre - initial API and implementation&lt;br /&gt;
 ******************************************************************************/&lt;br /&gt;
/**&lt;br /&gt;
 * Listener interested in {@link File} changes.&lt;br /&gt;
 * &lt;br /&gt;
 * @author Pascal Essiembre&lt;br /&gt;
 */&lt;br /&gt;
interface FileChangeListener {&lt;br /&gt;
  /**&lt;br /&gt;
   * Invoked when a file changes.&lt;br /&gt;
   * &lt;br /&gt;
   * @param fileName&lt;br /&gt;
   *          name of changed file.&lt;br /&gt;
   */&lt;br /&gt;
  public void fileChanged(File file);&lt;br /&gt;
}&lt;br /&gt;
   &lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
   &lt;br /&gt;
  &amp;lt;!-- end source code --&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Utility class for synchronizing files/directories ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
  &amp;lt;!-- start source code --&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
//$Id: FileHelper.java 15522 2008-11-05 20:06:43Z hardy.ferentschik $&lt;br /&gt;
//Revised from hibernate search util&lt;br /&gt;
import java.io.File;&lt;br /&gt;
import java.io.FileInputStream;&lt;br /&gt;
import java.io.FileOutputStream;&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import java.nio.channels.FileChannel;&lt;br /&gt;
import java.util.Arrays;&lt;br /&gt;
import java.util.HashSet;&lt;br /&gt;
import java.util.Set;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Utility class for synchronizing files/directories.&lt;br /&gt;
 *&lt;br /&gt;
 * @author Emmanuel Bernard&lt;br /&gt;
 * @author Sanne Grinovero&lt;br /&gt;
 * @author Hardy Ferentschik&lt;br /&gt;
 */&lt;br /&gt;
public abstract class FileHelper {&lt;br /&gt;
  private static final int FAT_PRECISION = 2000;&lt;br /&gt;
  public static final long DEFAULT_COPY_BUFFER_SIZE = 16 * 1024 * 1024; // 16 MB&lt;br /&gt;
&lt;br /&gt;
  public static boolean areInSync(File source, File destination) throws IOException {&lt;br /&gt;
    if ( source.isDirectory() ) {&lt;br /&gt;
      if ( !destination.exists() ) {&lt;br /&gt;
        return false;&lt;br /&gt;
      }&lt;br /&gt;
      else if ( !destination.isDirectory() ) {&lt;br /&gt;
        throw new IOException(&lt;br /&gt;
            &amp;quot;Source and Destination not of the same type:&amp;quot;&lt;br /&gt;
                + source.getCanonicalPath() + &amp;quot; , &amp;quot; + destination.getCanonicalPath()&lt;br /&gt;
        );&lt;br /&gt;
      }&lt;br /&gt;
      String[] sources = source.list();&lt;br /&gt;
      Set&amp;lt;String&amp;gt; srcNames = new HashSet&amp;lt;String&amp;gt;( Arrays.asList( sources ) );&lt;br /&gt;
      String[] dests = destination.list();&lt;br /&gt;
      // check for files in destination and not in source&lt;br /&gt;
      for ( String fileName : dests ) {&lt;br /&gt;
        if ( !srcNames.contains( fileName ) ) {&lt;br /&gt;
          return false;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      boolean inSync = true;&lt;br /&gt;
      for ( String fileName : sources ) {&lt;br /&gt;
        File srcFile = new File( source, fileName );&lt;br /&gt;
        File destFile = new File( destination, fileName );&lt;br /&gt;
        if ( !areInSync( srcFile, destFile ) ) {&lt;br /&gt;
          inSync = false;&lt;br /&gt;
          break;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      return inSync;&lt;br /&gt;
    }&lt;br /&gt;
    else {&lt;br /&gt;
      if ( destination.exists() &amp;amp;&amp;amp; destination.isFile() ) {&lt;br /&gt;
        long sts = source.lastModified() / FAT_PRECISION;&lt;br /&gt;
        long dts = destination.lastModified() / FAT_PRECISION;&lt;br /&gt;
        return sts == dts;&lt;br /&gt;
      }&lt;br /&gt;
      else {&lt;br /&gt;
        return false;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  public static void synchronize(File source, File destination, boolean smart) throws IOException {&lt;br /&gt;
    synchronize( source, destination, smart, DEFAULT_COPY_BUFFER_SIZE );&lt;br /&gt;
  }&lt;br /&gt;
  public static void synchronize(File source, File destination, boolean smart, long chunkSize) throws IOException {&lt;br /&gt;
    if ( chunkSize &amp;lt;= 0 ) {&lt;br /&gt;
      System.out.println(&amp;quot;Chunk size must be positive: using default value.&amp;quot; );&lt;br /&gt;
      chunkSize = DEFAULT_COPY_BUFFER_SIZE;&lt;br /&gt;
    }&lt;br /&gt;
    if ( source.isDirectory() ) {&lt;br /&gt;
      if ( !destination.exists() ) {&lt;br /&gt;
        if ( !destination.mkdirs() ) {&lt;br /&gt;
          throw new IOException( &amp;quot;Could not create path &amp;quot; + destination );&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      else if ( !destination.isDirectory() ) {&lt;br /&gt;
        throw new IOException(&lt;br /&gt;
            &amp;quot;Source and Destination not of the same type:&amp;quot;&lt;br /&gt;
                + source.getCanonicalPath() + &amp;quot; , &amp;quot; + destination.getCanonicalPath()&lt;br /&gt;
        );&lt;br /&gt;
      }&lt;br /&gt;
      String[] sources = source.list();&lt;br /&gt;
      Set&amp;lt;String&amp;gt; srcNames = new HashSet&amp;lt;String&amp;gt;( Arrays.asList( sources ) );&lt;br /&gt;
      String[] dests = destination.list();&lt;br /&gt;
      //delete files not present in source&lt;br /&gt;
      for ( String fileName : dests ) {&lt;br /&gt;
        if ( !srcNames.contains( fileName ) ) {&lt;br /&gt;
          delete( new File( destination, fileName ) );&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      //copy each file from source&lt;br /&gt;
      for ( String fileName : sources ) {&lt;br /&gt;
        File srcFile = new File( source, fileName );&lt;br /&gt;
        File destFile = new File( destination, fileName );&lt;br /&gt;
        synchronize( srcFile, destFile, smart, chunkSize );&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    else {&lt;br /&gt;
      if ( destination.exists() &amp;amp;&amp;amp; destination.isDirectory() ) {&lt;br /&gt;
        delete( destination );&lt;br /&gt;
      }&lt;br /&gt;
      if ( destination.exists() ) {&lt;br /&gt;
        long sts = source.lastModified() / FAT_PRECISION;&lt;br /&gt;
        long dts = destination.lastModified() / FAT_PRECISION;&lt;br /&gt;
        //do not copy if smart and same timestamp and same length&lt;br /&gt;
        if ( !smart || sts == 0 || sts != dts || source.length() != destination.length() ) {&lt;br /&gt;
          copyFile( source, destination, chunkSize );&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
      else {&lt;br /&gt;
        copyFile( source, destination, chunkSize );&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  private static void copyFile(File srcFile, File destFile, long chunkSize) throws IOException {&lt;br /&gt;
    FileInputStream is = null;&lt;br /&gt;
    FileOutputStream os = null;&lt;br /&gt;
    try {&lt;br /&gt;
      is = new FileInputStream( srcFile );&lt;br /&gt;
      FileChannel iChannel = is.getChannel();&lt;br /&gt;
      os = new FileOutputStream( destFile, false );&lt;br /&gt;
      FileChannel oChannel = os.getChannel();&lt;br /&gt;
      long doneBytes = 0L;&lt;br /&gt;
      long todoBytes = srcFile.length();&lt;br /&gt;
      while ( todoBytes != 0L ) {&lt;br /&gt;
        long iterationBytes = Math.min( todoBytes, chunkSize );&lt;br /&gt;
        long transferredLength = oChannel.transferFrom( iChannel, doneBytes, iterationBytes );&lt;br /&gt;
        if ( iterationBytes != transferredLength ) {&lt;br /&gt;
          throw new IOException(&lt;br /&gt;
              &amp;quot;Error during file transfer: expected &amp;quot;&lt;br /&gt;
                  + iterationBytes + &amp;quot; bytes, only &amp;quot; + transferredLength + &amp;quot; bytes copied.&amp;quot;&lt;br /&gt;
          );&lt;br /&gt;
        }&lt;br /&gt;
        doneBytes += transferredLength;&lt;br /&gt;
        todoBytes -= transferredLength;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    finally {&lt;br /&gt;
      if ( is != null ) {&lt;br /&gt;
        is.close();&lt;br /&gt;
      }&lt;br /&gt;
      if ( os != null ) {&lt;br /&gt;
        os.close();&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    boolean successTimestampOp = destFile.setLastModified( srcFile.lastModified() );&lt;br /&gt;
    if ( !successTimestampOp ) {&lt;br /&gt;
      System.out.println(&amp;quot;Could not change timestamp for {}. Index synchronization may be slow. &amp;quot; + destFile );&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  public static void delete(File file) {&lt;br /&gt;
    if ( file.isDirectory() ) {&lt;br /&gt;
      for ( File subFile : file.listFiles() ) {&lt;br /&gt;
        delete( subFile );&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    if ( file.exists() ) {&lt;br /&gt;
      if ( !file.delete() ) {&lt;br /&gt;
        System.out.println( &amp;quot;Could not delete {}&amp;quot; + file );&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
   &lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
  &amp;lt;/source&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
   &lt;br /&gt;
  &amp;lt;!-- end source code --&amp;gt;&lt;/div&gt;</summary>
			</entry>

	</feed>