我正在使用傳統文件格式。託管.NET等同於WinBase中的CreateFile和WriteFile(kernel32.dll)
該文件是使用非託管C++創建的,該C++利用WinBase.h CreateFile()& WriteFile()函數(可在kernel32.dll中找到)。我一直在以P
/Invoke的互操作來訪問,像這樣這些本機功能:
[DllImport("kernel32.dll")]
public static extern bool WriteFile(
IntPtr hFile,
byte[] lpBuffer,
uint nNumberOfBytesToWrite,
out uint lpNumberOfBytesWritten,
[In] ref NativeOverlapped lpOverlapped);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool WriteFileEx(
IntPtr hFile,
byte[] lpBuffer,
uint nNumberOfBytesToWrite,
[In] ref NativeOverlapped lpOverlapped,
WriteFileCompletionDelegate lpCompletionRoutine);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr CreateFile(
string lpFileName, uint dwDesiredAccess,
uint dwShareMode, IntPtr lpSecurityAttributes,
uint dwCreationDisposition,
uint dwFlagsAndAttributes, IntPtr hTemplateFile);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool CloseHandle(IntPtr hObject);
public delegate void WriteFileCompletionDelegate(
UInt32 dwErrorCode,
UInt32 dwNumberOfBytesTransfered,
ref NativeOverlapped lpOverlapped);
與此問題是,當我打電話的WriteFile(),該文件總是由程序調用覆蓋。
優選我想使用一個兼容的.NET等價物,它將允許我生成完全相同的輸出格式。
的C++代碼看起來像這樣:(WORKING)
HANDLE hFile = CreateFile(sFileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
WriteFile(hFile, &someVar1, sizeof(bool), &dwWritten, NULL);
WriteFile(hFile, &someVar1, sizeof(long), &dwWritten, NULL);
WriteFile(hFile, &someVar2, sizeof(bool), &dwWritten, NULL);
WriteFile(hFile, sStr.GetBuffer(0), dwStrLen*sizeof(TCHAR), &dwWritten, NULL);
CloseHandle(hFile);
C#的是如下:(覆蓋以前WRITE即會輸出文件將只包含 'T')
{
var hFile = COMFileOps2.CreateFile(FILE_NAME, (uint) COMFileOps2.FILE_GENERIC_WRITE,
COMFileOps2.FILE_SHARE_WRITE, IntPtr.Zero, COMFileOps2.CREATE_ALWAYS,
COMFileOps2.FILE_ATTRIBUTE_NORMAL, IntPtr.Zero);
var natOverlap = new NativeOverlapped();
COMFileOps2.WriteFileEx(hFile, new byte[] {(byte) 't'}, 1, ref natOverlap, Callback);
COMFileOps2.WriteFileEx(hFile, new byte[] { (byte)'e' }, 1, ref natOverlap, Callback);
COMFileOps2.WriteFileEx(hFile, new byte[] { (byte)'s' }, 1, ref natOverlap, Callback);
COMFileOps2.WriteFileEx(hFile, new byte[] { (byte)'T' }, 1, ref natOverlap, Callback);
COMFileOps2.CloseHandle(hFile);
}
private static void Callback(uint dwerrorcode, uint dwnumberofbytestransfered, ref NativeOverlapped lpoverlapped)
{
throw new NotImplementedException();
}
更新:下面的C#代碼將寫出「測試」:
uint written;
uint position = 0;
var natOverlap0 = new NativeOverlapped();
COMFileOps.WriteFile(hFile, new byte[] {(byte) 'T'}, 1, out written, ref natOverlap0);
position += written;
var natOverlap1 = new NativeOverlapped {OffsetLow = (int) position};
COMFileOps.WriteFile(hFile, new byte[] { (byte)'e' }, 1, out written, ref natOverlap1);
position += written;
var natOverlap2 = new NativeOverlapped { OffsetLow = (int)position };
COMFileOps.WriteFile(hFile, new byte[] { (byte)'s' }, 1, out written, ref natOverlap2);
position += written;
var natOverlap3 = new NativeOverlapped { OffsetLow = (int)position };
COMFileOps.WriteFile(hFile, new byte[] { (byte)'t' }, 1, out written, ref natOverlap3);
COMFileOps.CloseHandle(hFile);
謝謝。
實際上,原始的API調用I/O比功能強大得多。例如,Win32函數可以與控制檯,命名管道,郵筒,串行端口一起工作(並且可以通過其真實設備名稱打開所述串行端口),真正漫長而奇怪的文件名等。但是這些似乎都不適用於此。 – 2010-03-22 17:54:31