在C#中我定义了一个Struct:
public struct AccountType
{
public int Order;
public double Money;
public bool InOut;
public string Memo; //问题一:在C#中如何定义定长字符串
}
问题二:
如何直接向FileStream中二进制形式写入Struct,现在我只会分开写?
public struct AccountType
{
public int Order;
public double Money;
public bool InOut;
public string Memo; //问题一:在C#中如何定义定长字符串
}
问题二:
如何直接向FileStream中二进制形式写入Struct,现在我只会分开写?
public string Memo{
get { return memo; }
set {
if (value != null && value.Length > 100)
// 注:你可能希望判断字节长度而不是字符数量
throw new ArgumentException("Memo too long");
else
memo = value;
}
}至于二进制,用二进制序列化虽然是办法之一,但是序列化会额外添加很多信息,特别是程序集版本信息。如果你确定结构不会改变,自己写From/ToBytes也不错: public struct AccountType
{
public int Order;
public double Money;
public bool InOut;
public string Memo; public static AccountType FromBytes(byte[] bytes)
{
AccountType at = new AccountType();
using (BinaryReader br = new BinaryReader(new MemoryStream(bytes, false)))
try
{
at.Order = br.ReadInt32();
at.Money = br.ReadDouble();
at.InOut = br.ReadBoolean();
if (br.ReadBoolean()) // string 是否为空的标记
at.Memo = br.ReadString();
}
catch
{
throw new ArgumentException("Error parsing structure", "bytes");
}
finally
{
br.Close();
}
return at;
} public byte[] ToBytes()
{
MemoryStream ms = new MemoryStream();
BinaryWriter bw = new BinaryWriter(ms);
bw.Write(Order);
bw.Write(Money);
bw.Write(InOut);
bw.Write(Memo != null);
if (Memo != null) bw.Write(Memo);
bw.Close();
return ms.ToArray();
} public override string ToString()
{
return String.Format("{{Order={0},Money={1},InOut={2},Memo={3}}}",
Order, Money, InOut, Memo == null ? "<null>" : Memo);
} } class Class1
{
static void Main(string[] args)
{
AccountType at = new AccountType();
at.Order = 123; at.Money = 12.3; at.InOut = true; at.Memo = "books";
Console.WriteLine(at); BinaryWriter bw = new BinaryWriter(File.Create("C:\\test.bin"));
bw.Write(at.ToBytes());
bw.Close(); FileStream fs = File.OpenRead("C:\\test.bin");
int len = (int)fs.Length;
byte[] buffer = new byte[len];
fs.Read(buffer, 0, len);
fs.Close();
AccountType at2 = AccountType.FromBytes(buffer);
Console.WriteLine(at2);
Console.ReadLine();
} }
我还想知道利用FileStream\BinaryWriter,来把文件的后面一部分截掉。例如,我的文件test.dat现在是1024 bytes长,我现在想把后24个bytes截掉,使得文件的长度变成1000bytes。实际上我是想实现对二进制文件的记录进行插入(不是增加),和删除。
???
因为BinaryReader/Writer是首先写字符串长度,然后按UTF8编码将字符串写入流的,如果你截掉后面的部分,会出现两个状况:
1)流不够长,读取出错
2)一个被编码成两个或三个字节的字符如果被拦腰截断,会发生编码错误警告过之后,下面是你要的解决方法:FileStream fs = File.Open("C:\\test.bin", FileMode.Open);
if (fs.Length > 1000)
fs.SetLength(1000);
fs.Close();
FileInfo fi = new FileInfo("C:\\test.bin");
Console.WriteLine(fi.Length);