IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
logo
Sommaire > Fichiers,Parcours,Recherche,Existence
        Comment savoir si un fichier existe ?
        Comment faire une sélection d'un répertoire de destination?
        Comment sélectionner un fichier dans un répertoire ?
        Comment rechercher des fichiers ?
        Comment retrouver le répertoire courant ?
        Comment changer le répertoire courant ?
        Comment récupérer le répertoire Windows ?
        Comment scanner les unités d'un poste de travail ?
        Comment détecter le type de système de fichiers d'un disque ?
        Comment déterminer les répertoires spéciaux ?
        Comment afficher la date de création d'un fichier ?
        Comment supprimer un répertoire non vide ?
        Comment vérifier qu'un chemin de fichier existe ?
        Comment calculer l'espace disque disponible sur un lecteur ?
        Quelles sont les différentes méthodes pour manipuler un fichier ?
        Que choisir entre l'API Win32 et la surcouche MFC (CFile, CStdioFile) ?
        Dois-je créer un fichier binaire ou un fichier texte ?
        Comment déplacer le pointeur de fichier ?
        Comment lire tout mon fichier dans un buffer ?
        Comment lire et écrire dans un fichier en mode texte ?
        Comment lire et écrire dans un fichier en mode binaire ?
        Comment ouvrir/fermer le lecteur de CD (IOCTL)?
        Comment ouvrir/fermer le lecteur de CD (MCI)?
        Comment calculer la taille d'un répertoire et de ses sous-répertoires ?



Comment savoir si un fichier existe ?
auteur : Farscape
Avec la fonction _access :

int _access( const char *path, int mode );
Valeurs pour mode :

  • 00 : test de l'existence uniquement ;
  • 02 : permission d'écriture ;
  • 04 : permission lecture ;
  • 06 : permission lecture / écriture.

#include <io.h>
#include <errno.h>

//test si fichier existe
if((_access( "troll.c", 0 )) != -1 )
{
   printf( "Fichier troll.c existe\n" );
   // Pour permission d'écriture
   if( (_access( " troll.c ", 2 )) != -1 )
       printf( "le Fichier troll.c est ok pour l'écriture\n" );
}
else
{
     switch(errno)
     {
         case EACCES :printf("accès interdit\n ");
                                 break;
        case  ENOENT:printf("fichier ou chemin incorrect \n") ;
                                  break ;
      }
}

Comment faire une sélection d'un répertoire de destination?
auteur : Farscape
Avec la fonction SHBrowseForFolderA:
Exemple complet d'implémentation:

CString strTmpPath;
int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
{
    TCHAR szDir[MAX_PATH];
    switch(uMsg)
    {
        case BFFM_INITIALIZED:
        if (lpData)
        {
            strcpy(szDir, strTmpPath.GetBuffer(strTmpPath.GetLength()));
            SendMessage(hwnd,BFFM_SETSELECTION,TRUE,(LPARAM)szDir);
        }
        break;

        case BFFM_SELCHANGED:
        {
            if (SHGetPathFromIDList((LPITEMIDLIST) lParam ,szDir))
            {
              SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)szDir);        
            }
           break;

        }

        default:break;
    }         
    return 0;
}
//---------------------------------------------------------------------------------------------
BOOL GetFolder(CString* strSelectedFolder,
               const char* lpszTitle,
               const HWND hwndOwner, 
               const char* strRootFolder, 
               const char* strStartFolder)
{
    char pszDisplayName[MAX_PATH];
    LPITEMIDLIST lpID;
    BROWSEINFOA bi;

    bi.hwndOwner = hwndOwner;

    if (strRootFolder == NULL)
    {
        bi.pidlRoot = NULL;
    }
    else
    {
        LPITEMIDLIST  pIdl = NULL;
        IShellFolder* pDesktopFolder;
        char          szPath[MAX_PATH];
        OLECHAR       olePath[MAX_PATH];
        ULONG         chEaten;
        ULONG         dwAttributes;

        strcpy(szPath, (LPCTSTR)strRootFolder);
        if (SUCCEEDED(SHGetDesktopFolder(&pDesktopFolder)))
        {
            MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szPath, -1, olePath, MAX_PATH);
            pDesktopFolder->ParseDisplayName(NULL, NULL, olePath, &chEaten, &pIdl, &dwAttributes);
            pDesktopFolder->Release();
        }
        bi.pidlRoot = pIdl;
    }
    bi.pszDisplayName = pszDisplayName;
    bi.lpszTitle = lpszTitle;

