1.有时候单元测试需要对大批量的文件进行压力测试,这时候,代码里写死,xml配置文件,main的参数传递都不够方便。
2.这时候如果有一个动态库可以自动获取指定目录下的直接文件路径并返回一个C链表结构对象,那么就可以给各种语言调用了,非UNICODE版本。
3.以下在windows上使用MinGW的g++ 4.4编译过.
4.参考了msdn的win32的api例子.
文件1:Makefile
CP="cp -u"
gtest_main:gtest_main.cpp tt_test
g++ gtest_main.cpp -o gtest_main.exe -IE:/software/Lib/tests/gtest-1.5.0/win32/release/static/include -LE:/software/Lib/tests/gtest-1.5.0/win32/release/static -lgtest -L. -ltt_test
tt_test:tt_test.o Makefile
g++ -shared -o tt_test.dll -s tt_test.o -Wl,--out-implib,libtt_test.dll.a
tt_test.o:tt_test.cpp Makefile
g++ -DBUILDING_TT_TEST_DLL -c tt_test.cpp -o tt_test.o
文件2:tt_test.cpp
#include "tt_test.h"
#define _WIN32_WINNT 0x0501
//#define UNICODE
#include <windows.h>
#include <string.h>
#include <stdio.h>
#include <string>
#include <iostream>
using namespace std;
TargetFile* GetTargetFiles(const char* dir,const char* extension)
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind = INVALID_HANDLE_VALUE;
char DirSpec[MAX_PATH]; // directory specification
DWORD dwError;
size_t dir_len = strlen(dir);
strncpy (DirSpec, dir, dir_len+1);
strncat (DirSpec, extension, strlen(extension)+1);
TargetFile *target = NULL;
TargetFile *first = NULL;
hFind = FindFirstFile(DirSpec, &FindFileData);
if (hFind == INVALID_HANDLE_VALUE)
{
printf ("Invalid file handle. Error is %lu \n", GetLastError());
return NULL;
}
else
{
target = (TargetFile*)malloc(sizeof(TargetFile));
memset(target,0,sizeof(TargetFile));
size_t file_name_len = strlen(FindFileData.cFileName);
char* file_path = (char*)malloc(file_name_len+dir_len+1);
strncpy(file_path,dir,dir_len+1);
strncat(file_path,FindFileData.cFileName,file_name_len);
target->path = file_path;
TargetFile *previous = target;
first = target;
while (FindNextFile(hFind, &FindFileData) != 0)
{
file_name_len = strlen(FindFileData.cFileName);
char* temp_path = (char*)malloc(file_name_len+dir_len+1);
strncpy(temp_path,dir,dir_len+1);
strncat(temp_path,FindFileData.cFileName,file_name_len);
target = (TargetFile*)malloc(sizeof(TargetFile));
memset(target,0,sizeof(TargetFile));
target->path = temp_path;
previous->next = target;
previous = target;
}
dwError = GetLastError();
FindClose(hFind);
if (dwError != ERROR_NO_MORE_FILES)
{
printf ("FindNextFile error. Error is %lu \n", dwError);
return first;
}
}
return first;
}
void FreeTargetFiles(TargetFile* first)
{
while(first)
{
TargetFile *temp = first;
first = first->next;
free(temp->path);
temp->path = NULL;
free(temp);
}
}
文件3: tt_test.h
#ifndef TT_TEST_H
#define TT_TEST_H
#ifdef BUILDING_TT_TEST_DLL
#define TT_TEST_DLL __declspec(dllexport)
#else
#define TT_TEST_DLL __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct TargetFile TargetFile;
struct TargetFile
{
char *path;
TargetFile *next;
};
TT_TEST_DLL TargetFile* GetTargetFiles(const char* dir,const char* extension);
TT_TEST_DLL void FreeTargetFiles(TargetFile* first);
#ifdef __cplusplus
}
#endif
#endif /* TT_TEST_H */
文件4:gtest_main.cpp
#include <string.h>
#include "gtest/gtest.h"
#include "tt_test.h"
using namespace std;
int main(int argc, char **argv)
{
setbuf(stdout, (char*) 0);
setbuf(stderr, (char*) 0);
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
TEST(gtest_main,testTargetFile)
{
TargetFile* first = GetTargetFiles("E:\\software\\TestData\\pdf\\","*.pdf");
ASSERT_TRUE(first);
TargetFile* temp = first;
while(temp)
{
ASSERT_TRUE(strstr(temp->path,".pdf"));
temp = temp->next;
}
FreeTargetFiles(first);
cout << "finish" << endl;
}
输出结果:
备注:
1.判断是否是目录使用&运算法. FILE_ATTRIBUTE_DIRECTORY & FindFileData.dwFileAttributes