歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

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

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