#if _MFC_VER < 0x0700
    bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT;
#else
    bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT |BIF_NEWDIALOGSTYLE;
    OleInitialize(NULL);
#endif
    bi.lpfn = BrowseCallbackProc;
    if (strStartFolder == NULL)
    {
        bi.lParam = FALSE;
    }
    else
    {
        strTmpPath.Format("%s", strStartFolder);
        bi.lParam = TRUE;
    }
    bi.iImage = NULL;
    lpID = SHBrowseForFolderA(&bi);
    if (lpID != NULL)
    {
        BOOL b = SHGetPathFromIDList(lpID, pszDisplayName);
        if (b == TRUE)
        {
            strSelectedFolder->Format("%s",pszDisplayName);
            return TRUE;
        }
    }
    else
    {
        strSelectedFolder->Empty();
    }
    return FALSE;
}
utilisation:

CString strRepertoire="c:\\";
if(GetFolder(&strRepertoire,"Sélection du répertoire",this->m_hWnd, NULL, NULL))
{
     if (!strRepertoire.IsEmpty())
    {
    }
}
Une info intéressante pour rajouter un bouton de création de répertoire :

 bi.ulFlags= BIF_NEWDIALOGSTYLE; 
Le hic c'est que cette option fonctionne correctement à partir de Windows 2000 ,elle s'appuie sur shell32.dll et seulement la version 5.0 supporte cette nouvelle fonctionnalité.
Elle n'est pas disponible sous NT4,w95 ou 98 (traduction doc MSDN).
Il faudra rajouter à votre code

#ifndef BIF_NEWDIALOGSTYLE
#define BIF_NEWDIALOGSTYLE 0x0040
#endif

Comment sélectionner un fichier dans un répertoire ?
Mise à jour le 23/03/2008[haut]
auteur : Farscape
Avec la fonction GetOpenFileName:
Exemple d'implémentation complet:

#include <direct.h>
BOOL DlgSelFicName(CWnd *pParent,CString& rstrFileName,LPCTSTR pszExt,BOOL bUnlink=FALSE)
{
    #define MAXPATH 256
    char szDrive[_MAX_DRIVE];
    char szDir[_MAX_DIR];
    char szFname[_MAX_FNAME];
    char szExt[_MAX_EXT];

    OPENFILENAME ofn;
    char szFileBuf[MAXPATH];
    char    szpathDir[128],*pszPath=NULL,
    szbufDir[128];
    CString strRet;

    pszPath=(char *)_getcwd(NULL,127);

    szFileBuf[0] = 0;

    if(!rstrFileName.IsEmpty())
    {
        _splitpath((const char *)rstrFileName, szDrive, szDir, szFname, szExt);
        strcpy(szpathDir,szDrive);
        strcat(szpathDir,szDir);
        strcpy(szFileBuf,szFname);
        strcat(szFileBuf,szExt);
     }
    else
    {
        strRet=AfxGetApp()->GetProfileString( "OpenFileName","Path","");
        strcpy(szbufDir,strRet);
        if(strlen(szbufDir)) strcpy(szpathDir,szbufDir);
        else strcpy(szpathDir,pszPath);
    }
    ofn.lStructSize = sizeof(OPENFILENAME);
    ofn.hwndOwner =(pParent?pParent->GetSafeHwnd():NULL);
    ofn.lpstrFilter =pszExt;
    ofn.lpstrCustomFilter = NULL;
    ofn.nFilterIndex = 0;
    ofn.lpstrFile = szFileBuf;
    ofn.nMaxFile = MAXPATH;
    ofn.lpstrFileTitle = NULL;
    ofn.lpstrInitialDir = szpathDir;
    ofn.lpstrTitle = NULL;
    ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST;
    ofn.lpstrDefExt = NULL;

    rstrFileName="";
    BOOL bOK=FALSE;
    if (GetOpenFileName(&ofn))
    {
        CString e;
        _splitpath(szFileBuf, szDrive, szDir, szFname, szExt);
        sprintf(szpathDir,"%s%s",szDrive,szDir);
        AfxGetApp()->WriteProfileString("OpenFileName","Path",szpathDir);
        sprintf(szFileBuf,"%s%s%s",szDrive,szDir,(strlen(szFname)?szFname:""));

        e=pszExt;
        e=e.Right(5);
        e=e.Left(4);

        strcat(szFileBuf,(strlen(szExt)?szExt:e));
        rstrFileName=szFileBuf;
        if(bUnlink) _unlink(szFileBuf);
        bOK=TRUE;
    }
    else rstrFileName="";
    if(pszPath)
    {
        _chdir(pszPath);
        free(pszPath);
    }
    return bOK;
}
Utilisation

