Visual Basic到c#:以字符串形式加载二进制文件

本文关键字:加载 二进制文件 字符串 Basic Visual | 更新日期: 2023-09-27 18:09:36

我必须将一个项目从旧的VB6转换为c#,目的是尽可能多地保留旧代码,时间问题。

旧项目的一个函数将二进制文件加载到字符串变量中,然后使用asc函数分析该变量的单字符值:

旧VB代码:

Public Function LoadText(ByVal DirIn As String) As String
    Dim FileBuffer As String
    Dim LenghtFile As Long
    Dim ContIN As Long
    ContIN = FreeFile
    Open DirIn For Binary Access Read As #ContIN
    LenghtFile = LOF(ContIN)
    FileBuffer = Space(LenghtFile)
    Get #ContIN, , FileBuffer
    Close #ContIN
    LoadText = FileBuffer
    'following line for test purpose
    debug.print(asc(mid(filebuffer,1,1)))
    debug.print(asc(mid(filebuffer,2,1)))
    debug.print(asc(mid(filebuffer,3,1)))
End Function
SUB Main
    dim testSTring as String
    teststring=loadtext("e:'testme.bin")
end sub

结果立即窗口:

1

10

133年

c#代码:

public static string LoadText(string dirIn)
    {
        string myString, myString2;
        FileStream fs = new FileStream(dirIn, FileMode.Open);
        BinaryReader br = new BinaryReader(fs);
        byte[] bin = br.ReadBytes(Convert.ToInt32(fs.Length));
        //myString = Convert.ToBase64String(bin);
        myString =  Encoding.Default.GetString(bin);
        string m1 = Encoding.Default.GetString(bin);
        //string m1 =  Encoding.ASCII.GetString(bin);  
        //string m1 =  Encoding.BigEndianUnicode.GetString(bin);
        //string m1 = Encoding.UTF32.GetString(bin);
        //string m1 = Encoding.UTF7.GetString(bin);
        //string m1 = Encoding.UTF8.GetString(bin);
        //string m1 = Encoding.Unicode.GetString(bin);
        //string m1 = Encoding.Unicode.GetString(bin);

        Console.WriteLine(General.Asc(m1.Substring(0, 1)));
        Console.WriteLine(General.Asc(m1.Substring(1, 1)));
        Console.WriteLine(General.Asc(m1.Substring(2, 1)));
        br.Close();
        fs.Close();
        return myString;
}

一般类:

public static int Asc(string stringToEValuate)
{
    return (int)stringToEValuate[0];
}

输出窗口的结果:

1

10

8230 & lt;——失败!

VB6中的字符串长度为174848,与测试文件的大小相同。

在c#中默认和ASCII编码是相同的大小,而所有其他的有不同的大小,我不能使用它们,除非我改变了整个项目中的一切。

问题是,我找不到正确的编码,允许有一个字符串,asc函数返回相同的数字到VB6。

问题就在那里,如果字符串不相同,我必须更改很多行代码,因为整个程序是基于ASCii值和它在字符串中的位置。

也许将二进制文件加载到字符串或Asc函数中是错误的…

如果您想尝试示例文件,可以从这里下载:

http://www.snokie.org/testme.bin

Visual Basic到c#:以字符串形式加载二进制文件

8230 是否正确。它是Unicode码点的UTF-16代码单元(U+2026,只需要一个UTF-16代码单元)。你期望的是133。133作为一个字节是至少一个其他字符集中相同字符的编码:Windows-1252。

没有文本,只有编码文本。

当你读一个文本文件时,你必须知道用来写它的编码。一旦读取到。net String或Char,就得到了Unicode的UTF-16编码。因为Unicode是您将使用的任何字符集的超集,所以它不是不正确的。

如果您不想将字符作为字符进行比较,请将其作为二进制读取,以使其与文件保持相同的编码。然后可以比较字节序列。

问题是VB6代码,而不是像它应该使用Unicode字符代码,使用"默认的ANSI"字符集,这改变了含义从系统到系统和用户到用户。

问题是:"旧项目将二进制文件加载到字符串变量中"。是的,这是一个常见但不好的vb6实践。字符串数据类型用于文本。VB6中的字符串是UTF-16代码单元序列,就像。net(以及Java, JavaScript, HTML, XML,…)一样。

Get #ContIN, , FileBuffer将系统默认的ANSI代码页转换为UTF-16, Asc再将其转换回来。所以,你也需要在。net代码中这样做。

注意:就像在VB6中一样,编码。默认值是危险的,因为它可能因系统和用户而异。

参考Microsoft.VisualBasic.dll和

using static Microsoft.VisualBasic.Strings;
然后

var fileBuffer = File.ReadAllText(path, Encoding.Default); 
Debug.WriteLine(Asc(Mid(fileBuffer, 3, 1));

如果你不想把Microsoft.VisualBasic.dll带到c#项目中,你可以编写自己的版本

static class VB6StringReplacements
{
    static public Byte Asc(String source) => 
        Encoding.Default.GetBytes(source.Substring(0,1)).FirstOrDefault();
    static public String Mid(String source, Int32 offset, Int32 length) => 
        source.Substring(offset, length);
}

和,把using指令改成

using static VB6StringReplacements;