【问题标题】:How to write file header using FileStream in C#如何在 C# 中使用 FileStream 写入文件头
【发布时间】:2013-09-03 06:40:55
【问题描述】:

我正在创建自己的视频文件格式,并想写出文件头和帧头。

目前我只有这样定义的占位符:

byte[] fileHeader = new byte[FILE_HEADER_SIZE * sizeof(int)];
byte[] frameHeader = new byte[FRAME_HEADER_SIZE * sizeof(int)];

我使用以下文件头将它们写出来:

fsVideoWriter.Write(fileHeader, 0, FILE_HEADER_SIZE);

这对于帧头:

fsVideoWriter.Write(frameHeader, 0, FRAME_HEADER_SIZE);

现在我实际上需要正确使用这些标题,我不确定这是否是编写它们的最方便的方法,因为我不确定在我的各个字段中是否易于阅读需要与标题分开变量。

我想过做如下的事情:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct FileHeader
{
    public int x;
    public int y;
    public int z;
            // etc. etc.
}

我想以这样一种方式定义它,以便我可以随着文件格式的发展而轻松升级(即包括版本号)。这是定义文件/帧头的推荐方法吗?如果是这样,我应该如何使用 .NET FileStream 类读/写它?如果这不是推荐的方法,请提出正确的方法,因为也许有人已经创建了一个通用的视频文件相关类来处理这种事情?

【问题讨论】:

  • 我想我可以使用 Marshal.PtrToStructure() 和 Marshal.StructureToPtr(),但我想避免使用非托管代码。

标签: c# .net header filestream file-format


【解决方案1】:

我选择了以下解决方案:

写出文件头

public static bool WriteFileHeader(FileStream fileStream, FileHeader fileHeader)
{
    try
    {
        byte[] buffer = new byte[FILE_HEADER_SIZE];

        GCHandle gch = GCHandle.Alloc(buffer, GCHandleType.Pinned);
        Marshal.StructureToPtr(fileHeader, gch.AddrOfPinnedObject(), false);
        gch.Free();

        fileStream.Seek(0, SeekOrigin.Begin);                
        fileStream.Write(buffer, 0, FILE_HEADER_SIZE);

        return true;
    }
    catch (Exception ex)
    {
        throw ex;
    }
}

读入文件头

public static bool ReadFileHeader(FileStream fileStream, out FileHeader fileHeader)
{
    try
    {
        fileHeader = new FileHeader();

        byte[] buffer = new byte[FILE_HEADER_SIZE];

        fileStream.Seek(0, SeekOrigin.Begin);
        fileStream.Read(buffer, 0, FILE_HEADER_SIZE);

        GCHandle gch = GCHandle.Alloc(buffer, GCHandleType.Pinned);
        Marshal.PtrToStructure(gch.AddrOfPinnedObject(), fileHeader);

        gch.Free();

        // test for valid data
        boolean isSuccessful = IsValidHeader(fileHeader);

        return isSuccessful;

    }
    catch (Exception ex)
    {
        throw ex;
    }

}

我也对帧头使用了类似的方法。这个想法基本上是利用字节缓冲区和元帅。

【讨论】:

  • 什么是 FileHeader 输入类型?你是单独定义了一个类还是系统库?谢谢!
  • 我相信是我自己定义的。
【解决方案2】:

您可能想尝试BinaryFormatter 类。但它或多或少是一个黑匣子。如果您需要精确控制文件格式,您可以编写自己的 Formatter 并使用它来序列化您的 header 对象。

【讨论】:

  • 我只是想确保我的标头输出并以正确的顺序返回。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-02
  • 2012-09-24
  • 2020-11-15
  • 1970-01-01
  • 2012-07-23
相关资源
最近更新 更多