VB6:如何是二进制文件的连接codeD?使用PUT语句 [英] VB6: How are binary files encoded? using Put statement

查看:173
本文介绍了VB6:如何是二进制文件的连接codeD?使用PUT语句的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的code

  Open WritingPath & "\FplDb.txt" For Random As #1 Len = Len(WpRec)
    For i = 1 To 99
      WpRec.WpIndex = FplDB(i, 1)
      WpRec.WpName = FplDB(i, 2)
      WpRec.WpLat = FplDB(i, 3)
      WpRec.WpLon = FplDB(i, 4)
      WpRec.WpLatDir = FplDB(i, 5)
      WpRec.WpLonDir = FplDB(i, 6)
      Put #1, i, WpRec
   Next i
   Close #1
   SaveOk = 1
   FplSave = SaveOk
   Exit Function

此功能使99结构(W preC)提交一份矩阵的二进制序列化,采用开放与放的语句。但我没有得到它是如何连接$ C $ ... CD这对我很重要,因为我需要重写在C#中相同的序列化,但我需要知道什么编码方法用于那些这样我就可以做同样的在C#....

This function makes binary serialization of a matrix of 99 structs (WpRec) to file, using "Open" and "Put" statements. But I didn't get how it is encoded... It is important to me because I need to rewrite the same serialization in C# but I need to know what encoding method is used for that so I can do the same in C#....

推荐答案

在VB6的有点棘手的是,你被允许使用固定长度的字符串来声明结构,以便您可以编写包含字符串的记录中并不需要的长度preFIX。字符串缓冲区的长度为EN codeD插入类型,而不是需要与记录写出来。这允许用于固定大小的记录。在.NET中,这一种被抛在后面的感觉,VB.NET有一个机制,以支持它向后兼容,但它不是真正用于C#,据我可以告诉:的How在VB.NET声明固定长度的字符串?

The tricky bit in VB6 was that you were allowed to declare structures with fixed length strings so that you could write records containing strings that didn't need a length prefix. The length of the string buffer was encoded into the type instead of needing to be written out with the record. This allowed for fixed size records. In .NET, this has kind of been left behind in the sense that VB.NET has a mechanism to support it for backward compatibility, but it's not really intended for C# as far as I can tell: How to declare a fixed-length string in VB.NET?.

.NET似乎对通常写出串具有长度preFIX,这意味着记录通常是可变长度的preference。这是由 BinaryReader.ReadString 。

.NET seems to have a preference for generally writing out strings with a length prefix, meaning that records are generally variable-length. This is suggested by the implementation of BinaryReader.ReadString.

不过,您可以使用System.BitConverter拿到过如何记录被序列化,反序列化的字节(System.IO.BinaryReader和System.IO.BinaryWriter也有可能不是用更精细的控制,因为他们作出这样的字符串有一个假设长度preFIX)。请记住,VB6的整数映射到.NET的Int16和VB6龙是一个.NET的Int32。我不知道究竟你是如何定义你的VB6的结构,但这里有一个可能的实现作为一个例子:

However, you can use System.BitConverter to get finer control over how records are serialized and de-serialized as bytes (System.IO.BinaryReader and System.IO.BinaryWriter are probably not useful since they make assumptions that strings have a length prefix). Keep in mind that a VB6 Integer maps to a .NET Int16 and a VB6 Long is a .Net Int32. I don't know exactly how you have defined your VB6 structure, but here's one possible implementation as an example:

class Program
{
  static void Main(string[] args)
  {
     WpRecType[] WpRec = new WpRecType[3];
     WpRec[0] = new WpRecType();
     WpRec[0].WpIndex = 0;
     WpRec[0].WpName = "New York";
     WpRec[0].WpLat = 40.783f;
     WpRec[0].WpLon = 73.967f;
     WpRec[0].WpLatDir = 1;
     WpRec[0].WpLonDir = 1;
     WpRec[1] = new WpRecType();
     WpRec[1].WpIndex = 1;
     WpRec[1].WpName = "Minneapolis";
     WpRec[1].WpLat = 44.983f;
     WpRec[1].WpLon = 93.233f;
     WpRec[1].WpLatDir = 1;
     WpRec[1].WpLonDir = 1;
     WpRec[2] = new WpRecType();
     WpRec[2].WpIndex = 2;
     WpRec[2].WpName = "Moscow";
     WpRec[2].WpLat = 55.75f;
     WpRec[2].WpLon = 37.6f;
     WpRec[2].WpLatDir = 1;
     WpRec[2].WpLonDir = 2;
     byte[] buffer = new byte[WpRecType.RecordSize];
     using (System.IO.FileStream stm = 
        new System.IO.FileStream(@"C:\Users\Public\Documents\FplDb.dat",
        System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite))
     {
        WpRec[0].SerializeInto(buffer);
        stm.Write(buffer, 0, buffer.Length);
        WpRec[1].SerializeInto(buffer);
        stm.Write(buffer, 0, buffer.Length);
        WpRec[2].SerializeInto(buffer);
        stm.Write(buffer, 0, buffer.Length);

        // Seek to record #1, load and display it
        stm.Seek(WpRecType.RecordSize * 1, System.IO.SeekOrigin.Begin);
        stm.Read(buffer, 0, WpRecType.RecordSize);
        WpRecType rec = new WpRecType(buffer);
        Console.WriteLine("[{0}] {1}: {2} {3}, {4} {5}", rec.WpIndex, rec.WpName,
           rec.WpLat, (rec.WpLatDir == 1) ? "N" : "S",
           rec.WpLon, (rec.WpLonDir == 1) ? "W" : "E");
     }
  }
}

class WpRecType
{
  public short WpIndex;
  public string WpName;
  public Single WpLat;
  public Single WpLon;
  public byte WpLatDir;
  public byte WpLonDir;

  const int WpNameBytes = 40; // 20 unicode characters
  public const int RecordSize = WpNameBytes + 12;

  public void SerializeInto(byte[] target)
  {
     int position = 0;
     target.Initialize();
     BitConverter.GetBytes(WpIndex).CopyTo(target, position);
     position += 2;
     System.Text.Encoding.Unicode.GetBytes(WpName).CopyTo(target, position);
     position += WpNameBytes;
     BitConverter.GetBytes(WpLat).CopyTo(target, position);
     position += 4;
     BitConverter.GetBytes(WpLon).CopyTo(target, position);
     position += 4;
     target[position++] = WpLatDir;
     target[position++] = WpLonDir;
  }

  public void Deserialize(byte[] source)
  {
     int position = 0;
     WpIndex = BitConverter.ToInt16(source, position);
     position += 2;
     WpName = System.Text.Encoding.Unicode.GetString(source, position, WpNameBytes);
     position += WpNameBytes;
     WpLat = BitConverter.ToSingle(source, position);
     position += 4;
     WpLon = BitConverter.ToSingle(source, position);
     position += 4;
     WpLatDir = source[position++];
     WpLonDir = source[position++];
  }

  public WpRecType()
  {
  }

  public WpRecType(byte[] source)
  {
     Deserialize(source);
  }
}

这篇关于VB6:如何是二进制文件的连接codeD?使用PUT语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