Symbian3/PDK/Source/GUID-204627D4-3818-5DE7-8969-C335DBA5B153.dita
author Dominic Pinkman <Dominic.Pinkman@Nokia.com>
Thu, 11 Mar 2010 18:02:22 +0000
changeset 3 46218c8b8afa
parent 1 25a17d01db0c
child 5 f345bda72bc4
permissions -rw-r--r--
week 10 bug fix submission (SF PDK version): Bug 1892, Bug 1897, Bug 1319. Also 3 or 4 documents were found to contain code blocks with SFL, which has been fixed. Partial fix for broken links, links to Forum Nokia, and the 'Symbian platform' terminology issues.

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
<!-- This component and the accompanying materials are made available under the terms of the License 
"Eclipse Public License v1.0" which accompanies this distribution, 
and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
<!-- Initial Contributors:
    Nokia Corporation - initial contribution.
Contributors: 
-->
<!DOCTYPE concept
  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
<concept xml:lang="en" id="GUID-204627D4-3818-5DE7-8969-C335DBA5B153"><title>File management with CFileMan</title><prolog><metadata><keywords/></metadata></prolog><conbody><ul><li id="GUID-848AF5C4-9EC6-566C-BE5F-7901D0E89573"><p> <xref href="GUID-204627D4-3818-5DE7-8969-C335DBA5B153.dita#GUID-204627D4-3818-5DE7-8969-C335DBA5B153/GUID-BE295C9C-37BC-5CCE-9957-4DD5D0DF0672">Overview</xref>  </p> </li> <li id="GUID-64A906F7-3FF5-5B13-903C-938A55574E47"><p> <xref href="GUID-204627D4-3818-5DE7-8969-C335DBA5B153.dita#GUID-204627D4-3818-5DE7-8969-C335DBA5B153/GUID-EC9DAE8B-FB85-5E7F-925F-B03D2F1D584D">Using CFileMan</xref>  </p> </li> <li id="GUID-6D2CF059-A571-5C12-86DD-43211876F9BF"><p> <xref href="GUID-204627D4-3818-5DE7-8969-C335DBA5B153.dita#GUID-204627D4-3818-5DE7-8969-C335DBA5B153/GUID-41F2D8B1-8350-533F-B8BA-4583A6E1C695">Notes</xref>  </p> </li> </ul> <section id="GUID-BE295C9C-37BC-5CCE-9957-4DD5D0DF0672"><title>Overview</title> <p>The <xref href="GUID-82CEC14F-1479-3922-846A-9FCDB6465EF7.dita"><apiname>CFileMan</apiname></xref> class provides file management functionality, but unlike the corresponding functionality provided by class <xref href="GUID-E263C747-946F-35AA-9F1D-41833BD350FC.dita"><apiname>RFs</apiname></xref>, <codeph>CFileMan</codeph> can operate on files and directories located throughout a directory hierarchy. </p> <p> <codeph>CFileMan</codeph> lets you: </p> <ul><li id="GUID-009066F1-2047-5BEF-A3A0-FB4FC341753D"><p>copy files </p> </li> <li id="GUID-4777CAC8-8537-5AF6-87D0-D9C2AAE9DAB4"><p>move files </p> </li> <li id="GUID-7DA9BBBD-49E8-59F4-8A7C-B6C8D06FA981"><p>delete files </p> </li> <li id="GUID-03AF9640-CAC3-58F0-9FB3-A9227505D50B"><p>rename files </p> </li> <li id="GUID-44356ACA-0562-5B1D-BFE6-3ED20275FFBA"><p>delete directories and their contained files and sub-directories </p> </li> <li id="GUID-7703AEF1-64EE-54C5-8DD5-6F5D67B59A68"><p>set and clear file attributes. </p> </li> </ul> <p>The functions provided by the class accept the use of wildcards, and means that some operations may take time to complete. The class, however, provides both synchronous and asynchronous variants. </p> <p>All of the file manipulation functions except <codeph>Rename()</codeph> can operate recursively, and all can operate non-recursively. When operating recursively, these functions will act on all matching files located throughout the source directory's hierarchy. When operating non-recursively, these functions act upon files contained in the single top level source directory only. Recursion is set or unset using the switch parameter to these functions. </p> </section> <section id="GUID-EC9DAE8B-FB85-5E7F-925F-B03D2F1D584D"><title>Using CFileMan</title> <p>Typically, a <xref href="GUID-82CEC14F-1479-3922-846A-9FCDB6465EF7.dita"><apiname>CFileMan</apiname></xref> operation can result in a number of file/directory manipulation operations, especially if wild cards are used. Some operations, such as copying files, can take a (relatively) long time, especially if such files are large. </p> <p>Symbian OS provides a file notification observer interface that you can implement to provide notification of events resulting from <codeph>CFileMan</codeph> operations. The interface is defined by the <xref href="GUID-E608485F-B3E3-3310-A80E-169D8B9D2234.dita"><apiname>MFileManObserver</apiname></xref> class, and you provide an implementation for the functions: </p> <ul><li id="GUID-EFEAD891-17C8-56E9-9D1B-89E26CC60AD4"><p> <xref href="GUID-E608485F-B3E3-3310-A80E-169D8B9D2234.dita#GUID-E608485F-B3E3-3310-A80E-169D8B9D2234/GUID-54D77B42-2AD9-3F82-89A7-3E651FAC2670"><apiname>MFileManObserver::NotifyFileManStarted()</apiname></xref>  </p> </li> <li id="GUID-012EAF53-723B-5A60-822B-B33F8BEE3F1B"><p> <xref href="GUID-E608485F-B3E3-3310-A80E-169D8B9D2234.dita#GUID-E608485F-B3E3-3310-A80E-169D8B9D2234/GUID-8D17D294-DE4A-3382-A832-9D318F522DE6"><apiname>MFileManObserver::NotifyFileManOperation()</apiname></xref>  </p> </li> <li id="GUID-41626506-7665-5931-A3BA-931A863486AC"><p> <xref href="GUID-E608485F-B3E3-3310-A80E-169D8B9D2234.dita#GUID-E608485F-B3E3-3310-A80E-169D8B9D2234/GUID-A73812AF-0877-3322-90C9-8A8F43708C8E"><apiname>MFileManObserver::NotifyFileManEnded()</apiname></xref>. </p> </li> </ul> <p>Symbian OS calls the notification functions before or after each file or directory entry has been processed, or during a file copy or move operation. You can use the notification to provide information about the state of the operation, such as error codes, the names of the target and destination files, and the number of bytes transferred during a copy operation. This information is available to your implementation by calling the public functions in <xref href="GUID-82CEC14F-1479-3922-846A-9FCDB6465EF7.dita"><apiname>CFileMan</apiname></xref> and its base class <xref href="GUID-C1C0C7F9-2665-3475-B70F-61C41291BB4D.dita"><apiname>CFileBase</apiname></xref>: </p> <ul><li id="GUID-F374F903-8456-57E0-B990-50ADEDB62CC8"><p> <xref href="GUID-C1C0C7F9-2665-3475-B70F-61C41291BB4D.dita#GUID-C1C0C7F9-2665-3475-B70F-61C41291BB4D/GUID-5EAB13D4-F93B-388B-92DE-F1987FBF2967"><apiname>CFileBase::GetLastError()</apiname></xref>  </p> </li> <li id="GUID-473260BD-F9E1-54B2-BB2B-6D0DB397B774"><p> <xref href="GUID-C1C0C7F9-2665-3475-B70F-61C41291BB4D.dita#GUID-C1C0C7F9-2665-3475-B70F-61C41291BB4D/GUID-96D7B25A-DFF6-3D30-86E0-1393EE0EA301"><apiname>CFileBase::GetMoreInfoAboutError()</apiname></xref>  </p> </li> <li id="GUID-86E140C6-A65E-524D-B40C-8D22A3174217"><p> <xref href="GUID-82CEC14F-1479-3922-846A-9FCDB6465EF7.dita#GUID-82CEC14F-1479-3922-846A-9FCDB6465EF7/GUID-4D489875-CAAB-3022-BE81-DF53B961BD9E"><apiname>CFileMan::CurrentAction()</apiname></xref>  </p> </li> <li id="GUID-18116CCF-BEF7-5B47-B6C8-F08C8E2DE8D2"><p> <xref href="GUID-82CEC14F-1479-3922-846A-9FCDB6465EF7.dita#GUID-82CEC14F-1479-3922-846A-9FCDB6465EF7/GUID-9DB0E0B7-7100-3FB1-81FA-1075E6E9E609"><apiname>CFileMan::GetCurrentTarget()</apiname></xref>  </p> </li> <li id="GUID-F3100AE7-4234-5B9C-9F29-C46EC74B6408"><p> <xref href="GUID-82CEC14F-1479-3922-846A-9FCDB6465EF7.dita#GUID-82CEC14F-1479-3922-846A-9FCDB6465EF7/GUID-CF653BC4-8480-3774-AD87-05E4DDCBC1DE"><apiname>CFileMan::GetCurrentSource()</apiname></xref>  </p> </li> <li id="GUID-F2C0B561-6E6C-5223-8428-026D56125807"><p> <xref href="GUID-82CEC14F-1479-3922-846A-9FCDB6465EF7.dita#GUID-82CEC14F-1479-3922-846A-9FCDB6465EF7/GUID-351464A4-E108-39C4-9F40-6C099DC89F0A"><apiname>CFileMan::BytesTransferredByCopyStep()</apiname></xref>  </p> </li> </ul> <p>You can also use the notification function to cancel, retry or continue processing a file or directory, or to abort the whole operation, by returning a suitable <xref href="GUID-E608485F-B3E3-3310-A80E-169D8B9D2234.dita#GUID-E608485F-B3E3-3310-A80E-169D8B9D2234/GUID-077D82DD-0D4F-38DB-B2F9-EDE6806DBA7A"><apiname>MFileManObserver::TControl</apiname></xref> value. </p> <p>This mechanism provides a way for an application to provide feedback, or to give control over such operations to an end-user through its user interface. </p> <p><b>Example code (1)</b> </p> <p>The following example code shows how you might use this. It is not a complete example, but it gives you an idea of what's possible. The example attempts to copy all files from directory <filepath>C:\path1</filepath> to <filepath>c:\path2</filepath> synchronously. </p> <p>You would need to elaborate on this to make it part of a real application, and you would probably need the use of active objects, especially if using the asynchronous versions of the <codeph>CFileMan</codeph> functions. </p> <codeblock id="GUID-F23E9F4C-750D-5019-A38A-5A5EAF27DA48" xml:space="preserve">    ...
    _LIT(KSourcePath,"C:\\path1\\*.*");
    _LIT(KDestinationPath,"C:\\path2");

    // Connect session
    RFs fsSession;
    User::LeaveIfError(fsSession.Connect()); 
    
    // Create file management object
    CFileMan* fileMan = CFileMan::NewL(fsSession);
    CleanupStack::PushL(fileMan); 

    // Create file management notification object and set to observe
    TFileCopyProgressMonitor fileCopyProgressMonitor(*fileMan);
    fileMan-&gt;SetObserver(&amp;fileCopyProgressMonitor);
    
    // Do copy (here synchronously)
    fileMan-&gt;Copy(KSourcePath,KDestinationPath);
    
    // Clean up
    CleanupStack::PopAndDestroy(); 
    
    // close file server session
    fsSession.Close();
    ...
    </codeblock> <codeblock id="GUID-FD9D41C0-EF79-5F5A-92FE-E4128E652B5A" xml:space="preserve">class TFileCopyProgressMonitor : public MFileManObserver
    {
public :
    TFileCopyProgressMonitor(CFileMan&amp; aFileMan);
public : // implement the interface
    TControl NotifyFileManStarted();
    TControl NotifyFileManOperation();
    TControl NotifyFileManEnded();
public :
    CFileMan&amp; iFileMan;
    }
     </codeblock> <codeblock id="GUID-3DFCEC35-FDCE-57AC-B940-4F6A5467246D" xml:space="preserve">TFileCopyProgressMonitor::TFileCopyProgressMonitor(CFileMan&amp; aFileMan)
    :iFileMan(aFileMan)
    {    
    }

