2011-04-15 29 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

顺便说一句,我觉得@大卫赫弗南有一个点在这里。