2013-06-27 36 views
1

大家早上好!將結構中的字節寫入c文件中#

我在這裏遇到一個新問題。我必須寫下來自我在系統中聲明的結構的數據。

我創建的結構只有兩個字段,我用它來稍後將其轉換爲字節。

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] 
public struct MyStructData 
{ 
    public short Id; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)] 
    public string Name; 
} 

我轉換這個結構以字節爲單位用以下代碼:

private byte[] getBytes(MyStructData aux) 
{ 
    int length = Marshal.SizeOf(aux); 
    IntPtr ptr = Marshal.AllocHGlobal(length); 
    byte[] myBuffer = new byte[length]; 

    Marshal.StructureToPtr(aux, ptr, true); 
    Marshal.Copy(ptr, myBuffer, 0, length); 
    Marshal.FreeHGlobal(ptr); 

    return myBuffer; 
} 

此功能是由每個元素在MyStructData類型元素的列表結構的內部變換,其中我有所有我想要的寄存器發送到另一臺機器,和我一起粘貼下面的代碼做到這一點:

string saveToFilePath = "D:\\" + filename; 
Stream myStream = myFtpRequest.GetRequestStream(); 

using (FileStream myFileStream = new FileStream(saveToFilePath, FileMode.Create)) 
{ 
    foreach (MyStructData myData in myStructDataList) 
    { 
     int length = 2048; 
     byte[] newBuffer = new byte[length]; 
     newBuffer = getBytes(myCust); 

     int len = 0; 
     int bytesRead = 0; 

     myFileStream.Write(newBuffer, 0, len); 
     bytesRead += len; 
    } 

    myFileStream.Close(); 
} 

我的問題就來了,我看到我的新文件是空的,我不明白爲什麼它不會得到在形成我的字節。我已經檢查過列表是否帶有數據,我也檢查過我的字節轉換功能是否完美,但我無法明白是什麼原因導致我的文件是空的。

如果有人知道隧道盡頭的光線,我將非常感謝您的幫助!

編輯現在我有另一種方法將數據寫入到文件和它的作品好:

using (Stream stream = new FileStream(saveToFilePath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) 
{ 
    using (BinaryWriter writer = new BinaryWriter(stream, Encoding.Default)) 
    { 
     // get all data 
     foreach (MyStructData myData in myStructDataList) 
     { 
      byte[] newBuffer = getBytes(cd); 
      writer.Write(newBuffer); 
     } 
    } 
} 

回答

4

的第三個參數FileStream.Write是一個字節到計數。它不應該是0.

string saveToFilePath = "D:\\" + filename; 
Stream myStream = myFtpRequest.GetRequestStream(); 

int bytesWritten = 0; 
using (FileStream myFileStream = new FileStream(saveToFilePath, FileMode.Create)) 
{ 
    foreach (MyStructData myData in myStructDataList) 
    { 
     newBuffer = getBytes(myData); 
     myFileStream.Write(newBuffer, 0, newBuffer.Length); 
     bytesWritten += newBuffer.Length; 
    } 
} 
+0

當我在代碼中寫入第二行時,它給了我一個錯誤。它將void函數寫入myFileStream中,因此它根本不返回任何int值。 –

+0

對不起,我編輯了答案。 –

+0

謝謝!這工作得很好,現在我去我的下一個問題,所以我希望我不打擾你們所有 –

3

我不認爲你應該將數據寫入這樣的文件。對於一個簡單的結構,你最好使用BinaryFormatter

下面是一個例子。首先,你需要做MyStructData序列化通過將[Serializable]屬性:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] 
[Serializable] 
public struct MyStructData 
{ 
    public short Id; 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)] 
    public string Name; 
} 

然後你就可以寫那些結構的列表保存到文件,像這樣:

List<MyStructData> data = new List<MyStructData>(); 

for (short i = 0; i < 100; ++i) 
    data.Add(new MyStructData{Id = i, Name = i.ToString()}); 

string filename = "C:\\test\\test.data"; 

using (var file = File.OpenWrite(filename)) 
{ 
    var writer = new BinaryFormatter(); 
    writer.Serialize(file, data); // Writes the entire list. 
} 

而且你可以閱讀他們回來,像這樣:

using (var file = File.OpenRead(filename)) 
{ 
    var reader = new BinaryFormatter(); 
    data = (List<MyStructData>) reader.Deserialize(file); // Reads the entire list. 
} 

foreach (var item in data) 
    Console.WriteLine("Id = {0}, Name = {1}", item.Id, item.Name); 

如果您添加的編組的結構是這樣,你可以寫和讀給並從文件的唯一原因,然後你可以將其取下,你ST ruct看起來像這樣:

[Serializable] 
public struct MyStructData 
{ 
    public short Id; 
    public string Name; 
} 
+0

這看起來很好...我不知道如果我應該使用它,因爲這是一個測試發送文件,也許我必須改變結構更復雜一些。 –

+0

@MarialvyMartínez'BinaryFormatter'可以處理相當複雜的事情。它無法處理的是與非託管資源有關的事情(例如窗口句柄),但我不認爲你會序列化這些資源。我只建議BinaryFormatter,因爲它使用起來相當簡單。爲了更好的控制,你可以使用XmlSerializer。無論哪種方式,你都不應該爲了序列化而自己編組數據!編組實際上是將數據傳遞給非託管代碼。 –

+0

我強烈建議您在做出決定之前閱讀此內容:http://msdn.microsoft.com/en-us/library/vstudio/ms233843.aspx我可以說的一件事情:使用元帥做序列化是非常錯誤的。 –