CString strFileName;
::DlgSelFicName(this,strFileName,"Fichiers Txt (*.txt)\0*.txt\0");
// ou multi extensions
::DlgSelFicName(this,strFileName,
"Fichiers Texte (*.txt)\0*.txt\0Fichiers csv (*.csv)\0*.csv\0Fichiers tabulations (*.txt)\0*.txt\0");

Comment rechercher des fichiers ?
auteur : Abelman
Affiche tous les fichiers et répertoires en utilisant le filtre c:\*.*
La première version est avec les MFC:

CFileFind f;
BOOL bMoreFiles = f.FindFile("c:\\*.*");
while (bMoreFiles)
{
    bMoreFiles = f.FindNextFile();
    if (f.IsDirectory())
    cout << (LPCSTR)f.GetFileName() << " : Repertoire" << endl;
    else
    cout << (LPCSTR)f.GetFileName() << " : Taille=" << f.GetLength() << endl;
}
version sans les MFC

WIN32_FIND_DATA data;
HANDLE h = FindFirstFile("c:\\*.*", &data);
BOOL bMoreFiles =  (h != INVALID_HANDLE_VALUE);
while (bMoreFiles)
{
    if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
    cout << data.cFileName << " : Repertoire" << endl;
    else
    cout << data.cFileName << " : Taille=" << (data.nFileSizeHigh * MAXDWORD) + data.nFileSizeLow << endl;
    bMoreFiles = FindNextFile(h, &data);
}
if (GetLastError() != ERROR_NO_MORE_FILES)
    cout << "erreur  = " << GetLastError() << endl;
if (h!= INVALID_HANDLE_VALUE) FindClose(h);

Comment retrouver le répertoire courant ?
auteur : Farscape

TCHAR szDir[MAX_PATH] = "";
if(!::GetCurrentDirectory(sizeof(szDir) - 1, szDir))
{
  // ::GetLastError()
}

Comment changer le répertoire courant ?
auteur : Farscape

if(::SetCurrentDirectory("c:\\MyProjects\\Dvp") == FALSE)
{
  // GetLastError()
}

Comment récupérer le répertoire Windows ?
auteur : Farscape

TCHAR szWindDir[MAX_PATH] = "";
UINT nRetLen = ::GetWindowsDirectory(szWindDir, sizeof(szWindDir));
if(!nRetLen)
{
  // Erreur voir ::GetLastError()
}
else if(nRetLen > sizeof(szWindDir))
{
  // buffer trop petit.
}
else
{
  // ok!
}

Comment scanner les unités d'un poste de travail ?
auteur : Farscape
Le petit exemple ci-dessus explore les lettres de B à Z et récupère L'information concernant l'unité trouvée,
Les lecteurs réseaux sont aussi détectés et reconnectés le cas échéant.

