Traitement successif de fichiers

Résolu
Messages postés
8
Date d'inscription
jeudi 10 mai 2007
Statut
Membre
Dernière intervention
20 avril 2009
-
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
-
je veux lancer successivement le traitement de plusieurs instances contenues dans un même dossier.
les résultats de chaque instance va être stocké dans un fichier .txt.
mon programme est en C, je travail sous visual C++ V6.
ma question est: peut on accéder aux fichiers contenus dans un dossier, les traiter un par un et à chaque fois en emmagasines les résultats dans un fichier dont le nom sera incrémenté à chaque fois.
merci de votre aide

4 réponses

Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
14
Salut,

Heu... Rien compris moi.

"le traitement de plusieurs instances contenues dans un même dossier" -> Tu veux dire des fichiers ?

"peut on accéder aux fichiers contenus dans un dossier" -> Alors ça, par chance, oui, on peut lire des fichier. CreateFile, ReadFile, WriteFile.

"le nom sera incrémenté à chaque fois." -> Pour ça, c'est plus chiant. Soit il faut que tu stockes dans un fichier le numéro du dernier fichier, soit il faut que tu listes tous les fichiers. Tu peux aussi mettre la date et l'heure précise, ou utiliser une fonction style tmpfile_s.
Messages postés
1054
Date d'inscription
samedi 2 octobre 2004
Statut
Membre
Dernière intervention
9 juillet 2013
7
Salut
D'après ce que j'ai compris, il faut que tu utilises les fonctions FindFirstFile, FindNextFile() pour lister tous les noms des fichiers d'un dossier.
A+
____________________________________________________________________________
Mon site internet :  
http://ImAnalyse.free.fr
Messages postés
8
Date d'inscription
jeudi 10 mai 2007
Statut
Membre
Dernière intervention
20 avril 2009

En effet, il s'agit d'un problème d'ordonnancement, pour lequel il existe plusieurs instances (données d'un problème stockées dans un fichier). Je suis entrain de concevoir ce projet et je veux le tester sous plusieurs instances (ou benchmarks ).
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
14
Tu devrais pouvoir t'inspirer du code suivant par exemple.
Il cherche tous les fichiers input_*.txt d'un répertoire et les concatènes dans un fichier output_%d.txt.
Où %d est le plus petit entier disponible ne correspondant pas à un fichier déjà existant.

Application console. Pour compiler sous gcc, ajouter -nostartfiles -nodefaultlibs -nostdlib -ffreestanding dans les options du lieur.
Pour compiler sous VC, s'arranger pour que le lieur ignore toutes les librairies par défaut (/nodefaultlib).
Sous VC, en cas d'erreur LNK2001 : __chkesp symbole externe non résolu -> Enlever /GZ des options de compilation
<hr size="2" width="100%" />#ifdef UNICODE
#define _UNICODE
#endif /* UNICODE */

#include <windows.h>
#include <tchar.h>

#define WORKING_DIR _T("C:\\Temp\\Test\")

HANDLE _hOutput;                /* Fichier de sortie                          */

typedef BOOL (__stdcall *FILESYSTEM_ENUMFILEPROC)(const TCHAR*);

/**
 * Alloue une zone mémoire en utilisant VirtualAlloc
 *
 * @param nSize Taille de la zone à allouer
 * @return Pointeur sur la zone allouée
 */
void* __stdcall Mem_Alloc(const DWORD nSize)
{
  return VirtualAlloc(NULL, nSize,
                      MEM_RESERVE | MEM_COMMIT,
                      PAGE_READWRITE);
}

/**
 * Libère une zone mémoire allouée avec Mem_Alloc
 *
 * @param Pointeur sur la zone allouée
 */
void __stdcall Mem_Free(void *lpAddress)
{
  VirtualFree(lpAddress, 0, MEM_RELEASE);
}

/**
 * Affiche le texte indiqué dans la console
 *
 * @param lpText Texte à écrire dans la console
 * @return FALSE en cas de problème
 */
BOOL __stdcall Con_WriteLn(const TCHAR *lpText)
{
  DWORD nWritten;   /* Réception du nombre de caractère écris                 */
  char *lpOemText;  /* Texte traduit en OEM                                   */
  DWORD nSize;      /* Taille du texte à écrire                               */
  BOOL bResult;

  /* Traduction des caractère àùéè... */
  nSize = lstrlen(lpText);

  /* On aura un \n en plus */
  nSize++;

  lpOemText = (char*)Mem_Alloc(nSize);
  CharToOem(lpText, lpOemText);
  lstrcatA(lpOemText, "\n");

  bResult = WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), lpOemText,
                      nSize, &nWritten, NULL);

  Mem_Free(lpOemText);
  return bResult;
}

/**
 * Affiche un message d'erreur correspondant à la dernière erreur Win32
 */
DWORD __stdcall Err_ShowLatest()
{
  DWORD nLastError;           /* Numéro de l'erreur                           */
  LPTSTR lpMessageBuffer;     /* Récupération du message                      */

  nLastError = GetLastError();

  /* Formatage du message */
  FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
                NULL, nLastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                (void*)&lpMessageBuffer, 0, NULL);

  /* Affichage du message */
  MessageBox(NULL, lpMessageBuffer, _T("ERROR"), MB_OK | MB_ICONERROR);

  LocalFree(lpMessageBuffer);
  return nLastError;
}

