這不是如果文件中的記錄包含一個字符串,那麼你聲明的結構相似,你會如何聲明它在C:
struct Example {
int mumble; // Anything, not necessarily a string length
char text[42];
// etc...
};
等價的C#聲明會是什麼樣子:
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
private struct Example {
public int mumble;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 42)]
public string text;
// etc...
}
您通常會使用BinaryReader來讀取數據。但它不能直接處理這樣的字符串,你必須將它們作爲byte []讀取,然後自己進行字符串轉換。你也不能利用聲明語法,你必須爲結構的每個成員編寫一個調用。
有一個解決方法,Marshal類已經知道如何使用PtrToStructure()方法將非託管結構轉換爲託管結構。這是一個通用的實現,它適用於任何blittable類型。兩個版本,一個是從byte []讀取的靜態文件,另一個是從流中重複讀取的實例方法。你會使用一個FileStream或MemoryStream。
using System;
using System.IO;
using System.Runtime.InteropServices;
class StructTranslator {
public static bool Read<T>(byte[] buffer, int index, ref T retval) {
if (index == buffer.Length) return false;
int size = Marshal.SizeOf(typeof(T));
if (index + size > buffer.Length) throw new IndexOutOfRangeException();
var handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
try {
IntPtr addr = (IntPtr)((long)handle.AddrOfPinnedObject() + index);
retval = (T)Marshal.PtrToStructure(addr, typeof(T));
}
finally {
handle.Free();
}
return true;
}
public bool Read<T>(Stream stream, ref T retval) {
int size = Marshal.SizeOf(typeof(T));
if (buffer == null || size > buffer.Length) buffer = new byte[size];
int len = stream.Read(buffer, 0, size);
if (len == 0) return false;
if (len != size) throw new EndOfStreamException();
var handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
try {
retval = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
}
finally {
handle.Free();
}
return true;
}
private byte[] buffer;
}
未經測試,希望它能正常工作。
您提出的C代碼有問題,因此您將其轉換爲C#的機會註定要失敗! – 2010-10-05 11:32:47
這取決於。多少條數據記錄?他們多大? – 2010-10-05 11:34:44