1. 程式人生 > >C++中_finddata_t結構體儲存檔案資訊

C++中_finddata_t結構體儲存檔案資訊

最近除錯程式的時候需要處理大量txt檔案,這裡對於處理各種檔案的資訊做個筆記。

Struct _finddata_t結構體可以用來處理各種檔案的檔案資訊,使用該結構體需要新增標頭檔案io.h。

它的定義如下所示

struct _finddata_t
{
  unsigned attrib;
  time_t time_create;
  time_t time_access;
  time_t time_write;
  _fsize_t size;
  char name[_MAX_FNAME];
};

對於該結構體中的各個變數的定義如下所示:

unsigned attrib:無符號整形、位表示。它的作用是表示檔案的屬性,一般來說,檔案的屬性有如下幾種:

_A_ARCH(存檔)、 _A_HIDDEN(隱藏)、_A_NORMAL(正常)、_A_RDONLY(只讀)、_A_SUBDIR(資料夾)、_A_SYSTEM(系統)

time_t time_create:表示從1970年1月1日0時0分0秒到現在時刻的秒數。

time_t time_access:檔案最後一次被訪問的時間

time_t time_write:檔案最後一次被修改的時間

_fsize_t size:檔案的大小。

char name[_MAX_FNAME]:檔案的檔名,這裡的_MAX_FNAME是一個常量巨集,它在標頭檔案中被定義,表示的是檔名的最大長度。

為了使用這個結構體將檔案的資訊儲存到該結構體的記憶體空間,需要搭配使用_findfirst()、_findnext()、_findclose()

三個函式使用。首先用_findfirst函式查詢第一個檔案,若成功則用返回的控制代碼,呼叫_findnext函式查詢其他的檔案,當查詢檔案完成之後,就會用_findclose函式結束查詢。

long _findfirst( char *filespec, struct _finddata_t *fileinfo );

返回值:如果查詢成功,那麼就返回一個long型的唯一查詢用的控制代碼。這個控制代碼會在_findnext函式中被使用。失敗的話就會返回0.

引數:filespec:標明檔案的字串。例如:*.c

fileinfo:這裡就是用來存放檔案資訊的結構體的指標。函式成功後,函式會把找到的檔案的資訊放入這個結構體所分配的記憶體空間中。

int _findnext( long handle, struct _finddata_t *fileinfo );

返回值:若成功返回0,否則返回-1。

引數:handle:即由_findfirst函式返回回來的控制代碼。

int _findclose( long handle );

返回值:成功返回0,失敗返回-1。

下面介紹一下C++裡面的控制代碼,為了區分控制代碼和指標。分別介紹一下:

指標:指標通俗來著就是地址,他是記憶體的編號,通過指標我們可以直接對記憶體進行操作,只要地址不變,我們每次操作的物理位置是絕對不變的。

控制代碼:一般是指向系統的資源的位置,可以說也是地址。但是這些資源的位置真的不變,我們都知道window支援虛擬記憶體的技術,同一時間內可能有些資源被換出記憶體,一些被換回來,這就是說同一資源在系統的不同時刻,他在記憶體的物理位置是不確定的,那麼window是如何解決這個問題呢,就是通過控制代碼來處理資源的物理位置不斷變化的這個問題的。window會在物理位置固定的區域儲存一張對應表,表中記錄了所有的資源實時地址,控制代碼其實沒有直接指向資源的實體地址,而是指向了這個對應表中的一項,這樣無論資源怎樣的換進換出,通過控制代碼都可以找到他的實時位置。

以下為解決工程問題所寫的小測試程式:

#include <iostream>
#include <io.h>
#include <Windows.h>
#include <vector>
#include <string>

using namespace std;

#define ADDR "C://Users//CiCi//Desktop//8.7//*.txt"
const char *SearchAddr = ADDR;

int main()
{
	long Handle;
	struct _finddata_t FileInfo;
	vector<string>name;
	vector<string>direction;
	vector<string>last_t;
	vector<int>id;
	vector<int>direction_2;
	Handle = _findfirst(SearchAddr, &FileInfo);
	name.push_back(FileInfo.name);
	while (!_findnext(Handle, &FileInfo))
	{
		name.push_back(FileInfo.name);
	}
	for (auto it = name.begin(); it != name.end(); it++)
	{
		/*cout << *it << endl;*/
		string str = *it;
		direction.push_back(str.substr(21, 1));
		last_t.push_back(str.substr(0, 6));
	}
	for (auto it = direction.begin(); it != (direction.end()-3); it = it + 3)
	{
		string a = *it;
		string b = *(it + 3);
		auto c = a.compare(b);
		direction_2.push_back(c);
	}
	for (auto it = last_t.begin(); it !=(last_t.end() - 3); it = it + 3)
	{
		string a = *it;
		string b = *(it + 3);
		auto c = a.compare(b);
		/*cout << c << endl;*/
		id.push_back(c);
	}
	for (auto it = id.begin(); it != id.end(); it++)
	{
		if (direction_2.at(it - id.begin())==  0 && id.at(it - id.begin())==0)
		{
			cout << name.at(3*(it - id.begin())) << endl;
		}
	}
	_findclose(Handle);
	return 0;
}

這裡有幾個注意的地方:

1.使用_findfirst函式之後,要立刻把檔名存入vector容器中去,不然接下來呼叫_findnext函式會導致缺少第一個檔案。

2.這裡使用了string的一個substr函式,函式結構為str.substr(m,n)。其中,str為string型變數的變數名,m為字串的第m個字元,n為從第m個字元起的個數。

3.比較兩個string物件是否相等,這裡用compare函式,函式結構為s1.compare(s2),如果兩個string物件相等的話,就會返回0;