歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> remove()和直接使用system的一個區別

remove()和直接使用system的一個區別

日期:2017/3/1 9:42:44   编辑:Linux編程

1、事出有因

今天在做一個從web頁面中得到POST回應數據的時候,需要把臨時文件夾裡面(包含子文件)內容清空。本來一直使用的是system("rmdir /s /q ..//tmp//data.txt")、後面測試使用system("del /s /q ..\\tmp\\data.txt")也是可以清空緩存數據文件的,但是發現這個每次都會顯示出控制台的黑框,而且我這個文件夾是大概每隔2秒中,要清空一次的。所以刪除多了之後,黑框會越來越多。總之很不好!

2、臨時解決辦法

臨時的一個解決辦法,設置控制台命令的屬性,讓其進行隱藏運行,代碼如下:

BOOL SystemHide(char* CommandLine)
{
SECURITY_ATTRIBUTES sa;
HANDLE hRead, hWrite;

sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
if (!CreatePipe(&hRead, &hWrite, &sa, 0))
{
return FALSE;
}

STARTUPINFO si;
PROCESS_INFORMATION pi;
si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
si.hStdError = hWrite;
si.hStdOutput = hWrite;
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
//關鍵步驟,CreateProcess函數參數意義請查閱MSDN
if (!CreateProcess(NULL, CommandLine, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi))
{
return FALSE;
}
CloseHandle(hWrite);
char buffer[4096] = { 0 };
DWORD bytesRead;
while(true)
{
memset(buffer, 0, strlen(buffer));
if(ReadFile(hRead, buffer, 4095, &bytesRead, NULL) == NULL)
{
break;
}
//buffer中就是執行的結果,可以保存到文本,也可以直接輸出
//printf(buffer);//這行注釋掉就可以了
Sleep(100);
}
return TRUE;
}

代碼就不詳細解釋了,說說結果吧。

已經能夠隱藏掉控制台的窗口了,但有的時候,並不能刪掉對應的文件,我也不知道為何,後面總覺得應該在c++中有對應的api吧,就沒在糾結了(稍微看了一下,總覺得是傳入函數的參數少個一個/導致的)。

3、找到對應的函數

而且還是跨平台的!本來就要打算用ofstream再重新覆蓋掉對應的文件了!沒想到google了下,發現了這個函數可以直接刪除文件,還是個跨平台的!使用時就需要傳進來一個path,我這裡沒涉及到chmod,所以直接使用(如果涉及,還需要使用system或者別的api改變文件的權限)。

remove("..\\tmp\\data.txt");

這是他整個函數的源代碼,其實也就是使用了windows的DeleteFile整個api:

int __cdecl remove (
const char *path
)
{
wchar_t* pathw = NULL;
int retval;

if (path)
{
if (!__copy_path_to_wide_string(path, &pathw))
return -1;
}

/* call the wide-char variant */
retval = _wremove(pathw);

_free_crt(pathw); /* _free_crt leaves errno alone if everything completes as expected */

return retval;
}

#else /* _UNICODE */

int __cdecl _wremove (
const wchar_t *path
)
{
ULONG dosretval;

if (!DeleteFileW(path))
dosretval = GetLastError();
else
dosretval = 0;

if (dosretval) {
/* error occured -- map error code and return */
_dosmaperr(dosretval);
return -1;
}

return 0;
}

4、結語

一般的函數,都能在c/c++的庫中找到。我上面為了追求快速,使用了system和system的隱藏屬性,但是問題多多,用戶給我反應說,整個data.txt會越來越大,程序運行2個小時,這個文件的大小已經變成了800多M(沒有正確刪除,libcurl一直追加了),如果運行一個晚上,將不可設想。

與其使用system裡面的命令,還不如直接在c/c++的庫中找到對應的函數並使用!

Copyright © Linux教程網 All Rights Reserved