void ExploreDrives()
{
    char let,szbuf[5];
    int nError;
    char szRemote[256];
    DWORD l=255;
    short int *pt=NULL;
    CString str;
    UINT ntyp;
    for(let='B';let<='Z';let++)
    {
        sprintf(szbuf,"%c:",let);
        if((nError=WNetGetConnection(szbuf,szRemote,&l))==NO_ERROR)
        {
            TRACE("\nWnet:%s",szRemote);
        }
        else 
        {
            str.Format("%c:\\",let);
            ntyp=GetDriveType(str);
            TRACE("\nDrive :%s :%d"",(const char *)str,ntyp);
            if(ntyp==DRIVE_CDROM)
            {
                // 
                continue;
            }
            if(ntyp==DRIVE_REMOVABLE)
            {
                // 
                continue;
            }
            if(ntyp==DRIVE_FIXED)
            {
                // 
                continue;
            }
            else
            // tentative de reconnection lettre reseau
            if(nError==ERROR_CONNECTION_UNAVAIL)
            {
                if(WNetAddConnection(szRemote,NULL,szbuf)==NO_ERROR)
                {
                    // si pas d'erreur
                    
                }
            }
        }
    }
}

Comment détecter le type de système de fichiers d'un disque ?
auteur : Farscape
il faut utiliser l'api32 : GetVolumeInformation le type de fat est chargé dans la zone lpFileSystemNameBuffer

BOOL GetVolumeInformation(
  LPCTSTR lpRootPathName,           // root directory
  LPTSTR lpVolumeNameBuffer,        // volume name buffer
  DWORD nVolumeNameSize,            // length of name buffer
  LPDWORD lpVolumeSerialNumber,     // volume serial number
  LPDWORD lpMaximumComponentLength, // maximum file name length
  LPDWORD lpFileSystemFlags,        // file system options
  LPTSTR lpFileSystemNameBuffer,    // file system name buffer
  DWORD nFileSystemNameSize         // length of file system name buffer
);
Exemple:

BOOL bSuccess;
char szVolName[MAX_PATH];
DWORD dwVolSerialNumber;
DWORD dwMaxNameLength;
DWORD dwFileSystemFlags;
char szSystemName[MAX_PATH];

bSuccess= GetVolumeInformation("c:\\",
szVolName,MAX_PATH,
&dwVolSerialNumber,
&dwMaxNameLength,
&dwFileSystemFlags,
szSystemName,MAX_PATH);

   cout << "Nom du volume " << szVolName << endl;
   cout << "Numero de serie " << dwVolSerialNumber << endl;
   cout << "Systeme de Fichier " << szSystemName << endl;
   cout << "Longueur maximale d'un nom de fichier " << dwMaxNameLength << endl;

Comment déterminer les répertoires spéciaux ?
auteur : nico-pyright(c)
En utilisant SHGetSpecialFolderPath, la liste des attributs que l'on peut récupérer est disponible ici : http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/enums/csidl.asp

Voilà à titre d'exemple quelques emplacement spéciaux, pour récuperer le path de "mes documents" ou bien du bureau, etc ...
char mesDocumentsPath[MAX_PATH];
SHGetSpecialFolderPath(0,mesDocumentsPath,CSIDL_PERSONAL,0);

char applicationData[MAX_PATH];
SHGetSpecialFolderPath(0,applicationData,CSIDL_COMMON_APPDATA,0);

char bureau[MAX_PATH];
SHGetSpecialFolderPath(0,bureau,CSIDL_DESKTOPDIRECTORY,0);

char favoris[MAX_PATH];
SHGetSpecialFolderPath(0,favoris,CSIDL_FAVORITES,0);

char maMusique[MAX_PATH];
SHGetSpecialFolderPath(0,maMusique,CSIDL_MYMUSIC,0);

char mesImages[MAX_PATH];
SHGetSpecialFolderPath(0,mesImages,CSIDL_MYPICTURES,0);

char profile[MAX_PATH];
SHGetSpecialFolderPath(0,profile,CSIDL_PROFILE,0);

char programFiles[MAX_PATH];
SHGetSpecialFolderPath(0,programFiles,CSIDL_PROGRAM_FILES,0);

char sendTo[MAX_PATH];
SHGetSpecialFolderPath(0,sendTo,CSIDL_SENDTO,0);
Note: Si le dernier paramètre est positionné à 1, il permet de créer l'entrée.


Comment afficher la date de création d'un fichier ?
Créé le 19/09/2005[haut]
auteur : nico-pyright(c)
il y a plusieurs façons de le faire, le but étant d'obtenir une variable de type FILETIME correctement renseignée.
Voilà un exemple en utilisant l'API GetFileAttributesEx

char nomFichier[] = "test.txt";
WIN32_FILE_ATTRIBUTE_DATA attr;
FILETIME ftlocal;
SYSTEMTIME st;
GetFileAttributesEx( nomFichier, GetFileExInfoStandard, &attr);
FileTimeToLocalFileTime(&attr.ftCreationTime, &ftlocal);
FileTimeToSystemTime(&ftlocal, &st);

char date[50];
wsprintf(date,"%02d/%02d/%04d-%02d:%02d:%02d",
st.wDay,st.wMonth,st.wYear,st.wHour,st.wMinute,st.wSecond);
MessageBox(0,date,"Date de création du fichier",MB_ICONSTOP);
la structure WIN32_FILE_ATTRIBUTE_DATA nous donne aussi la possibilité d'utiliser
la date de dernier accès ftLastAccessTime
la date de derniere écriture ftLastWriteTime


Comment supprimer un répertoire non vide ?
Mise à jour le 22/01/2007[haut]
auteur : nico-pyright(c)
On peut éviter de faire une fonction récursive qui supprime tous les fichiers dans tous les répertoires en déléguant ceci aux fonctions Shell de l'API.
Ici en l'occurence, on se sert d'une fonctionnalité de l'API SHFileOperation.
#include <shellapi.h>

bool myDeleteDirectory(LPCTSTR repertoire, bool suppressionDefinitive = true)
{
    int s = strlen(repertoire);
    TCHAR * rep = new TCHAR[strlen(repertoire)+2];
    strcpy(rep, repertoire);
    rep[strlen(repertoire)+1] = '\0';
    SHFILEOPSTRUCT sh;
    sh.hwnd = NULL;
    sh.wFunc = FO_DELETE;
    sh.pFrom = rep;
    sh.pTo = NULL;
    sh.fFlags = FOF_NOCONFIRMATION|FOF_SILENT;
    if(!suppressionDefinitive)
        sh.fFlags |= FOF_ALLOWUNDO;
    sh.fAnyOperationsAborted = FALSE;
    sh.lpszProgressTitle = NULL;
    sh.hNameMappings = NULL;
    
    delete [] rep;
    return (SHFileOperation(&sh)==0);
}
   myDeleteDirectory("d:\\test", false);
NB : Prendre garde à ne pas utiliser de chemin relatif et à toujours utiliser un chemin absolu.
Sinon, cette utilisation n'est pas garantie et peut provoquer un comportement indéterminé.
On utilise une liste d'emplacements à supprimer, séparés par des \0, et qui se termine par un double \0


Comment vérifier qu'un chemin de fichier existe ?
Créé le 19/09/2005[haut]
auteur : Farscape
En utilisant la fonction :

BOOL PathFileExists(LPCTSTR pszPath);
Cette fonction détermine si un fichier ou un chemin existe.
Pour l'utiliser vous devrez inclure l'entête "Shlwapi.h"
et rajouter la librairie Shlwapi.lib à l'assemblage des liens (link) .


Comment calculer l'espace disque disponible sur un lecteur ?
Créé le 19/09/2005[haut]
auteur : nico-pyright(c)
En parcourant la chaîne renvoyée par GetLogicalDriveStrings() qui contient la liste des lecteurs On peut observer aussi comment calculer l'espace disque disponible avec l'API GetDiskFreeSpaceEx().

void exploreDisque()
{
    char buff[264];
    GetLogicalDriveStrings(264,buff);
    char *c;
    c=buff;
    while(*c!=NULL)
    {
        printf("%s",c);
        char disqueReseau[20] = " --> disque réseau";
        UINT type = GetDriveType(c);
        switch (type)
        {
        case DRIVE_UNKNOWN:
            printf(" --> type inconnu");
            break;
        case DRIVE_REMOVABLE:
            printf(" --> disque extractible");
            break;
        case DRIVE_FIXED:
            printf(" --> disque dur");
            break;
        case DRIVE_REMOTE:
            CharToOem(disqueReseau,disqueReseau);
            printf(disqueReseau);
            break;
        case DRIVE_CDROM:
            printf(" --> CDROM");
            break;
        case DRIVE_RAMDISK:
            printf(" --> Ram disque");
            break;
        }
        
        // calcul l'espace disque
        __int64 FreeBytesToCaller;
        __int64 TotalBytes;
        __int64 FreeBytes;
        if (GetDiskFreeSpaceEx(c,
            (PULARGE_INTEGER)&FreeBytesToCaller,
            (PULARGE_INTEGER)&TotalBytes,
            (PULARGE_INTEGER)&FreeBytes))
        {
            printf(" ; %d Ko",FreeBytesToCaller/1024);
        }
        printf("\n");
        while (*c!=NULL)
            c++;
        c++;
    }
}

Quelles sont les différentes méthodes pour manipuler un fichier ?
Créé le 20/05/2006[haut]
auteur : nico-pyright(c)
Pour manipuler un fichier en C/C++ il existe différentes méthodes.

Sous windows, on utilisera directement les API Win32 (CreateFile, ReadFile, ...) ou une surcouche comme les MFC (CFile et ses dérivées)


Que choisir entre l'API Win32 et la surcouche MFC (CFile, CStdioFile) ?
Créé le 20/05/2006[haut]
auteur : nico-pyright(c)
Tant qu'à utiliser les bibliothèques MFC, il est plus intéressant de privilégier les classes CFile ou CStdioFile qui sont plus faciles à manipuler que les fonctions de l'API. On utilisera les fonctions de l'API que lorsque le projet ne doit pas utiliser les MFC.
Globalement, on choisit d'utiliser CFile lorsqu'on utilise des fichiers en mode binaire et CStdioFile pour des fichiers en mode texte.
L'API Win32 manipule les fichiers comme étant des fichiers binaires.


Dois-je créer un fichier binaire ou un fichier texte ?
Créé le 20/05/2006[haut]
auteur : nico-pyright(c)
Un fichier est une suite d'octets. Donc tout fichier est un fichier binaire en soit. On va lire une suite d'octets dans ce fichier. L'abstraction d'un fichier en mode texte, permet d'établir un séparateur de lignes dans un fichier texte.
Ce séparateur va permettre de lire plutôt des lignes dans un fichier qu'une suite d'octets.
Ce séparateur de lignes correspond à un ou plusieurs caractères suivant les plateformes.

Par exemple, sur MAC, le séparateur est un simple retour chariot (0x0D en ascii), tandis que sur des OS basés sur Unix, on utilise le caractère de retour en début de ligne (0x0A en ascii).
Par contre, sous DOS/OS2 et Windows, c'est une combinaison de ces deux caractères (à savoir 0x0D0A). Donc si on utilise un fichier en mode texte en lisant octet par octet, il faudra faire attention au séparateur suivant les OS.
Heureusement, les fonctions du C/C++ nous permettent de manipuler les fichiers sans se soucier de la plateforme tant que nous ouvrons le fichier en mode texte.

On a tendance à dire que l'utilisation d'un fichier binaire, bien que pratique dans certains cas, peut présenter des inconvénients à long terme.
Imaginons que l'on veuille stocker les coordonnées de sa souris dans un fichier.
On va utiliser deux entier (int) pour les stocker, soit à l'heure actuelle 2*4 = 8 octets dans le fichier.
Mais imaginons que d'ici quelques années, les entiers ne soient plus stockés sur 4 octets mais sur 8.
Si on recompile notre programme avec des entier sur 8 octets, la lecture d'un entier dans ce fichier ne produira pas le même résultat.
L'inconvénient d'un fichier texte bien sur est qu'il est plus délicat de stocker n'importe quelle suite d'octet.

Il faut donc bien choisir son type de fichier en fonction de ses besoins.


Comment déplacer le pointeur de fichier ?
Créé le 20/05/2006[haut]
auteur : nico-pyright(c)
API Win32 : on utilise SetFilePointer
SetFilePointer(fichier,NULL,NULL,FILE_END);
CFile et ses dérivées : on utilise Seek, SeekToBegin ou SeekToEnd
cfile.SeekToEnd();

Comment lire tout mon fichier dans un buffer ?
Créé le 20/05/2006[haut]
auteur : nico-pyright(c)
Cette pratique est souvent utilisée pour éviter les multiaccès au fichier Api Win32
HANDLE hFile; 
hFile = CreateFile("test.txt",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (hFile == INVALID_HANDLE_VALUE)
return false;
DWORD dwSize;
dwSize = GetFileSize (hFile, NULL);
if (dwSize == INVALID_FILE_SIZE)
return false;
char *buffer = new char[dwSize+1];
DWORD bLu;
ReadFile(hFile,buffer,dwSize,&bLu,NULL);
// ...
delete buffer;
CFile
   CFile f2 ("c:\\test.txt", CFile::modeRead | CFile::typeBinary );
   ULONGLONG taille = f2.GetLength();
   char *buffer = new char[(int)taille+1];
   CString str;
   UINT nOctetsLu = f2.Read(buffer, (int)taille);
   str = buffer;
   f2.Close();
   delete buffer;
NB : Lorsqu'on utilise des gros fichiers, new peut échouer par manque de place sur le tas. Il est recommandé d'avoir recours à une allocation dynamique.
// initialisation du buffer (remplace le new)
char * buffer = (char *) VirtualAlloc(NULL, dwSize * sizeof(char), MEMDISPO, PAGE_READWRITE);
if (!buffer)
{
return 1; // erreur de mémoire
}

// ...

// Libération du buffer
VirtualFree(buffer, 0, MEM_RELEASE);


Comment lire et écrire dans un fichier en mode texte ?
Créé le 20/05/2006[haut]
auteur : nico-pyright(c)
CStdioFile f1 ("c:\\test.txt", CFile::modeCreate | CFile::modeWrite | CFile::typeText );
f1.WriteString("premiere ligne\n");
f1.WriteString("deuxieme ligne");
f1.Close();

CStdioFile f2 ("c:\\test.txt", CFile::modeRead | CFile::typeText );
CString s1, s2;
f2.ReadString(s1); // s1 contient "premiere ligne"
f2.ReadString(s2); // s2 contient "deuxieme ligne"
f2.Close();
Nb : pour ajouter un caractère de séparation de ligne, on utilise \n (0x0A).
La fonction WriteString le transforme alors en 0x0D, 0x0A. Inversement, lorsqu'on lit la paire 0x0D, 0x0A, la fonction ReadString le transforme en \n (0x0A)


Comment lire et écrire dans un fichier en mode binaire ?
Créé le 20/05/2006[haut]
auteur : nico-pyright(c)
par exemple, lire et ecrire un tableau de 5 entiers
avec les API Win32
int t1[5] = {1,2,3,4,5};
HANDLE fichier; 
DWORD octetsEcrits;
fichier = CreateFile("test.txt", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if( fichier == INVALID_HANDLE_VALUE)
   return false;
if (!WriteFile(fichier, t1 ,sizeof(int)*5,&octetsEcrits,NULL))
{
   // erreur;
}
CloseHandle(fichier);

hFile = CreateFile("test.txt",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (hFile == INVALID_HANDLE_VALUE)
   return false;
int t2[5];
DWORD octetsLu;
if (!ReadFile(hFile,t2,sizeof(int)*5,&octetsLu,NULL))
{
   // erreur;
}
CloseHandle(fichier);
Avec CFile
   int t1[5] = {1,2,3,4,5};
   CFile f1 ("c:\\test.txt", CFile::modeCreate | CFile::modeWrite | CFile::typeBinary );
   f1.Write(t1,sizeof(int)*5);
   f1.Close();

   int t2[5];
   CFile f2 ("c:\\test.txt", CFile::modeRead | CFile::typeBinary );
   UINT nOctetsLu = f2.Read( t2, sizeof(int)*5);
   f2.Close();

Comment ouvrir/fermer le lecteur de CD (IOCTL)?
Créé le 20/05/2006[haut]
auteur : Aurelien.Regat-Barrel
En utilisant les IOCTL (donc devrait marcher avec les lecteurs Zip etc...).
On peut aussi spécifier quel lecteur éjecter / refermer.
#include <windows.h>

// Envoie un IOCTL simple vers le périphérique donné
bool SendSimpleIOCTL( LPCTSTR DeviceName, DWORD IoControlCode )
{
    // ouvrir le driver associé au périphérique donné
    HANDLE hDevice = ::CreateFile(
        DeviceName,
        GENERIC_READ,
        0,
        0,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        0 ); 
    if ( hDevice == INVALID_HANDLE_VALUE )
    {
        return false;
    }

    // envoyer l'IOCTL
    DWORD unused;
    BOOL res = ::DeviceIoControl(
        hDevice,
        IoControlCode,
        NULL,
        0,
        NULL,
        0,
        &unused,
        NULL ); 

    // libérer les ressource
    ::CloseHandle( hDevice ); 

    return res == TRUE; 
}

// ouvre le tiroir d'un CD-ROM, ou autre...
bool EjectDevice( LPCTSTR DeviceName ) 
{ 
    return SendSimpleIOCTL(
        DeviceName, 
        IOCTL_STORAGE_EJECT_MEDIA );
} 

// ferme le tiroir d'un CD-ROM, ou autre...
bool CloseDeviceDoor( LPCTSTR DeviceName ) 
{ 
    return SendSimpleIOCTL(
        DeviceName, 
        IOCTL_STORAGE_LOAD_MEDIA );
}

int main()
{
    // le disque peut être désigné soit via son nom logique (par exemple "D:")
    // soit par son nom de périphérique ("CdRom0")
    // Dans les deux cas, ils doivent être précédés du caractere antislash 
// en C/C++ il ne faut pas oublier de les doubler:
    EjectDevice( "\\\\.\\D:" );
    CloseDeviceDoor( "\\\\.\\CdRom0" );
}
Ne fonctionne que sous NT.

Petit lien pour spécifier le lecteur à ouvrir avec mciSendString:
http://c.developpez.com/faq/bcb/?page=systemelecteurs#ouvrirfermertiroircd


Comment ouvrir/fermer le lecteur de CD (MCI)?
Créé le 20/05/2006[haut]
auteur : nico-pyright(c)
En utilisant les commandes MCI, exemple : pour éjecter le CD

#include <mmsystem.h>
bool ejectCD(void)
{
    bool ejected=false;
    if(mciSendString("open cdaudio",NULL,0,NULL)==0)
    {
        char buffer[10];
        if(mciSendString("capability cdaudio can eject",buffer,sizeof(buffer),NULL)==0)
        {
            if(stricmp(buffer,"true")==0)
            {
                ejected=mciSendString("set cdaudio door open",NULL,0,NULL)==0;
            }
        }
        mciSendString("close cdaudio",NULL,0,NULL);
    }
    return(ejected);
}
Pour fermer le lecteur :

bool closeCD(void)
{
    bool closed=false;
    if(mciSendString("open cdaudio",NULL,0,NULL)==0)
    {
        char buffer[10];
        if(mciSendString("capability cdaudio can eject",buffer,sizeof(buffer),NULL)==0)
        {
            if(stricmp(buffer,"true")==0)
            {
                closed=mciSendString("Set cdaudio door closed wait",NULL,0,NULL)==0;
            }
        }
        mciSendString("close cdaudio",NULL,0,NULL);
    }
    return(closed);
}
NB : Ces fonctions nécessitent le link de la librairie Winmm.lib
#pragma comment (lib, "Winmm.lib")

Comment calculer la taille d'un répertoire et de ses sous-répertoires ?
Créé le 20/05/2006[haut]
auteur : nico-pyright(c)
Il faut parcourir récursivement tous les fichiers à partir du répertoire racine.

Voici, une petite fonction qui fait le travail
#include <windows.h>

void mycalculTaille(char * rep, __int64 *taille)
{
    WIN32_FIND_DATA FindFileData;
    char path[MAX_PATH];
    strcpy(path,rep);
    strcat(path,"\\*.*");
    HANDLE hFind = FindFirstFile(path, &FindFileData);
    if (hFind==INVALID_HANDLE_VALUE)
        return;
    if (strcmp(FindFileData.cFileName,".")!=0 && strcmp(FindFileData.cFileName,"..")!=0)
    {
        strcpy(path,rep);
        strcat(path,"\\");
        strcat(path,FindFileData.cFileName);
        mycalculTaille(path, taille);
    }
    DWORD a = 0;
    while (a != ERROR_NO_MORE_FILES)
    {
        if (!FindNextFile(hFind, &FindFileData))
            a = GetLastError();
        else
        {
            if (strcmp(FindFileData.cFileName,".")!=0 && strcmp(FindFileData.cFileName,"..")!=0)
            {
                strcpy(path,rep);
                strcat(path,"\\");
                strcat(path,FindFileData.cFileName);
                if (FindFileData.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
                    mycalculTaille(path, taille);
                else
                {
                    *taille = *taille + (FindFileData.nFileSizeHigh * ((long)MAXDWORD+1) + FindFileData.nFileSizeLow);
                }
            }
        }
    }
    FindClose(hFind);
}

__int64 calculTaille(char * rep)
{
   __int64 taille;
   taille = 0;
    mycalculTaille(rep, &taille);
    return taille;
}

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
   __int64 taille = calculTaille("d:\\truc");
   return 1;
} 


Consultez les autres F.A.Q.


Valid XHTML 1.0 TransitionalValid CSS!

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2004 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.