Chào mừng đến với Diễn đàn lập trình - Cộng đồng lập trình.
Trang 1 của 2 12 CuốiCuối
Kết quả 1 đến 10 của 17
  1. #1

    Hàm tìm kiếm tất cả các file loại trừ một số thư mục?

    Dear all,

    Em đang code 1 function list all file trong ổ C:\ và write ra file C:\filelist.txt, dùng 2 API FindFirstFile() và FindNextFile() kết hợp với thuật toán recursive. Code đã hoàn tất như sau :

    Mã:
    void find(char* path)
    {
    	static int found =0;
    	FILE *filehandle = fopen("C:\\filelist.txt", "a");
    
    	HANDLE fh;
    	WIN32_FIND_DATA wfd;
    	int i=0;
    	int j=0;
    
    	fh=FindFirstFile(path,&wfd);
    	if(fh)
    	{
    		char full_path[350];
    		if (strcmp(wfd.cFileName,".")!=0)
    		{
    			for (int i = 0; i < strlen(path)-3; i++)
    				full_path[i] = path[i];
    			full_path[strlen(path)-3]='\0';
    			strcat(full_path,wfd.cFileName);
    			fputs (full_path,filehandle);
    			fputs ("
    ",filehandle);
    		}
    
    		while(FindNextFile(fh,&wfd) && found ==0)
    		{
    			if (strcmp(wfd.cFileName,"..")!=0)
    			{
    				for (int i = 0; i < strlen(path)-3; i++)
    					full_path[i] = path[i];
    				full_path[strlen(path)-3]='\0';
    				strcat(full_path,wfd.cFileName);
    				fputs (full_path,filehandle);
    				fputs ("
    ",filehandle);
    			}
    
    			if(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY && strcmp(wfd.cFileName,"..")!=0 && strcmp(wfd.cFileName,".")!=0)
    			{
    				path[strlen(path)-3]='\0';
    				strcat(path,wfd.cFileName);
    				strcat(path,"\\*.*");
    				find(path);
    			}
    		}
    			
    		if(found==0)
    			{
    			for(i=strlen(path)-1;i>0;i--)
    			{
    				if(j==1 && path[i]=='\\')
    				{
    					path[i]='\0';
    					strcat(path,"\\*.*");
    					break;
    				}
    				if(path[i]=='\\')
    					j=1;
    			}
    		}
    	}
    	FindClose(fh);
    	fclose(filehandle);
    }
    Tuy nhiên, khi compile & chạy ctrinh thì ok nhưng chạy 1 lúc thì sẽ bị báo lỗi, sau khi em debug thì đây ko phải lỗi do code mà là 1 lỗi logic. Lý do là vì khi scan đến thư mục "C:\System Volume Information" thì bị access denied (vì thư mục này của chức năng System Restore trong Windows và default là ko có permission access trừ khi ta chủ động set permission lại). Em đã thử chủ động xóa folder này và chạy ctrinh lại thì mọi thứ đều rất ok

    Do đó em muốn sửa file hàm find trên sao cho khi list file nếu đó là thư mục có path là "C:\System Volume Information" thì bỏ wa và tiếp tục list tiếp. Em sửa code như sau :

    Mã:
    void find(char* path)
    {
    	static int found =0;
    	FILE *filehandle = fopen("C:\\filelist.txt", "a");
    
    	HANDLE fh;
    	WIN32_FIND_DATA wfd;
    	int i=0;
    	int j=0;
    
    	fh=FindFirstFile(path,&wfd);
    	if(fh)
    	{
    		char full_path[350];
    		if (strcmp(wfd.cFileName,".")!=0)
    		{
    			for (int i = 0; i < strlen(path)-3; i++)
    				full_path[i] = path[i];
    			full_path[strlen(path)-3]='\0';
    			strcat(full_path,wfd.cFileName);
    			fputs (full_path,filehandle);
    			fputs ("
    ",filehandle);
    		}
    
    		while(FindNextFile(fh,&wfd) && found ==0)
    		{
    			if (strcmp(wfd.cFileName,"..")!=0)
    			{
    				for (int i = 0; i < strlen(path)-3; i++)
    					full_path[i] = path[i];
    				full_path[strlen(path)-3]='\0';
    				strcat(full_path,wfd.cFileName);
    				fputs (full_path,filehandle);
    				fputs ("
    ",filehandle);
    			}
    
    			if(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY && strcmp(wfd.cFileName,"..")!=0 && strcmp(wfd.cFileName,".")!=0)
    			{
    				path[strlen(path)-3]='\0';
    				strcat(path,wfd.cFileName);
    				if(strcmp(path, "C:\\System Volume Information"))
    					continue;
    				strcat(path,"\\*.*");
    				find(path);
    			}
    		}
    			
    		if(found==0)
    			{
    			for(i=strlen(path)-1;i>0;i--)
    			{
    				if(j==1 && path[i]=='\\')
    				{
    					path[i]='\0';
    					strcat(path,"\\*.*");
    					break;
    				}
    				if(path[i]=='\\')
    					j=1;
    			}
    		}
    	}
    	FindClose(fh);
    	fclose(filehandle);
    }
    Phần in đậm màu đỏ là phần em add thêm vào để compare, khi compile thì vẫn ok nhưng kết quả write ra file ko còn chính xác như ban đầu nhưng em ko hiểu tại sao? Bạn nào nhìn ra lỗi thì giúp em với. Thanx

    Best Regards,

  2. #2
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Vietwow viết lại đi, code của em lung tung lắm, if while nhảy lung tung, bug, chậm, lỗi overwrite memory nhiều lắm. Anh cũng tính optimize lại cho em, nhưng thôi, để em tự làm.
    Hồi xưa anh review code cho các coder khác của công ty, code vầy là anh bắt xóa bỏ hết, viết lại cái mới, không sữa, không workaround, chắp vá.
    Em dùng hàm FindFirstFindEx thay cho FindFirstFile, sẽ gọn đi nhiều đấy.

  3. #3
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Dạ, em sẽ xem thêm hàm FindFirstFindEx(). Còn viết lại nguyên hàm find thì chắc em chịu vì trình hiện tại em chỉ biết 1 cách như trên thôi anh (dùng 2 API search kết hợp với recursive), em sẽ cố gắng search docs thêm xem sao. Nếu a còn cách khác thì nhờ a gợi mở để e mày mò thêm. Cám ơn anh TQN và các bạn khác rất nhiều vì chịu khó follow giúp đỡ em mấy topic vừa qua [IMG]images/smilies/biggrin.png[/IMG]

    Best Regards,

  4. #4
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Hệ thống Help2 trên máy anh đang bị hư, mày mò vừa RCE Help2 API (\Program Files\Common Files\Microsoft Shared\Help\hxds.dll, \Program Files\Common Files\Microsoft Shared\Help\hxvz.dll, \Program Files\Common Files\Microsoft Shared\Help\ITIRCL55.DLL, dexplore.exe) vừa monitor, mà vẫn chưa được. Mà install lại thì no, nhứt quyết không install lại, phải tìm tại sao không còn help collection nào.
    Vì vậy anh phải lên MSDN Online đọc, và sorry anh đã có lỗi sai về return value của FindNextFile.
    Nếu mục đích của vietwow chỉ là write tất cả file name vào filelist.txt thì code trên của em sẽ chỉ còn gần một nữa. Bỏ luôn cái compare "System Volume..." gì đó luôn, code như vậy là tệ lắm, nếu ở ổ D, E, F.. thì sao, nếu thư mục khác cũng có security attribute như nó thì sao.
    Cố lên thử xem nhé. Đã làm thì phải làm cho được, làm cho tốt, không làm tạm bợ.
    Lúc trước anh đã có lần nói: ct run được thì chưa chắc là ct tốt, chỉ 30-50% thôi. Chỉ cần tốt nhất theo mình là được rồi.

  5. #5
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Em code kiểm tra sai trị return value của FindFirst và FindNext. Nó return INVALID_HANDLE_VALUE khi failed, chứ không phải NULL.
    Sữa lại:

    Mã:
    fh=FindFirstFile(path,&wfd);if (INVALID_HANDLE_VALUE != fh)...........while ((INVALID_HANDLE_VALUE != FindNextFile(fh,&wfd)) && (0 == found)).........
    Đọc kỹ MSDN về hàm API mình dùng, tham số, return value....

  6. #6
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Mã:
                    if(strcmp(path, "C:\\System Volume Information"))                    continue;
    hàm strcmp trả về 0 khi 2 xâu bằng nhau mà. Như vậy bạn phải sửa thế này chứ:

    Mã:
                    if(!strcmp(path, "C:\\System Volume Information"))                    continue;

  7. #7
    Trích dẫn Gửi bởi birthis
    Mã:
                    if(strcmp(path, "C:\\System Volume Information"))                    continue;
    hàm strcmp trả về 0 khi 2 xâu bằng nhau mà. Như vậy bạn phải sửa thế này chứ:

    Mã:
                    if(!strcmp(path, "C:\\System Volume Information"))                    continue;
    À, đúng là khúc đó mình nhầm, nhưng khi sửa lại rồi nhưng chương trình chỉ list được 1 khúc thì ngưng, ko list được hết tòan bộ như code ban đầu, mình nghi ngờ là logic khi mình sử dụng lệnh continue mình sai, hic

  8. #8
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Dear anh TQN,

    Hàm find() em sẽ cố gắng tìm cách viết lại theo lời a suggest để improve khả năng code. Nhưng hiện tại em gặp 1 lỗi rất quái nên chắc phải nhờ anh hay các bạn nào có khả năng debug xem giúp giùm. Tình hình hiện tại code em (chưa optimize lại hàm find) đã chạy ok, nó list all file name ra fille "C:\filelist.txt" và đọc filename từ file đó ra rùi md5 (dùng chương trình m5dsums mới, ko phải chương trình bị lỗi tham số lần trước nha anh) và write output ra "C:\output.txt". Em run code qua VS 2010 (chức năng Ctrl + F5 - Run Without Debugging) thì ok, check C:\output.txt thấy ok :

    Mã:
    c059d45d0fec1e833b1ad9a64c06cbd7 *192.168.10.5.txt
    c059d45d0fec1e833b1ad9a64c06cbd7 *192.168.10.6.txt
    c059d45d0fec1e833b1ad9a64c06cbd7 *192.168.12.7.txt
    Nhưng khi em run chương trình qua file exe (được generate từ source mà e vừa run Ctrl + F5 từ VS) thì output của file C:\output.txt lại thành như vậy :

    Mã:
    c059d45d0fec1e833b1ad9a64c06cbd7 *192.168.10.5.txt
    
    Press ENTER to exitc059d45d0fec1e833b1ad9a64c06cbd7 *192.168.10.6.txt
    
    Press ENTER to exitc059d45d0fec1e833b1ad9a64c06cbd7 *192.168.12.7.txt
    
    Press ENTER to exit
    Em ko hiểu tại sao lại như vậy ? Cái string "Press ENTER to exit" ko biết ở đâu sinh ra ? Em thử dùng OllyDbg để search string cái ctrinh md5sums.exe cũng ko thấy chuỗi "Press ENTER to exit", trong ctrinh của em viết thì chắc chắn ko có rồi, vậy nó ở đâu ra nhỉ ? Và lạ nhất là tại sao cùng 1 source nhưng run qua VS 2010 thì chạy tốt mà run qua exe thì lại khác ?

    Để tiện, em xin up nguyên project lên :

    http://www.mediafire.com/?lxww96910nqazml

    kèm theo link ctrinh md5sums em sử dụng : http://www.pc-tools.net/win32/md5sums/

    Để test lẹ, em đã comment đi hàm find(), do đó chỉ cần tạo ra file C:\filelist.txt với nội dung là 3 path file trong ổ C:\, vd :

    Mã:
    C:\1\192.168.10.5.txt
    C:\1\192.168.10.6.txt
    C:\1\192.168.12.7.txt
    Rồi chạy code là nó sẽ sinh ra "C:\output.txt"

    Hy vọng anh hay airỗi xem qua giúp em tý, emdebug cả ngày rùi vẫn chưa biết tại sao Thanx

    Best Regards,

  9. #9
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Hic, ai rãnh giúp em debug cái này cái, bữa giờ em mò hoài vẫn ko ra [IMG]images/smilies/dont_know.gif[/IMG]

  10. #10
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Tối qua anh đã debug thử code của em, bug nhiều lắm, stack bị corrupt lung tung.
    Vài lỗi nặng: strtok return NULL thì sao, fgets failed thì sao, buffer 300 chắc chắn đủ không ?
    Thấy code của em như vậy, anh thấy em nên chịu khó viết lại, chia nhỏ ra thành từng hàm nhỏ, test kỹ từng hàm đó với mọi dạng dữ liệu, mọi đầu vào, mọi path có thể xảy ra.

 

 
Trang 1 của 2 12 CuốiCuối

Quyền viết bài

  • Bạn Không thể gửi Chủ đề mới
  • Bạn Không thể Gửi trả lời
  • Bạn Không thể Gửi file đính kèm
  • Bạn Không thể Sửa bài viết của mình
  •