2017-11-01 17 views
1

私は起動時にディレクトリ内のすべてのファイルのリストを取得し、それらを使って何らかの処理を行います(ネットワーク経由での転送用にパケット化します)。現在のバージョンは静的で、プログラムはプログラムの開始時にファイルのみを表示します。今度は、動的なバージョンに変更して、ディレクトリに追加された新しいファイルを継続的に見ることができます(たとえば、f1、f2、f3などの意味のある名前が増えたと仮定しましょう)。 。私はいくつかのインデックスを使用することができますこのように)。C++は新しいファイルをディレクトリに追加しました

今、これはコードの一部(すべてのファイルの静的読み取り)である:

DIR *dp; 
struct dirent *dirp; 
char * dir = new char[inData->dir.length() + 1]; 
strcpy(dir, inData->dir.c_str()); 
dp = opendir(dir); 
int file_index = 0; 
int total_files = DataUtil::count_files(dp); 

if (readdir(dp) == NULL) 
    rewinddir(dp); 

//for each file in the directory 
    while ((dirp = readdir(dp))) { 
     string f_name = dirp->d_name; 
     if (f_name != "." && f_name != "..") { // except . and .. 
      //Do some processing 
      my_function(f_name, file_index); 
      file_index++;    
     } 
    } 
    closedir(dp); 

私は新しいファイルに気づきrewinddir(dp);機能とfile_indexを使用してコードを変更しました。しかし、それは動作しません。問題はどこだ?

DIR *dp; 
struct dirent *dirp; 
char * dir = new char[inData->dir.length() + 1]; 
strcpy(dir, inData->dir.c_str()); 
dp = opendir(dir); 
int file_index = 0; 
int total_files = MyDataUtil::count_files(dp); 

if (readdir(dp) == NULL) 
    rewinddir(dp); 

//for each file in the directory 
    while ((dirp = readdir(dp))) { 
     string f_name = dirp->d_name; 
     if (f_name != "." && f_name != "..") { 
     //skip files already read 
     for (int var = 0; var < file_index; var++) { 
      readdir(dp); 
     } 
      //Do some processing 
      my_function(f_name, file_index); 
      file_index++; 

     //reset dir stream, and update total_files 
     rewinddir(dp); 
     total_files = MyDataUtil::count_files(dp);    
     } 
    } 
    closedir(dp); 

total_files機能:ここで

int MyDataUtil::count_files(DIR *dp){ 
    struct dirent *dirp; 
    int num = 0; 

    while ((dirp = readdir(dp))) { 
     string f_name = dirp->d_name; 
     if (f_name != "." && f_name != "..") 
      num++; 
    } 
    return num; 
} 

rewinddirドキュメントです。それは「返されるかもしれないし、返されないかもしれない!ここで

Description: 

The rewinddir function is used to reinitialize the directory stream dirstream, so that if you call readdir 
it returns information about the first entry in the directory again. This function also notices if files 
have been added or removed to the directory since it was opened with opendir. (Entries for these files 
might or might not be returned by readdir if they were added or removed since you last called opendir 
or rewinddir.) 
+0

することができますこのコードの問題は、まずあなたのPCを常にビジー状態に保つための無限ループを作成しようとしています。その後、新しいファイルがリストの最後に終わることは当然のことですが、そうではありません確かに。しかし、これらの2つの問題のほかに、あなたのコードについて話をすると、total_filesに値を割り当てており、あなたはそれを使って何かをしています。 – Marco

+0

@Marco私の更新を見てください。 count_filesがdirポインタを変更するように見えます。 total_filesは別のファイルで使用されます。 –

+0

'myFileCount'関数のように見えますが、ファイルポインタをインクリメントしています。だから、 'total_files = MyDataUtil :: count_files(dp);'の後に別の 'rewinddir(dp)'を追加する必要があります。少なくとも今は動作します。 –

答えて

0


多分あなたはそれを試すことができ、別の方法です。

#include "stdafx.h" 
#include <windows.h> 
#include <iostream> 
#include <list> 
#include <Locale.h> 

using namespace std; 

void ListFile(std::list<std::wstring> &list_Steady) 
{ 
    setlocale(LC_ALL, "chs"); 
    WIN32_FIND_DATAW FindFileData; 
    HANDLE hFind; 
    LPCWSTR s = L"C:\\Test_Monitor\\*.*";//The path of Directory you want to Monitor 

    hFind = FindFirstFileW(s, &FindFileData); 

    if (hFind == INVALID_HANDLE_VALUE) 
    { 
     printf ("FindFirstFile failed (%d)\n", GetLastError()); 
     return ; 
    } 
    else 
    { 
     wcout << "The first file found is " << FindFileData.cFileName << endl; 
     list_Steady.push_back(FindFileData.cFileName); 
    } 

    while(FindNextFile(hFind, &FindFileData)) 
    { 
     wcout << "The next file found is " << FindFileData.cFileName << endl; 
     list_Steady.push_back(FindFileData.cFileName); 
    } 

    FindClose(hFind); 
    hFind = NULL; 
} 

