我不知道你的數據是如何序列化的(你沒有指定任何協議或數據描述);但是你說過,爲其他問題制定解決方案可以解決你的問題。我正在給你一個闡述:你可以很容易地改變我的實現,以便根據你的格式解析數據(而不是像下面的例子那樣使用二進制流)。
我認爲在您提到的問題中,他們建議實施自己的屬性以獲得解決方案。
我可以在這裏給出一個實現的例子(這只是一個例子,在生產使用前編輯它...):包含你的數據結構
文件:
//MyData.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FixedLengthFileReader
{
class MyData
{
[Layout(0, 10)]
public string field1;
[Layout(10, 4)]
public int field2;
[Layout(14, 8)]
public double field3;
public override String ToString() {
return String.Format("String: {0}; int: {1}; double: {2}", field1, field2, field3);
}
}
}
屬性:
// LayoutAttribute.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FixedLengthFileReader
{
[AttributeUsage(AttributeTargets.Field)]
class LayoutAttribute : Attribute
{
private int _index;
private int _length;
public int index
{
get { return _index; }
}
public int length
{
get { return _length; }
}
public LayoutAttribute(int index, int length)
{
this._index = index;
this._length = length;
}
}
}
閱讀器實現的例子:
//FixedLengthReader.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Reflection;
namespace FixedLengthFileReader
{
class FixedLengthReader
{
private Stream stream;
private byte[] buffer;
public FixedLengthReader(Stream stream)
{
this.stream = stream;
this.buffer = new byte[4];
}
public void read<T>(T data)
{
foreach (FieldInfo fi in typeof(T).GetFields())
{
foreach (object attr in fi.GetCustomAttributes())
{
if (attr is LayoutAttribute)
{
LayoutAttribute la = (LayoutAttribute)attr;
stream.Seek(la.index, SeekOrigin.Begin);
if (buffer.Length < la.length) buffer = new byte[la.length];
stream.Read(buffer, 0, la.length);
if (fi.FieldType.Equals(typeof(int)))
{
fi.SetValue(data, BitConverter.ToInt32(buffer, 0));
}
else if (fi.FieldType.Equals(typeof(bool)))
{
fi.SetValue(data, BitConverter.ToBoolean(buffer, 0));
}
else if (fi.FieldType.Equals(typeof(string)))
{
// --- If string was written using UTF8 ---
byte[] tmp = new byte[la.length];
Array.Copy(buffer, tmp, tmp.Length);
fi.SetValue(data, System.Text.Encoding.UTF8.GetString(tmp));
// --- ALTERNATIVE: Chars were written to file ---
//char[] tmp = new char[la.length - 1];
//for (int i = 0; i < la.length; i++)
//{
// tmp[i] = BitConverter.ToChar(buffer, i * sizeof(char));
//}
//fi.SetValue(data, new string(tmp));
}
else if (fi.FieldType.Equals(typeof(double)))
{
fi.SetValue(data, BitConverter.ToDouble(buffer, 0));
}
else if (fi.FieldType.Equals(typeof(short)))
{
fi.SetValue(data, BitConverter.ToInt16(buffer, 0));
}
else if (fi.FieldType.Equals(typeof(long)))
{
fi.SetValue(data, BitConverter.ToInt64(buffer, 0));
}
else if (fi.FieldType.Equals(typeof(float)))
{
fi.SetValue(data, BitConverter.ToSingle(buffer, 0));
}
else if (fi.FieldType.Equals(typeof(ushort)))
{
fi.SetValue(data, BitConverter.ToUInt16(buffer, 0));
}
else if (fi.FieldType.Equals(typeof(uint)))
{
fi.SetValue(data, BitConverter.ToUInt32(buffer, 0));
}
else if (fi.FieldType.Equals(typeof(ulong)))
{
fi.SetValue(data, BitConverter.ToUInt64(buffer, 0));
}
}
}
}
}
}
}
最後方案實施的一個例子(很簡單):
// Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace FixedLengthFileReader
{
class Program
{
static void Main(string[] args)
{
MyData md = new MyData();
Console.WriteLine(md);
Stream s = File.OpenRead("testFile.bin");
FixedLengthReader flr = new FixedLengthReader(s);
flr.read(md);
s.Close();
Console.WriteLine(md);
}
}
}
如果你想測試對一個例子二進制文件代碼,你可以創建具有以下的十六進制代碼的文件:
41 42 43 44 45 46 47 48 49 4A 01 00 00 00 00 00 00
00 00 00 E0 3F
它代表的字節:
- 字符串ABCDEFGHIJ(10字節)
- 整數1(4字節)
- 雙0.5(8字節)
(我使用XVI32創建了一個文件,添加了十六進制代碼並將其保存爲testFile.bin)
您的固定長度文件是怎樣的?在我們提出任何建議之前,我們可以先看看內容以及您嘗試過的內容嗎? – 2014-09-26 13:18:50
@theghostofc現在我正在實現StreamReader,後來計劃使用簡單的字符串函數(如spilt或indexof)來獲取數據..但是我想知道是否所有這些都可以跳過,就像我在上面提供的鏈接中那樣,那麼代碼將看起來更乾淨。請不要在這裏我不要求代碼,只是想知道我在這種情況下有什麼選擇。 – IFlyHigh 2014-09-26 13:56:26
編輯我的問題也爲示例固定長度文件。 – IFlyHigh 2014-09-26 13:56:52