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 108230 & lt;——失败!
VB6中的字符串长度为174848,与测试文件的大小相同。
在c#中默认和ASCII编码是相同的大小,而所有其他的有不同的大小,我不能使用它们,除非我改变了整个项目中的一切。
问题是,我找不到正确的编码,允许有一个字符串,asc函数返回相同的数字到VB6。
问题就在那里,如果字符串不相同,我必须更改很多行代码,因为整个程序是基于ASCii值和它在字符串中的位置。
也许将二进制文件加载到字符串或Asc函数中是错误的…
如果您想尝试示例文件,可以从这里下载:
http://www.snokie.org/testme.bin
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;