void CompareFile(std::list<std::wstring> &new_list , std::list<std::wstring> &steady_list) 
{ 
    bool bFound = false; 

     for (std::list<std::wstring>::iterator it = new_list.begin(); it != new_list.end(); ++it) 
     { 
      bFound = false; 
      for (std::list<std::wstring>::iterator steady_it = steady_list.begin(); steady_it != steady_list.end(); ++steady_it) 
      { 
       //Compare to origin list, if file still exist will return true 
       if(it->compare(steady_it->c_str()) == 0) 
       { 
        bFound = true; 

       } 
      }  

      //else this is a new file 
      if(!bFound) 
      { 
       wcout << it->c_str() << L" new file detected" << endl; 
      }   
     } 

    bool bfound2 = false; 

     for (std::list<std::wstring>::iterator it = steady_list.begin(); it != steady_list.end(); ++it) 
     { 
      bfound2 = false; 
      for (std::list<std::wstring>::iterator new_it = new_list.begin(); new_it != new_list.end(); ++new_it) 
      { 
       //Compare to origin list, if file still exist will return true 
       if(it->compare(new_it->c_str()) == 0) 
       { 
        bfound2 = true; 
       } 
      } 

      //else this file has been deleted 
      if(!bfound2) 
      { 
       wcout<< it->c_str() << L" This file has disappeared" << endl; 

      } 
     } 
} 


int _tmain(int argc, _TCHAR* argv[]) 
{ 
    list<wstring> Steady_Directory; 
    list<wstring> New_Directory; 
    DWORD WaitStatus = 0; 

    Steady_Directory.clear(); New_Directory.clear(); //be sure that list is clean 
    ListFile(Steady_Directory); 
    HANDLE FileChange = INVALID_HANDLE_VALUE; 
    FileChange = ::FindFirstChangeNotification(L"C:\\Test_Monitor",FALSE,FILE_NOTIFY_CHANGE_FILE_NAME); 

    if(FileChange == INVALID_HANDLE_VALUE) 
    { 
     cout << "LOG : FAIL to get File Change, With error code: " << ::GetLastError() << endl; 
     return -1; 
    } 

    WaitStatus = ::WaitForSingleObject(FileChange, INFINITE); 
    if (WaitStatus == WAIT_OBJECT_0) 
    { 
     ListFile(New_Directory); 
     CompareFile(New_Directory, Steady_Directory); 
    } 

    system("PAUSE"); 
    return 0; 
} 

私は他には次の状態のためである2つのリスト、古い状態のための1つのスタンドを使用して、特定のディレクトリの状態をサブスクライブする:: FindFirstChangeNotificationを使用しています。
ディレクトリ内のファイルが変更されると、ハンドルFilechangeが設定され、追加または削除されたファイルを確認するために、関数CompareFileが呼び出されます。
あなたはファイルが選択したディレクトリに変更/削除/追加されたときにループが常に

+0

[ここ](https://imgur.com/a/l5iMf)は、特定のディレクトリの起点の状態です –

+0

[この](https://imgur.com/a/75bWV)は新しいテキストDocument.txtを追加した後です –

+1

これは当然のことながらウィンドウズ特有のものです - ポスターの売りはどんなポジションでもあります –

1

が非同期通知を得るためにLinux上でinotifyを使って、このモニターを動作させるためにしばらくの間、/あなたはいくつか持っている http://man7.org/linux/man-pages/man7/inotify.7.html

+0

はい、私はそれを知っています。私が持っていた1つの質問は、そのスレッドのバージョンを使用してキューを使用する方法でした。 –

+0

おそらくあなたは新しい質問でそれを聞いてください。つまり、スレッド、新しいスレッドでのinotifyのセットアップ、そのfdでの無限ループ選択、プロセスイベント、mutexロック、エンキュー、条件シグナル、mutexロック解除、新しいスレッドの先頭に戻る。オリジナルでは、endlesループ、mutexロック、キューの空の状態の待機、デキュー、mutexのロック解除、qアイテムの使用、元のスレッドのループの先頭に戻る – Waslap

関連する問題