我有一个应用程序,需要读取和写入兼容的VB6二进制文件。我了解了Microsoft.VisualBasic.FileSystem
类,我正试图写出一个结构到文件。
FileSystem.FileOpen(file, "test.bin", Microsoft.VisualBasic.OpenMode.Binary);
FileSystem.FilePut(file, patch.intTest);
FileSystem.FilePut(file, patch.dateTest);
FileSystem.FilePut(file, patch.stringTest, StringIsFixedLength: false);
FileSystem.FilePut(file, patch.boolTest);
除了字符串之外,如果我将每个条目单独放置,则所有内容都可以正确写入。当VB6应用程序写入字符串时,它在前面加上两个长度字节,我的代码没有。
在MSDN中,它说二进制模式删除长度字节,除非它在一个结构中。将StringIsFixedLength设置为true应该可以做到这一点,但似乎二进制模式优于该设置。
我尝试使用FilePutObject
并尝试传递一个结构体或类(这是msdn说你需要做什么来获得字节显示)它抛出异常
System.ArgumentException occurred
Message=File I/O with type 'PatchFileStructure' is not valid.
Source=Microsoft.VisualBasic
StackTrace:
at Microsoft.VisualBasic.FileSystem.FilePutObject(Int32 FileNumber, Object Value, Int64 RecordNumber)
at SandboxConsole.Sandbox.Main(String[] args) in E:CodeSandbox ConsoleSandboxConsoleProgram.cs:line 41
InnerException:
完整代码
using System;
using Microsoft.VisualBasic;
namespace SandboxConsole
{
static class Sandbox
{
public struct PatchFileStructure
{
public Int32 intTest { get; set; }
public DateTime dateTest { get; set; }
public string stringTest { get; set; }
public bool boolTest { get; set; }
}
public static void Main(params string[] args)
{
var patch = new PatchFileStructure()
{
intTest = 5,
dateTest = new DateTime(1999, 1, 1, 1, 1, 1),
stringTest = "Test Name",
boolTest = true,
};
int file = FileSystem.FreeFile();
FileSystem.Kill("test.bin");
FileSystem.FileOpen(file, "test.bin", Microsoft.VisualBasic.OpenMode.Binary);
FileSystem.FilePutObject(file, patch);
//FileSystem.FilePut(file, patch.intTest);
//FileSystem.FilePut(file, patch.dateTest);
//FileSystem.FilePut(file, patch.stringTest, StringIsFixedLength: false);
//FileSystem.FilePut(file, patch.boolTest);
FileSystem.FileClose(file);
}
}
}
这是我比较的两个文件。c#版本中添加了空格来说明问题。
vb6 - 05 00 00 00 24 F6 1D 5B 21 A8 E1 40 09 00 54 65 73 74 20 4E 61 6D 65 FF FF
C# - 05 00 00 00 24 F6 1D 5B 21 A8 E1 40 54 65 73 74 20 4E 61 6D 65 FF FF
如果我尝试从c#中读取vb6文件,除了返回null的字符串外,一切都很好。
FilePutObject
似乎要冗长得多,并且写出了比需要更多的元数据,主要用于变体。
你有没有试过:
FileSystem.FilePut(file, patch);
使用ValueType重载
可以在字符串之前显式地写出长度:
FileSystem.FilePut(file, patch.stringTest.Lenght.ToInt16);
FileSystem.FilePut(file, patch.stringTest, StringIsFixedLength: false);
更改为:
FileSystem.FilePut(file, patch.stringTest, StringIsFixedLength: false);
系统不写长度前缀,因为你告诉它字符串是固定长度