/**
 * Renvoie un handle sur un nouveau fichier
 *
 * @param lpDir Répertoire de création, terminé par un \
 * @param lpName Nom du fichier, doit contenir un %d
 */
HANDLE __stdcall CreateNewFile(const TCHAR *lpDir, const TCHAR *lpName)
{
  TCHAR lpFilePath[1024];    /* Chemin et nom du nouveau fichier              */
  HANDLE hResult;
  int nI;

  /* On boucle tant que le nom est utilisé */
  nI = 0;
  do
  {
    /* Nouveau nom potentiellement disponible */
    lstrcpy(lpFilePath, lpDir);
    lstrcat(lpFilePath, lpName);
    wsprintf(lpFilePath, lpFilePath, nI);

    /* On essaie de l'ouvrir comme nouveau fichier */
    hResult = CreateFile(lpFilePath,
                         GENERIC_READ | GENERIC_WRITE,
                         FILE_SHARE_READ | FILE_SHARE_WRITE,
                         NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hResult != INVALID_HANDLE_VALUE) break;
    nI++;
  }
  while (GetLastError() == ERROR_FILE_EXISTS);

  return hResult;
}

/**
 * Fonction qui va traiter les fichiers en entrée
 */
BOOL __stdcall HandleFile(const TCHAR* lpFile)
{
  HANDLE hInput;           /* Handle du fichier d'entrée                      */
  char lpBuffer[2048];     /* Buffer de lecture                               */
  DWORD nBytesRead;        /* Récupération du nombre d'octets lus             */
  DWORD nBytesWritten;     /* Récupération du nombre d'octets écrits          */

  Con_WriteLn(lpFile);

  hInput = CreateFile(lpFile,
                      GENERIC_READ,
                      FILE_SHARE_READ | FILE_SHARE_WRITE,
                      NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  if (hInput == INVALID_HANDLE_VALUE)
  {
    Err_ShowLatest();
    goto the_end;
  }

  do
  {
    ReadFile(hInput, lpBuffer, sizeof(lpBuffer), &nBytesRead, NULL);
    WriteFile(_hOutput, lpBuffer, nBytesRead, &nBytesWritten, NULL);
  }
  while (nBytesRead == sizeof(lpBuffer));

  CloseHandle(hInput);
the_end:
  return TRUE;
}

/**
 * Enumère les fichier et répertoire d'un dossier
 *
 * La fonction appelée doit renvoyer TRUE pour que le listage continue.
 *
 * @param lpDir Répertoire, doit se terminer par \
 * @param lpFileName Pattern de recherche
 * @param lpCallBack Fonction appelée pour chaque fichier
 */
int __stdcall FileSys_EnumFiles(const TCHAR* lpDir, const TCHAR* lpFileName, FILESYSTEM_ENUMFILEPROC lpCallBack)
{
  TCHAR lpFilePath[1024];        /* Chemin et nom d'un fichier en entrée      */
  WIN32_FIND_DATA findFileData;  /* Information sur les fichiers trouvés      */
  HANDLE hFind;                  /* Handle sur la recherche                   */
  int nResult;

  nResult = 0;

  lstrcpy(lpFilePath, lpDir);
  lstrcat(lpFilePath, lpFileName);

  /* Parcourt des fichiers d'entrée */
  hFind = FindFirstFile(lpFilePath, &findFileData);
  if (hFind == INVALID_HANDLE_VALUE)
  {
    if (GetLastError() != ERROR_FILE_NOT_FOUND)
      goto the_end;
  }
  else
  {
    do
    {
      if (lstrcmp(findFileData.cFileName, _T(".")))
        if (lstrcmp(findFileData.cFileName, _T("..")))
        {
          lstrcpy(lpFilePath, lpDir);
          lstrcat(lpFilePath, findFileData.cFileName);

          /* Appel de la callback pour tous les fichiers */
          if (! lpCallBack(lpFilePath))
          {
            nResult = 1;
            goto the_end;
          }
        }
    }
    while (FindNextFile(hFind, &findFileData));
    FindClose(hFind);

    /* Vérification que l'on est sorti de le la boucle */
    /* car il n'y a plus de fichiers.                  */
    if (GetLastError() != ERROR_NO_MORE_FILES)
      goto the_end;
  }
 
  nResult = 1;
the_end:
  return nResult;
}

/**
 * Main
 */
int __cdecl mainCRTStartup()
{
  int nResult;

  nResult = 0;

  /* Création d'un nouveau fichier de sortie */
  _hOutput = CreateNewFile(WORKING_DIR, _T("output_%d.txt"));
  if (_hOutput == INVALID_HANDLE_VALUE)
  {
    nResult = Err_ShowLatest();
    goto the_end;
  }

  /* Traitement des fichiers en entrée */
  if (! FileSys_EnumFiles(WORKING_DIR, _T("input_*.txt"), HandleFile)) Err_ShowLatest();

  CloseHandle(_hOutput);
the_end:
  /* ExitProcess nécessaire car sinon c'est un ExitThread */
  ExitProcess(nResult);

  /* Pour esquiver le warning */
  return 0;
}