采用多线程自动监视并扫描指定文件夹中的文件变化,实现其功能的代码由四个java文件组成 :FileListener.java,FileMonitor.java,FileTableModel.java,ParseUtility.java.其具体代码如下:
FileListener.java
/*
* FileListener.java
*
* Created on 2007-9-27, 17:58:49
*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package DirectoryScanner;
/**
*
* @author Hale Chou
*/
public interface FileListener {
void dirChanged(FileMonitor monitor);
}
FileMonitor.java
/*
* FileMonitor.java
*
* Created on 2007-9-27, 17:59:05
*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package DirectoryScanner;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author Hale Chou
*/
public class FileMonitor implements Runnable {
List
private File dir;
private long interval;
private long lastScanedTime;
private int oldLength;
public void addListener(FileListener listener) {
listenerList.add(listener);
}
public void start(boolean isDamon) {
Thread t = new Thread(this);
t.setDaemon(isDamon);
t.start();
}
public FileMonitor(String _dir, long intervalTime) {
File f = new File(_dir);
if(!f.isDirectory())
throw new RuntimeException();
//筛选出不是标准文件的目录
File[] fileList = f.listFiles();
for( int i = 0; i < fileList.length; i++ ) {
if(fileList[i].isDirectory()) {
fileList[i].delete();
}
}
this.dir = f;
this.interval = intervalTime ;
this.oldLength = dir.listFiles().length;
}
public File[] getMonitoredFile() {
return this.dir.listFiles();
}
public void run() {
while(true) {
if(!dir.isDirectory())
throw new RuntimeException();
if(filesChanged()) {
fireFilesChangedEvent(this);
}
try {
Thread.sleep(interval);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
private void fireFilesChangedEvent(FileMonitor monitor) {
for( int i = 0; i < listenerList.size(); i ++ ) {
listenerList.get(i).dirChanged(monitor);
}
}
protected boolean filesChanged() {
File[] newFiles = dir.listFiles();
if(newFiles.length != oldLength) {
oldLength = newFiles.length;
//System.out.println(newFiles.length);
return true;
}
for( int i = 0; i < newFiles.length; i++ ) {
if(newFiles[i].lastModified() >= lastScanedTime) {
return true;
}
}
return false ;
}
}
FileTableModel.java
/*
* FileTableModel.java
*
* Created on 2007-9-27, 17:59:28
*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package DirectoryScanner;
import java.io.File;
import javax.swing.table.AbstractTableModel;
/**
*
* @author Hale Chou
*/
public class FileTableModel extends AbstractTableModel implements FileListener {
private File[] files = null ;
public FileTableModel(File dir) {
files = dir.listFiles();
}
public FileTableModel(File[] ff) {
this.files = ff;
}
public int getRowCount() {
return files.length;
}
// Get a column's name.
@Override
public String getColumnName(int col) {
String s = "文件名,路径,大小,修改时间";
return s.split(",")[col];
}
public int getColumnCount() {
return 4;
}
public Object getValueAt(int rowIndex, int columnIndex) {
File f = files[rowIndex];
if(f.isDirectory()){
f.delete();
}else{
switch(columnIndex){
case 0 :
return f.getName();
case 1 :
return f.getPath();
case 2 :
return ParseUtility.bytes2kb(f.length());
case 3 :
return ParseUtility.toYYYYMMDDHHMMSS(f.lastModified());
}
}
return "";
}
public void dirChanged(FileMonitor monitor) {
this.files = monitor.getMonitoredFile();
fireTableDataChanged();
}
}
ParseUtility.java
/*
* ParseUtility.java
*
* Created on 2007-9-27, 17:59:55
*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package DirectoryScanner;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
*
* @author Administrator
*/
public class ParseUtility {
public ParseUtility(){
}
public static String toYYYYMMDDHHMMSS(long time) {
SimpleDateFormat format = new SimpleDateFormat("M月d日H时m分s秒");
return format.format(new Date(time));
}
public static String bytes2kb(long bytes) {
BigDecimal filesize = new BigDecimal(bytes);
BigDecimal megabyte = new BigDecimal(1024 * 1024);
float returnValue = filesize.divide(megabyte, 2 , BigDecimal.ROUND_UP).floatValue();
if (returnValue > 1)
return(returnValue + " MB");
BigDecimal kilobyte = new BigDecimal(1024);
returnValue = filesize.divide(kilobyte, 2 , BigDecimal.ROUND_UP).floatValue();
return (returnValue + " KB");
}
}
最后是调用程序:
/*
* FileMonitorTest.java
*
* Created on 2007年9月28日, 上午9:21
*/
package file;
import java.io.File;
import javax.swing.table.TableModel;
import javax.swing.JFileChooser;
import javax.swing.event.*;
import DirectoryScanner.*;
/**
*
* @author Hale Chou
*/
public class FileMonitorTest extends javax.swing.JFrame {
public TableModel tableModel;
/** Creates new form FileMonitorTest */
public FileMonitorTest() {
initComponents();
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
//
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
jTable1 = new javax.swing.JTable();
jLabel1 = new javax.swing.JLabel();
txt_FilesCount = new javax.swing.JTextField();
jLabel2 = new javax.swing.JLabel();
txt_ScannedDirectory = new javax.swing.JTextField();
btn_StartScan = new javax.swing.JButton();
btn_SelectDirectory = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jTable1.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
},
new String [] {
}
));
jScrollPane1.setViewportView(jTable1);
jLabel1.setText("当前文件数:");
txt_FilesCount.setEditable(false);
jLabel2.setText("选择文件夹:");
btn_StartScan.setText("开始监视");
btn_StartScan.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btn_StartScanActionPerformed(evt);
}
});
btn_SelectDirectory.setText("选择目录");
btn_SelectDirectory.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btn_SelectDirectoryActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jLabel2)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(txt_ScannedDirectory, javax.swing.GroupLayout.PREFERRED_SIZE, 198, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(btn_SelectDirectory)
.addContainerGap(31, Short.MAX_VALUE))
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jLabel1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(txt_FilesCount, javax.swing.GroupLayout.PREFERRED_SIZE, 198, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(btn_StartScan)
.addContainerGap(31, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 170, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel2)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(txt_ScannedDirectory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(btn_SelectDirectory)))
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel1)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(txt_FilesCount, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(btn_StartScan)))
.addContainerGap(48, Short.MAX_VALUE))
);
pack();
}//
private void btn_SelectDirectoryActionPerformed(java.awt.event.ActionEvent evt) {
JFileChooser fc = new JFileChooser();
fc.setDialogTitle("Select Directory");
//fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
int returnVal = fc.showOpenDialog(FileMonitorTest.this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
txt_ScannedDirectory.setText(file.getPath());
}
else {
}
}
private void btn_StartScanActionPerformed(java.awt.event.ActionEvent evt) {
String directory = txt_ScannedDirectory.getText();
FileMonitor fileMonitor = new FileMonitor(directory, 100);
tableModel = new FileTableModel(new File(directory));
fileMonitor.addListener((FileListener)tableModel);
fileMonitor.start(true);
jTable1.setModel(tableModel);
tableModel.addTableModelListener(new TableModelListener() {
public void tableChanged(TableModelEvent e) {
if(tableModel.getRowCount()>0){
txt_FilesCount.setText(String.valueOf(tableModel.getRowCount()));
}
else{
txt_FilesCount.setText("shit,have nothing in it!");
}
}
});
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new FileMonitorTest().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JButton btn_SelectDirectory;
private javax.swing.JButton btn_StartScan;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTable jTable1;
private javax.swing.JTextField txt_FilesCount;
private javax.swing.JTextField txt_ScannedDirectory;
// End of variables declaration
}