Windows Removable Drive Detector

The following code allows the detection of the insertion and/or removal of removable drives including the insertion and/or removal of CD's and DVD's from their players. All possible drives can be checked or a subset of drives can be specified.

The class has static methods for determining which drives are currently available or you can create an instance of the class which runs a background thread polling the drives and notifiying registered listeners of any changes of state of the specified drives.

Note: This class will only work on Windows based systems.

License

This software is released under the GNU GPLv3 license


WinDriveDetector

To use this class see the Usage section.
/**
 * Copyright (c) 2010 Keang Ltd
 *
 * The WinDriveDetector class is free software: you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * The WinDriveDetector class 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 General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with the WinDriveDetector class.  If not, see http://www.gnu.org/licenses/.
 */
package uk.co.keang.utilities;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Timer;
import javax.swing.event.ChangeEvent;

/**
 * Lists the available disk drives and detects the insertion and/or removal of Removable drives
 * on Windows Systems. This includes the insertion and removal of CD's and DVD's from their drives.
 *
 *
 *@author Keang Ltd
 *@version 1.1, 01/02/2010
 */
public class WinDriveDetector
{
private final static char[] DRIVE_LETTERS = new char[]{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
        'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
private static final int DELAY = 1000;

/**
 * Gets all drives that are currently available on the local Windows system
 *
 * @return an array of File objects representing the root of each available drive
 */
public static File[] getAvailableDrives()
    {
    return getAvailableDrives(DRIVE_LETTERS);
    }

/**
 * Gets the drives that are currently available on the local Windows system from
 * this list of drive letters.
 *
 * @param driveLetters the drive letters to look for
 * @return an array of File objects representing the root of each available drive
 */
public static File[] getAvailableDrives(char[] driveLetters)
    {
    List d = new ArrayList();

    for ( int i = 0; i < driveLetters.length; ++i )
        {
        File drive = new File(driveLetters[i]+":/");

        if ( drive.canRead() )
            {
            d.add(drive);
            }
        }

    return d.toArray(new File[d.size()]);
    }

private File[] drives;
private Timer timer;
private List driveListeners = new ArrayList();
private boolean[] state;

/**
 * Create a WinDriveDetector to monitor the insertion and/or removal of all drives.
 * This polls the list of drives once every second.
 * 

* To receive notification of changes add an ActionListener(). *

* To start the monitor call start(). */ public WinDriveDetector() { this(DRIVE_LETTERS, DELAY); } /** * Create a WinDriveDetector to monitor the insertion and/or removal of the specified drives. * This polls the list of drives once every second. *

* To receive notification of changes add an ActionListener(). *

* To start the monitor call start(). * * @param driveLetters the drive letters to monitor */ public WinDriveDetector(char[] driveLetters) { this(driveLetters, DELAY); } /** * Create a WinDriveDetector to monitor the insertion and/or removal of all drives. * This polls the list of drives once every 'time' milliseconds. *

* To receive notification of changes add an ActionListener(). *

* To start the monitor call start(). * * @param time the time to wait between each check */ public WinDriveDetector(int time) { this(DRIVE_LETTERS, time); } /** * Create a WinDriveDetector to monitor the insertion and/or removal of the specified drives. * This polls the list of drives once every 'time' milliseconds. *

* To receive notification of changes add an ActionListener(). *

* To start the monitor call start(). * * @param driveLetters the drive letters to monitor * @param time the time to wait between each check */ public WinDriveDetector(char[] driveLetters, int time) { drives = new File[driveLetters.length]; state = new boolean[driveLetters.length]; // create File objects for each drive for ( int j = 0; j < driveLetters.length; j++ ) { drives[j] = new File(driveLetters[j]+":/"); state[j] = drives[j].canRead(); } // create the timer timer = new Timer(time, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { findChanges(); } }); timer.setRepeats(true); } /** * Starts the monitor. */ public void start() { timer.restart(); } /** * Stops this monitor. Once stopped it can be restarted by calling start(). */ public void stop() { timer.stop(); } /** * Sets the time to wait between polling the list of drives * * @param time the time to wait */ public void setTime(int time) { timer.setDelay(time); } /** * Adds a drive listener. This will be called when * * @param l - the listener to add */ public void addDriveListener(DriveListener l) { driveListeners.add(l); } /** * Removes the drive listener * * @param l - the listener to remove */ public void removeDriveListener(DriveListener l) { driveListeners.remove(l); } /** * Notifies registered listener of the change of state * * @param drive - the drive that has changed state * @param available - the new state, true for the drive is available else false */ protected void fireDriveEvent(File drive, boolean available) { ChangeEvent event = new ChangeEvent(drive); for ( DriveListener l : driveListeners ) { if ( available ) { l.driveInserted(event); } else { l.driveRemoved(event); } } } /** * Checks each drive to see if it's state has changed */ private void findChanges() { for ( int i = 0; i < drives.length; i++ ) { boolean currentState = drives[i].canRead(); if ( state[i] != currentState ) { state[i] = currentState; fireDriveEvent(drives[i], currentState); } } } }

DriveListener

The listener interface for receiving drive state change events.
/**
 * Copyright (c) 2010 Keang Ltd
 *
 * The WinDriveDetector class is free software: you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * The WinDriveDetector class 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 General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with the WinDriveDetector class.  If not, see .
 */
package uk.co.keang.utilities;

import javax.swing.event.ChangeEvent;

/**
 * The listener interface for receiving drive state events.
 * The class that is interested in processing a drive state event implements this interface,
 * and the object created with that class is registered with WinDriveDetector, using the
 * addDriveListener() method.
 *
 * @author Keang Ltd
 * @date 4 Feb 2010
 *
 */
public interface DriveListener
{
/**
 * Called when a drive has been inserted
 *
 * @param event  the event
 */
public void driveInserted(ChangeEvent event) ;

/**
 * Called when a drive has been removed
 *
 * @param e  the event
 */
public void driveRemoved(ChangeEvent event) ;
}

    


Usage

The following code is an example of how to create a drive detector. This example monitors the D and E drives every 2 seconds and prints a message to the console whenever one of the drives is inserted or removed.
    WinDriveDetector detector = new WinDriveDetector(new char[]{'D','E'}, 2000);
    detector.addDriveListener(new DriveListener()
        {
        @Override
        public void driveRemoved(ChangeEvent e)
            {
            System.out.println("Drive "+e.getSource()+" has been removed");
            }

        @Override
        public void driveInserted(ChangeEvent e)
            {
            System.out.println("Drive "+e.getSource()+" has been inserted");
            }
        });

    detector.start();
    
 
Back to the Top