在C#中我定义了一个Struct:
public struct AccountType
{
public int Order;
public double Money;
public bool InOut;
public string Memo; //问题一:在C#中如何定义定长字符串
}
问题二:
如何直接向FileStream中二进制形式写入Struct,现在我只会分开写?

解决方案 »

  1.   

    1.定长字符串? .Net中只有string一种字符串类型.2.struct要能序列化二进制才可以吧.  没玩过...
      

  2.   

    1) 从你定义的struct的字面看,Memo绝对不应该定长,你想定长是为了容易读写二进制形式吧?有其它方法的。如果要“定最大长度”,就用 Property,即private string memo;
    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();
    } }
      

  3.   

    强!!!谢谢大佬 netmicro(麦)
    我还想知道利用FileStream\BinaryWriter,来把文件的后面一部分截掉。例如,我的文件test.dat现在是1024 bytes长,我现在想把后24个bytes截掉,使得文件的长度变成1000bytes。实际上我是想实现对二进制文件的记录进行插入(不是增加),和删除。
    ???
      

  4.   

    希望你不会需要将属于Memo的部分截掉
    因为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);