// Called when a copy operation started
MFileManObserver::TControl TFileCopyProgressMonitor::NotifyFileManStarted()
    {
    TFileName&amp; aFile
    
    // Get name of file we are copying.
    // you might want to do something with this, such as display in a UI,
    // or save in a data member of this object for later use.
    iFileMan.GetCurrentSource(aFile);

    // Allow the operation to continue.
    return EContinue;
    }

// Called while a copy operation is in progress
MFileManObserver::TControl TFileCopyProgressMonitor::NotifyFileManOperation()
    {
    TInt bytesTransferred;
    
    // number of bytes copied so far for the file. 
    bytesbytesTransferred = iFileMan.BytesTransferredByCopyStep();
    
    // Allow the operation to continue.
    // You would choose to do something different; for example, you could 
    // return ECancel to cancel the operation if you had a reason to do so,
    return EContinue;
    }
    
// Called when a copy operation is complete
MFileManObserver::TControl TFileCopyProgressMonitor::NotifyFileManEnded()
    {
    TInt lasterror;
    
    // Allow operations to continue if all is well. 
    lasterror = iFileMan.GetLastError();
    if (lasterror == KErrNone)
        {
        return EContinue;
        }
    
    // Operation has not completed properly, so you might want to get
    // more information, and proceed accordingly.
    TFileManError filemanerror;
    
    filemanerror = iFileMan.GetMoreInfoAboutError();
    if (filemanerror==ESrcOpenFailed)
        {
        ...
        return EAbort;
        }
        
    if (filemanerror==ETrgOpenFailed)
        {
        ...
        return EAbort;
        }
      
    ... // you might want to check for other conditions etc.
    }
     </codeblock> <p><b>Example code (1)</b> </p> <p>This code fragment shows a use of the <xref href="GUID-82CEC14F-1479-3922-846A-9FCDB6465EF7.dita#GUID-82CEC14F-1479-3922-846A-9FCDB6465EF7/GUID-53411800-9145-38CA-8C8C-B8C6F97E8FEE"><apiname>CFileMan::Attribs()</apiname></xref> functions. </p> <codeblock id="GUID-DFE5FD10-DDCC-5882-A8C1-256B3CB5E42B" xml:space="preserve">_LIT(KDirText,"\\TopDir\\");
