Categories: Symbian C++ | How To | Code Examples | Files/Data | S60
This page was last modified 16:01, 16 March 2008.
Directory Monitoring
From Forum Nokia Wiki
This code is to monitor for file changes (added, erased) in a particular directory.
| ID | Creation date | March 12, 2008 | |
| Platform | S60 3rd Edition S60 3rd Edition, FP1 | Tested on devices | N73 |
| Category | Symbian C++ | Subcategory | File/Data |
| Keywords (APIs, classes, methods, functions): |
Contents |
Overview
This code shows how to monitor for file changes (added/erased) in a particular directory. There is also an application showing how to use the code Source Code
This snippet can be self-signed.
MMP file (optional)
The following capabilities and libraries are required:
CAPABILITY ReadUserData
Header file
/* ============================================================================ Name : DirectoryMonitor.h Author : Olympio Cipriano Version : 1.0 Copyright : Description : CDirectoryMonitor declaration ============================================================================ */ #ifndef CDirectoryMonitor_H #define CDirectoryMonitor_H #include <e32base.h> // For CActive, link against: euser.lib #include <e32std.h> // For RTimer, link against: euser.lib #include <f32file.h> enum TFileAction { EFileErased, EFileAdded }; class DirectoryObserver { public: virtual void DirectoryChanged( const TDesC& aFileName, TFileAction aAction ) = 0; }; class CDirectoryMonitor : public CActive { public: // Cancel and destroy ~CDirectoryMonitor(); // Two-phased constructor. static CDirectoryMonitor* NewL( DirectoryObserver * iObserver ); // Two-phased constructor. static CDirectoryMonitor* NewLC(DirectoryObserver * iObserver ); public: // New functions // Function for making the initial request void Monitor( const TDesC& aDirPath ); private: // C++ constructor CDirectoryMonitor( DirectoryObserver* aObserver ); // Second-phase constructor void ConstructL(); //directory internals void ListFiles( CDir*& aDir ); void DiffDirectoryContents( ); bool SearchEntry( const TEntry& aEntry, CDir* aDir ); void Clean(); private: // From CActive // Handle completion void RunL(); // How to cancel me void DoCancel(); // Override to handle leaves from RunL(). Default implementation causes // the active scheduler to panic. TInt RunError(TInt aError); struct TFileChange { TFileChange(const TEntry aEntry, TFileAction aAction) :fileEntry(aEntry),action(aAction){} const TEntry fileEntry; TFileAction action; }; private: enum TCDirectoryMonitorState { EUninitialized, // Uninitialized EInitialized, // Initalized EError // Error condition }; private: TInt iState; // State of the active object RFs iFs; DirectoryObserver* iObserver; CDir* iOldDir; CDir* iNewDir; RArray<TFileChange> iFileChangeArray; RArray<TEntry> iFileList; HBufC* iPath; }; #endif // CDirectoryMonitor_H
Source file
/* ============================================================================ Name : DirectoryMonitor.cpp Author : Olympio Cipriano Version : 1.0 Copyright : Description : CDirectoryMonitor implementation ============================================================================ */ #include "DirectoryMonitor.h" CDirectoryMonitor::CDirectoryMonitor( DirectoryObserver* aObserver ) : CActive(EPriorityStandard), iObserver( aObserver ) { } CDirectoryMonitor* CDirectoryMonitor::NewLC( DirectoryObserver* aObserver ) { CDirectoryMonitor* self = new ( ELeave ) CDirectoryMonitor( aObserver ); CleanupStack::PushL(self); self->ConstructL(); return self; } CDirectoryMonitor* CDirectoryMonitor::NewL( DirectoryObserver* aObserver ) { CDirectoryMonitor* self = CDirectoryMonitor::NewLC( aObserver ); CleanupStack::Pop(); // self; return self; } void CDirectoryMonitor::ConstructL() { User::LeaveIfError( iFs.Connect() ); CActiveScheduler::Add( this ); // Add to scheduler iPath = HBufC16::NewL(100); } CDirectoryMonitor::~CDirectoryMonitor() { Cancel(); // Cancel any request, if outstanding iFs.Close(); iFileChangeArray.Close(); if( iOldDir ) delete iOldDir; if( iNewDir ) delete iNewDir; if( iPath ) delete iPath; } void CDirectoryMonitor::DoCancel() { iFs.NotifyChangeCancel( iStatus ); } void CDirectoryMonitor::Monitor( const TDesC& aDirPath ) { *iPath = aDirPath; Cancel(); // Cancel any request, just to be sure iState = EUninitialized; iFs.NotifyChange( ENotifyFile, iStatus, *iPath ); ListFiles( iOldDir ); SetActive(); // Tell scheduler a request is active } void CDirectoryMonitor::RunL() { TInt err = iStatus.Int(); if ( err == KErrNone ) { ListFiles( iNewDir ); DiffDirectoryContents( ); if( iObserver ) for (int i = 0; i < iFileChangeArray.Count(); ++i) { TFileChange changeEntry = iFileChangeArray[i]; iObserver->DirectoryChanged( changeEntry.fileEntry.iName, changeEntry.action ); } Clean(); iFs.NotifyChange( ENotifyEntry, iStatus, *iPath ); SetActive(); // Tell scheduler a request is active } } TInt CDirectoryMonitor::RunError(TInt aError) { return aError; } void CDirectoryMonitor::ListFiles( CDir*& aDir ) { if( aDir ) { delete aDir; aDir = 0; } TInt err = iFs.GetDir( *iPath, KEntryAttNormal, ESortByName, aDir ); if( err ) { //TODO: error handling } } void CDirectoryMonitor::DiffDirectoryContents( ) { for (int i = 0; (iOldDir != NULL) && (i < iNewDir->Count()); ++i) { const TEntry entry = (const TEntry& )(*iNewDir)[i]; if( ! SearchEntry( entry, iOldDir ) ) { //file added TFileChange change(entry,EFileAdded); iFileChangeArray.Append( change ); } } for (int i = 0; ( iOldDir != NULL ) && ( i < iOldDir->Count() ); ++i) { const TEntry entry = (const TEntry& )(*iOldDir)[i]; if( ! SearchEntry( entry, iNewDir ) ) { //file added TFileChange change(entry,EFileErased); iFileChangeArray.Append( change ); } } } bool CDirectoryMonitor::SearchEntry( const TEntry& aEntry, CDir * aDir ) { for (int i = 0; ( aDir != NULL ) && ( i < aDir->Count() ); ++i) { const TEntry& dirEntry = (const TEntry& ) (*aDir)[i]; TDesC& entryName = (TDesC&) dirEntry.iName; if ( entryName.Compare( aEntry.iName ) == 0 ) return true; } return false; } void CDirectoryMonitor::Clean() { if( iNewDir ) { delete iNewDir; iNewDir = 0; } iFileChangeArray.Reset(); ListFiles( iOldDir ); } //end line
Postconditions
This code monitors a specific folder. A call to Monitor member funcion starts the monitoring process. The changes to be monitored are those occurred after the call to Monitor function.
Test application and other attachments
Directory Monitor Source Code: Image:DirectoryMonitoring.zip
| Related Discussions | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| how to pass specific gcc options | urrg | Symbian Tools & SDKs | 3 | 2004-07-02 08:04 |
| Install JRE on 7610 | mobiletask | Mobile Java General | 4 | 2004-10-21 08:38 |
| Project offer - 1 euro (was: 2 Programs @ the same time) | marsiboy123 | General Symbian C++ | 149 | 2008-06-19 20:12 |
| Carbide.c++ 1.3 build error EPOC variable doesn't show to the existing directory. | ashmodeus | Symbian Tools & SDKs | 4 | 2008-04-09 20:15 |
| Detecting battery level with Javaphone API | cassioli | Mobile Java General | 17 | 2007-03-19 20:16 |
