当从c#向二进制文件写入字符串时,FilePut不会在前面加上两个长度字节.FilePutObject在类/结构上抛出异

本文关键字:两个 字节 FilePutObject 结构上 在类 字符串 二进制文件 在前面 FilePut 当从 | 更新日期: 2023-09-27 18:14:14

我有一个应用程序,需要读取和写入兼容的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:'Code'Sandbox Console'SandboxConsole'Program.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的字符串外,一切都很好。

当从c#向二进制文件写入字符串时,FilePut不会在前面加上两个长度字节.FilePutObject在类/结构上抛出异

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

系统不写长度前缀,因为你告诉它字符串是固定长度