...
fileMan.Attribs(KDirText,KEntryAttHidden|KEntryAttReadOnly,
    KEntryAttArchive,TTime(0),CFileMan::ERecurse);
...</codeblock> <p>This sets the hidden and read-only attributes, and clears the archive attribute for all files located in the hierarchy below <filepath>\TopDir\</filepath>. The time of their last modification will be unchanged. </p> </section> <section id="GUID-41F2D8B1-8350-533F-B8BA-4583A6E1C695"><title>Notes</title> <ol id="GUID-D1790FF2-8C3C-55ED-98D8-D095227D5B83"><li id="GUID-602606F3-D537-580F-BEB7-1E25F1760B8A"><p>If you use <xref href="GUID-82CEC14F-1479-3922-846A-9FCDB6465EF7.dita#GUID-82CEC14F-1479-3922-846A-9FCDB6465EF7/GUID-9456C8B9-C975-356C-B3A4-755928DE2AC3"><apiname>CFileMan::Move()</apiname></xref>, be aware that the behaviour of this operation is sensitive to the presence (or absence) of a trailing backslash ("\") character on the end of the source path: </p> <ul><li id="GUID-E542B9BE-888B-55DE-95A1-A9B00810FD11"><p>if there is a trailing backslash ("\") character, then the operation moves the content of the last directory level only. </p> </li> <li id="GUID-C6A158E1-612C-596D-8C26-88377E3B7AC1"><p>if there is no trailing backslash ("\") character, then the operation moves both the last directory level and its content, but note that you also need to specify <xref href="GUID-82CEC14F-1479-3922-846A-9FCDB6465EF7.dita#GUID-82CEC14F-1479-3922-846A-9FCDB6465EF7/GUID-8FD6F114-0D4C-3701-ACCF-4748129B1F79"><apiname>CFileMan::ERecurse</apiname></xref> in the switches passed to the function. </p> </li> </ul> <p>For example, if the directory level "b" contains the files <filepath>F1</filepath>, <filepath>F2</filepath> and <filepath>F3</filepath>, then: </p> <codeblock id="GUID-A08081B3-213E-527D-B413-42A05B54CF0D" xml:space="preserve">CFileMan fm;
...
fm-&gt;Move(_L("C:\a\b\"), _L("C:\x\y\"), CFileMan::ERecurse);</codeblock> <p>results in files <filepath>F1</filepath>, <filepath>F2</filepath> and <filepath>F3</filepath> being moved from <filepath>C:\a\b</filepath> to <filepath>C:\x\y</filepath>, leaving the path <filepath>C:\a\b</filepath> unchanged, except that it no longer contains the files <filepath>F1</filepath>, <filepath>F2</filepath> and <filepath>F3</filepath>. </p> <p>If there is no trailing backslash character, for example: </p> <codeblock id="GUID-6A5A2B8F-67C4-5278-9A43-FDFC5D849C78" xml:space="preserve">CFileMan fm;
...
fm-&gt;Move(_L("C:\a\b"), _L("C:\x\y\"), CFileMan::ERecurse);</codeblock> <p>then both the directory level "b" and its contents are moved. This means that there is no longer a directory "b" under <filepath>C:\\a</filepath>. Instead there is a new directory structure <filepath>C:\x\y\b</filepath> and the files <filepath>F1</filepath>, <filepath>F2</filepath> and <filepath>F3</filepath> now exist under <filepath>C:\x\y\b</filepath>. Also if "b" contains subdirectories, then these are also moved along with "b". </p> </li> <li id="GUID-3CAC4CA6-AB36-56AC-81AB-032DF70D99B7"><p>If you use <xref href="GUID-82CEC14F-1479-3922-846A-9FCDB6465EF7.dita#GUID-82CEC14F-1479-3922-846A-9FCDB6465EF7/GUID-633C2FF5-4077-346D-B7B6-4CC04F887D7B"><apiname>CFileMan::Copy()</apiname></xref>, the behaviour of this function does <i>not</i> depend on the presence or absence of a trailing backslash ("\") character on the end of the source path. This pattern of behaviour is in <i>contrast</i> to that of <xref href="GUID-82CEC14F-1479-3922-846A-9FCDB6465EF7.dita#GUID-82CEC14F-1479-3922-846A-9FCDB6465EF7/GUID-9456C8B9-C975-356C-B3A4-755928DE2AC3"><apiname>CFileMan::Move()</apiname></xref>. You can only copy the content of the source path. You cannot request that the last directory level plus its content be copied to the target path, by adding a trailing backslash ("\") character onto the end of the source path. This means that both of the following copy operations produce identical results: </p> <codeblock id="GUID-75B4FA7B-BB08-5322-A8C6-ACFD4C860D1D" xml:space="preserve">CFileMan fm;
...
fm-&gt;Copy(_L("C:\a\b\"), _L("C:\x\y\"), CFileMan::ERecurse);
fm-&gt;Copy(_L("C:\a\b"), _L("C:\x\y\"), CFileMan::ERecurse);</codeblock> </li> <li id="GUID-A17CB3FD-39BA-5D57-816B-1AB70C746E3F"><p>It is possible to pass <xref href="GUID-5A096F1A-B316-3B40-BB4B-F9F12099DC91.dita"><apiname>KNullDesC</apiname></xref>, the null (or empty) descriptor, to the <xref href="GUID-82CEC14F-1479-3922-846A-9FCDB6465EF7.dita#GUID-82CEC14F-1479-3922-846A-9FCDB6465EF7/GUID-71056B22-AC2A-3E91-8896-8A6F2FB9B619"><apiname>CFileMan::Delete()</apiname></xref> functions as the path name. Although you might expect these functions to treat this as a null request, i.e. to delete nothing, they interpret the null descriptor as the string <filepath>\*.*</filepath>. </p> </li> </ol> </section> </conbody></concept>