#include "stdafx.h"
#include <Windows.h>
#include <io.h>
#include <direct.h>
#include <atlstr.h>
const char *_tmpfileName = "tmptestfile";
const char *TestStr = "0123456789";
const int TestStrLen = 10;
const double Send_Rate = 0.1;
LONGLONG Cpu_Freq = 0;
const __int64 Default_Data_Size = 1024*1024*100;
char strbuf[256];
int giNumLastOutput = 0;
/*
void OneLineOutput(const char *strput)
{
for(int i=0;i<giNumLastOutput;i++) printf("\b");
giNumLastOutput = printf(strput);
}*/
// 将TCHAR转化为char
char *TCHAR2char(_TCHAR *tchar)
{
int wlen = lstrlen(tchar);
char *_char = new char[wlen+1];
if(_char == NULL)
{
printf("TCHAR2char new char[] error %d\n",GetLastError());
return NULL;
}
WideCharToMultiByte(CP_ACP,0,tchar,-1,NULL,wlen,NULL,NULL);
return _char;
}
// 字符串截断
char *CharCut(char *srcbuf)
{
int pos;
int len = strlen(srcbuf);
for(pos = 0;pos<len;pos++)
{
if(srcbuf[pos] == '\n') break;
}
srcbuf[pos] = '\0';
return srcbuf;
}
// 测试写速度
void TestWriteFile(char *filepath,__int64 totalSize);
// 测试读速度
void TestReadFile(char *filepath,__int64 totalSize);
// 获取CPU频率
LONGLONG GetCPUFreq();
// 获取时间戳
inline unsigned __int64 GetCycleCount()
{
__asm _emit 0x0F
__asm _emit 0x31
}
void LogOut(char strbuf[])
{
FILE *fp;
TCHAR wstrAppPath[MAX_PATH]=_T("");
char filePath[MAX_PATH]="";
GetModuleFileName(NULL,wstrAppPath,MAX_PATH);
CString str(wstrAppPath);
int pos = str.ReverseFind('\\');
wsprintf(wstrAppPath,_T("%s\\toollogout.txt"),str.Mid(0,pos));
DWORD dwNum = WideCharToMultiByte(CP_ACP,NULL,wstrAppPath,-1,NULL,0,NULL,FALSE);
WideCharToMultiByte(CP_ACP,NULL,wstrAppPath,-1,filePath,dwNum,NULL,FALSE);
fopen_s(&fp,filePath,"r");
if(fp != NULL) fclose(fp);
if(fp == NULL)
{
fopen_s(&fp,filePath,"w");
}
else
{
fopen_s(&fp,filePath,"a+");
}
fwrite(strbuf,sizeof(char),strlen(strbuf),fp);
fflush(fp);
fclose(fp);
}
// 如果文件夹不存在就创建
void CreateDir(const char *dirpath)
{
char mkpath[256]="";
for(int i=0;i<(int)strlen(dirpath);i++)
{
mkpath[i] = dirpath[i];
if(dirpath[i] == '\\')
{
if(_access(mkpath,0) == -1)
{
_mkdir(mkpath);
}
}
}
if(_access(mkpath,0) == -1)
{
_mkdir(mkpath);
}
}
// 从服务器管道接收数据线程
DWORD CALLBACK ReadFromServerPipeThread(LPVOID lpvParam){
HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE); // 获取标准输入句柄
char readbuff[256];
DWORD dwLen = 0;
while(ReadFile(hStdIn,readbuff,256,&dwLen,NULL))
{
if(dwLen > 0)
{
CharCut(readbuff);
if(strcmp(readbuff,"stop") == 0)
{
LogOut("need stop!");
//OneLineOutput("Sub Program Stop!\n");
printf("Sub Program Stop!\n");
fflush(stdout);
CloseHandle(hStdIn);
exit(0);
}
}
}
CloseHandle(hStdIn);
return 0;
}
// 主函数
int main(int argc, char* argv[])
{
if(argc != 4)
{
sprintf_s(strbuf,256,"Usage:%s size read/write path\n",argv[0]);
//OneLineOutput(strbuf);
printf("Usage:%s size read/write path\n",argv[0]);
fflush(stdout);
return -1;
}
__int64 DataSize = (__int64)(atof(argv[1])*1024*1024);
char *dirPath = argv[3];
char filePath[128];
LogOut("test");
sprintf_s(filePath,128,"%s\\%s",dirPath,_tmpfileName);
Cpu_Freq = GetCPUFreq();
CreateDir(dirPath); // 如果文件夹不存在就创建
sprintf_s(strbuf,256,"DataSize=%I64d\n",DataSize);
LogOut(strbuf);
sprintf_s(strbuf,256,"Style:%s\n",argv[2]);
LogOut(strbuf);
DWORD dwThreadId = 0;
HANDLE hThread = CreateThread(NULL,0,ReadFromServerPipeThread,NULL,0,&dwThreadId);
fflush(stdout);
if(strcmp(argv[2],"w") == 0)
TestWriteFile(filePath,DataSize);
else if(strcmp(argv[2],"r") == 0)
TestReadFile(filePath,DataSize);
printf("done\n");
fflush(stdout);
Sleep(100);
//OneLineOutput("done\n");
printf("done\n");
fflush(stdout);
Sleep(100);
CloseHandle(hThread);
return 0;
}
// 测试写速度
void TestWriteFile(char *filepath,__int64 totalSize)
{
__int64 _sizeWriten = 0; // 已经写入的数据大小
__int64 _sizeLastWriten = 0; // 上次写入的数据大小
__int64 _cycTimes = totalSize / TestStrLen; // 计算循环次数
__int64 _sendSize = (__int64)(totalSize * Send_Rate)<(__int64)(10*1024*1024)?(__int64)(totalSize * Send_Rate):(__int64)(10*1024*1024); // 计算发送超限
char strWriteSpd[128]; // 写速度字符串
__int64 _CycStartCnt = 0,_CycCurCnt = 0;
double _timeS = 0;
double _sizeWritenM,_curWriteSpeed;
char sendbuf[256] = { 0 };
FILE *fp;
if(fopen_s(&fp,filepath,"w+") != 0)
{
//sprintf_s(strbuf,256,"Can not open file %s\n",filepath);
//OneLineOutput(strbuf);
fprintf(stderr,"Can not open file %s\n",filepath);
fflush(stderr);
return;
}
_CycStartCnt = GetCycleCount();
for(__int64 _i=0;_i<_cycTimes;_i++)
{
fwrite(TestStr,sizeof(char),TestStrLen,fp);
_sizeWriten += TestStrLen;
if(_sizeWriten - _sizeLastWriten >= _sendSize)
{
_sizeLastWriten = _sizeWriten;
_CycCurCnt = GetCycleCount();
_timeS = (double)((_CycCurCnt - _CycStartCnt)*1.0/Cpu_Freq); // 现在距起始的时间(S)
_sizeWritenM = (double)(_sizeWriten*1.0/1024/1024); // 已经写入的数据大小(M)
_curWriteSpeed = _sizeWritenM/_timeS; // 现在的写入速度 M/S
sprintf_s(sendbuf,sizeof(sendbuf),"[Written:%0.1fM,Speed:%0.2fM]/s\n",_sizeWritenM,_curWriteSpeed);
printf(sendbuf);
//OneLineOutput(sendbuf);
fflush(stdout);
}
}
_CycCurCnt = GetCycleCount();
if(fp!=NULL) fclose(fp);
_timeS = (double)((_CycCurCnt - _CycStartCnt)/Cpu_Freq*1.0); // 现在距起始的时间(S)
_sizeWritenM = (double)(_sizeWriten/1024*1.0/1024); // 已经写入的数据大小(M)
_curWriteSpeed = _sizeWritenM*1.0/_timeS; // 现在的写入速度 M/S
sprintf_s(strWriteSpd,128,"[Written:%0.1fM,Speed:%0.2fM]/s\n",_sizeWritenM,_curWriteSpeed);
printf(strWriteSpd);
//OneLineOutput(strWriteSpd);
fflush(stdout);
}
// 测试读速度
void TestReadFile(char *filepath,__int64 totalSize)
{
char _strReadSpd[256];
__int64 _sizeRead = 0;
__int64 _sizeLastRead = 0;
__int64 _sendSize = (__int64)(totalSize * Send_Rate)<(__int64)(10*1024*1024)?(__int64)(totalSize * Send_Rate):(__int64)(10*1024*1024); // 计算发送超限
double _sizeReadM = 0;
double _timeS = 0;
double _curReadSpd = 0;
__int64 _startCycCnt = 0,_curCycCnt = 0;
int numRead = 0;
char sendbuf[256] = { 0 };
FILE *fp;
fopen_s(&fp,filepath,"r");
if(fp == NULL)
{
sprintf_s(strbuf,256,"can not open file %s!\n",filepath);
//OneLineOutput(strbuf);
printf("can not open file %s!\n",filepath);
fflush(stdout);
return;
}
_startCycCnt = GetCycleCount();
while((numRead = fread(_strReadSpd,sizeof(char),256,fp)))
{
_sizeRead += numRead;
if(_sizeRead - _sizeLastRead >= _sendSize)
{
_sizeLastRead = _sizeRead;
_sizeReadM = (double)(_sizeRead/1024*1.0/1024);
_curCycCnt = GetCycleCount();
_timeS = double((_curCycCnt - _startCycCnt)*1.0/Cpu_Freq);
_curReadSpd = _sizeReadM/_timeS;
sprintf_s(sendbuf,sizeof(sendbuf),"[Read:%0.1fM,Speed:%0.2fM]/s\n",_sizeReadM,_curReadSpd);
printf(sendbuf);
//OneLineOutput(sendbuf);
fflush(stdout);
}
}
_curCycCnt = GetCycleCount();
if(fp!=NULL) fclose(fp);
_sizeReadM = (double)(_sizeRead/1024*1.0/1024);
_timeS = double((_curCycCnt - _startCycCnt)*1.0/Cpu_Freq);
_curReadSpd = _sizeReadM/_timeS;
sprintf_s(_strReadSpd,256,"[Read:%0.1fM,Speed:%0.2fM]/s\n",_sizeReadM,_curReadSpd);
//OneLineOutput(_strReadSpd);
printf(_strReadSpd);
fflush(stdout);
}
// 获取CPU频率
LONGLONG GetCPUFreq()
{
DWORD low1 = 0,high1 = 0, low2 = 0, high2 = 0;
LARGE_INTEGER fq,st,ed;
::QueryPerformanceFrequency(&fq); // 精确计时,返回(硬件支持的高精度计数器)
::QueryPerformanceCounter(&st); // 获取起始时间
__asm
{
rdtsc
mov low1,eax
mov high1,edx
}
Sleep(1000);
::QueryPerformanceCounter(&ed); // 获取结束时间
__asm
{
rdtsc // 读取CPU的时间戳计数器
mov low2,eax
mov high2,edx
}
// 将CPU的时间周期数转化为64位整数
LONGLONG begin = (LONGLONG)high1<<32 | low1;
LONGLONG end = (LONGLONG)high2<<32 | low2;
return (end - begin)*fq.QuadPart/(ed.QuadPart-st.QuadPart);
}