-1

My question crossreferrer with [question]Visual C#: Move multiple files with the same extensions into another directory but i have yet biggest problem - my directory contain more than 3 million files. C# with .GetFiles() can not solve my problem. I think, that only with C++ i can do it. Algorithm

  1. CreateDir "temp"+counterDirs
  2. FindFirst file into source dir
  3. MoveFile into newDir (created on step 1)
  4. increment counterFiles
  5. repeat Steps 2-4 until FindFirst not have error(stop prog) or counterFiles < moveLimit (exmpl 100 000)
  6. increment counterDirs
  7. repeat all from Steps 1-6

target: move all files from src-dir (3 million) into a few target-dirs with 100 000 files.

Please help me with coding - i don't know C++ (VS 2010)

This is my code

`int _tmain(int argc, TCHAR *argv[])
{
   WIN32_FIND_DATA ffd;
   LARGE_INTEGER filesize;
   TCHAR szDir[MAX_PATH];
   TCHAR szNewDir[MAX_PATH];
   TCHAR szNewDirEx[MAX_PATH];   
   size_t length_of_arg;
   HANDLE hFind = INVALID_HANDLE_VALUE;
   DWORD dwError=0;
   DWORD dwFiles = 0;
   DWORD dwDirs = 0;

   // If the directory is not specified as a command-line argument,
   // print usage.

   if(argc != 2)
   {
      _tprintf(TEXT("\nUsage: %s <directory name>\n"), argv[0]);
      return (-1);
   }

   // Check that the input path plus 3 is not longer than MAX_PATH.
   // Three characters are for the "\*" plus NULL appended below.

   StringCchLength(argv[1], MAX_PATH, &length_of_arg);

   if (length_of_arg > (MAX_PATH - 3))
   {
      _tprintf(TEXT("\nDirectory path is too long.\n"));
      return (-1);
   }

   _tprintf(TEXT("\nTarget directory is %s\n\n"), argv[1]);

   // Prepare string for use with FindFile functions.  First, copy the
   // string to a buffer, then append '\*' to the directory name.

   StringCchCopy(szDir, MAX_PATH, argv[1]);
   StringCchCat(szDir, MAX_PATH, TEXT("\\*"));

    StringCchCopy(szNewDir, MAX_PATH, argv[1]);
    StringCchCat(szNewDir, MAX_PATH, TEXT("\\dir"));
    StringCchCat(szNewDirEx, MAX_PATH, szNewDir);
   // Find the first file in the directory.

   hFind = FindFirstFile(szDir , &ffd);

   if (INVALID_HANDLE_VALUE == hFind) 
   {
      DisplayErrorBox(TEXT("FindFirstFile"));
      return dwError;
   } 

   // List all the files in the directory with some info about them.

   do
   {
      if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
      {
         _tprintf(TEXT("  %s   <DIR>\n"), ffd.cFileName);
      }
      else
      {
            if(dwFiles == 0) {
                StringCchCat(szNewDirEx, MAX_PATH, TEXT(dwDirs));
                CreateDir(szNewDirEx);  //dwDirs toString
            }

            if (!MoveFileEx(__OLDDIR__ + ffd.cFileName, szNewDirEx + ffd.cFileName, MOVEFILE_WRITE_THROUGH))
            { 
                printf ("MoveFileEx failed with error %d\n", GetLastError());
                return;
            } else  {
                dwFiles++;
                if (dwFiles == 50000) {
                    dwDirs++;
                    dwFiles = 0;
                }

            }
      }
   }
   while (FindFirstFile(hFind, &ffd) != 0);

   dwError = GetLastError();
   if (dwError != ERROR_NO_MORE_FILES) 
   {
      DisplayErrorBox(TEXT("FindFirstFile"));
   }

   FindClose(hFind);
   return dwError;
}
Community
  • 1
  • 1
Toologic
  • 11
  • 4
  • FindFirstFile is only used for first file, then you have to use FindNextFile. But where is the problem? – Tomashu Oct 17 '14 at 10:31
  • I think, that after moveFile need to use FindFirstFile again, because previous "first" was moved. – Toologic Oct 17 '14 at 10:58

1 Answers1

0

I found solution my task in How to use DirectoryInfo.GetFiles and have it stop after finding the first match?. I will try run this in my directory and will post result later.

Complete. Code in thread link worked perfect.

Community
  • 1
  • 1
Toologic
  • 11
  • 4