VB6의 까다로운 점은 고정 길이 문자열이있는 구조를 선언 할 수있어서 길이 접두사가 필요없는 문자열이 포함 된 레코드를 쓸 수 있다는 것이 었습니다. 문자열 버퍼의 길이가 레코드로 쓰여지는 대신 형식으로 인코딩되었습니다. 고정 크기 레코드가 허용됩니다. .NET에서 이것은 VB.NET이 이전 버전과의 호환성을 위해 지원하는 메커니즘을 가지고 있다는 의미에서 다소 남겨져 있지만, 실제로 말할 수있는 한 C#을위한 것이 아닙니다. How to declare a fixed-length string in VB.NET?.
.NET은 일반적으로 길이 접두사가있는 문자열을 쓰는 것을 선호하는 것으로 보입니다. 즉, 레코드는 일반적으로 가변 길이입니다. 이는 BinaryReader.ReadString 구현에 의해 제안됩니다.
그러나 System.BitConverter를 사용하면 레코드가 직렬화되고 바이트로 직렬화 해제되는 방식을보다 세밀하게 제어 할 수 있습니다. System.IO.BinaryReader 및 System.IO.BinaryWriter는 문자열에 다음과 같은 가정을하기 때문에 유용하지 않을 수 있습니다. 길이 접두사). VB6 Integer는 .NET Int16에 매핑되고 VB6 Long은 .Net Int32입니다. 나는 당신이 당신의 VB6 구조를 정의하는 방법을 정확히 알고 있지만, 여기에 예를 들어 하나의 가능한 구현입니다하지 않습니다
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);
}
}
인코딩은 2 진수로 처리하기에는 까다 롭습니다. 최선의 방법은 VB6 파일을 작성하는 FilePut() 함수를 사용하는 것입니다. http://msdn.microsoft.com/en-us/library/0s9sa1ab.aspx –
@ 한스 +1 귀하의 의견을 바탕으로 답변, 정말 대답이 될 자격이 – MarkJ