2011-09-03 5 views
3

를 사용하여이 코드VB6 : 바이너리 파일은 어떻게 암호화됩니까? 넣어 문

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 구조체 (WpRec)의 매트릭스의 바이너리 직렬화를 만드는에게 있습니다. 하지만 나는 그것이 인코딩 된 방법을 얻지 못했습니다 ... C#에서 동일한 serialization을 다시 작성해야하기 때문에 중요합니다.하지만 C#에서 동일한 작업을 수행 할 수 있도록 인코딩 방법이 무엇인지 알아야합니다. ..

+1

인코딩은 2 진수로 처리하기에는 까다 롭습니다. 최선의 방법은 VB6 파일을 작성하는 FilePut() 함수를 사용하는 것입니다. http://msdn.microsoft.com/en-us/library/0s9sa1ab.aspx –

+0

@ 한스 +1 귀하의 의견을 바탕으로 답변, 정말 대답이 될 자격이 – MarkJ

답변

4

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); 
    } 
} 
0

VB6의 put 문은 인코딩을 수행하지 않습니다. 내부적으로 메모리에 저장되는 것처럼 구조를 저장합니다. 예를 들어, put은 메모리에 표시된 것처럼 double을 64 비트 부동 소수점 값으로 저장합니다. 위 예제에서 WpRec 멤버는 메모리에 저장된 것처럼 put 문에 저장됩니다.

+0

전체 이야기 아닙니다. 문자열은 내부적으로 유니 코드로 저장되지만 Put은 시스템 기본 코드 페이지를 사용하여 인코딩 된 "ANSI"로 씁니다. – MarkJ

+0

좋은 점 @MarkJ – xpda

2

Microsoft.VisualBasic에 대한 참조를 추가하고 FilePut

사용 그것은과의 호환성을 지원하기 위해 designed입니다 VB6

은 문제의 VB6 코드 (I이 컴파일하지 않은)

Microsoft.VisualBasic.FileOpen (1, WritingPath & "\FplDb.txt", OpenMode.Random, 
    RecordLength:=Marshal.SizeOf(WpRec)) 
for (i = 1; i < 100 ; i++) { 
    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) 
    Microsoft.VisualBasic.FilePut(1, WpRec, i) 
} 
Microsoft.VisualBasic.FileClose(1) 
C#에서이 같은 것

나는 Marshal.SizeOf(WpRec)이 VB6에서 반환 할 Len(WpRec)과 동일한 값을 반환한다고 생각한다.

관련 문제