2011-04-15 68 views
2

我開始了新的項目類型的Windows窗體應用程序,我把兩個文本框(TextBox1的1和TextBox)和一個按鈕。我用打開文件對話框,選擇從系統中的文件,並把它在TextBox1的路徑,我把下面的代碼爲按鈕:本地WINAPI

HANDLE hFile; 
HANDLE hMap ; 
LPVOID base; 

hFile = ::CreateFile((LPCWSTR)Marshal::StringToHGlobalAnsi(this->textBox1->Text).ToPointer(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,0,OPEN_EXISTING , FILE_FLAG_SEQUENTIAL_SCAN, 0); 

unsigned long sifi= ::GetFileSize(hFile,NULL); 

if(hFile !=INVALID_HANDLE_VALUE){ 
hMap= ::CreateFileMapping(hFile, 0, PAGE_READONLY | SEC_COMMIT, 0, 0, 0);//create Mem mapping for the file in virtual memory 
} 
if(hMap!=NULL){ 
base = ::MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);//load the mapped file into the RAM 
          } 
this->textBox2->Text=sifi.ToString(); 

我試圖與該代碼做的是讀取TextBox1中的文件路徑用它打開文件句柄,然後獲取文件的大小並將其放入textbox2。現在的問題是,textbox2顯示文件大小的值不正確。它似乎總是像所有文件4294967295!

編輯:

謝謝你們,我已經解決了這個問題。它是CreateFile的第一個參數,它假設爲:

(LPCWSTR)Marshal::StringToHGlobalUni(this->textBox1->Text).ToPointer() 
+0

那豈不是更容易地使用內存.NET類映射是在.NET 4.0中引入的文件? – 2011-04-15 22:56:21

+0

是的,但我已經寫過.net 4.0 ,,順便說一句,如果我使用.net類比本機API更快? – Aan 2011-04-15 23:22:19

+0

獲得工作代碼會更快! ;-)我希望在性能方面沒有什麼區別。 – 2011-04-15 23:23:06

回答

2

我們推薦使用GetFileSizeEx而不是GetFileSize。但認爲你的CreateFile調用失敗。

CreateFile不接受HGLOBAL。並且你將字符串轉換爲ANSI,然後將它傳遞給Unicode版本的CreateFile,這也被破壞了。

只是停留在Unicode中,像這樣的:

pin_ptr<wchar_t> wszFilename = PtrToStringChars(textBox1->Text); 
HANDLE hFile = ::CreateFileW(wszFilename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,0,OPEN_EXISTING , FILE_FLAG_SEQUENTIAL_SCAN, 0); 
if (hFile == 0 || hFile == INVALID_HANDLE_VALUE) throw gcnew Win32Exception(); 
+0

我意識到這一點,感謝您的詳細解答。 – Aan 2011-04-15 23:18:20

2

GetFileSize函數返回一個錯誤值。

注意,如果返回值是 INVALID_FILE_SIZE(爲0xffffffff),一個 應用程序必須調用GetLastError來 確定函數是否具有 成功還是失敗。

查看API docs on MSDN

順便說一句,我覺得@大衛赫弗南有一個點在這裏。