C# 读取、修改然后将二进制数据写入文件。最佳会议?

C# 读取、修改然后将二进制数据写入文件。最佳会议?,c#,binary,bytearray,C#,Binary,Bytearray,一般来说,我对编程还不熟悉(我对编程概念的理解仍在增长)。所以这个问题是关于学习的,所以请提供足够的信息让我学习,但不要太多,我不能,谢谢。 (我还想了解如何使代码在项目中可重用。) 我正在从事的项目的目标包括: 读取二进制文件 我知道需要读取偏移量才能从该文件中找到特定的数据块 第一个偏移量是前4个字节(块末尾的偏移量) 第二个偏移量是距离文件末尾的16字节。我读取了4个字节(以十六进制表示块的大小) 第三个偏移量是前一个字节之后的4个字节,读取4个字节(十六进制中块开始的偏移量) 通过搜索A

一般来说,我对编程还不熟悉(我对编程概念的理解仍在增长)。所以这个问题是关于学习的,所以请提供足够的信息让我学习,但不要太多,我不能,谢谢。 (我还想了解如何使代码在项目中可重用。)

我正在从事的项目的目标包括:

  • 读取二进制文件

  • 我知道需要读取偏移量才能从该文件中找到特定的数据块

  • 第一个偏移量是前4个字节(块末尾的偏移量)

  • 第二个偏移量是距离文件末尾的16字节。我读取了4个字节(以十六进制表示块的大小)

  • 第三个偏移量是前一个字节之后的4个字节,读取4个字节(十六进制中块开始的偏移量)

  • 通过搜索ASCII文本和偏移量,找到块中要修改的部分

  • 现在我有了块的开始偏移量、结束偏移量和大小。 这应该允许我将文件中的字节读入字节数组,并提前知道数组的大小

    (问题:1.知道大小重要吗?除了验证之外。2.将文件的一部分读入字节数组以便更改字节并覆盖该部分文件是最好的方法吗?)

    到目前为止,我已经在MemoryStream上使用BinaryReader从文件中读取了偏移量。然后找到所需的数据块并将其读入字节数组

    我被困在几个方面:

    • 二进制读/写的最佳实践是什么
    • 读取数据的最佳存储约定是什么
    • 当我需要修改字节时,我该怎么做
    • 我应该使用文件流吗

    因为您既想读也想写,所以直接使用FileStream类(使用FileMode.Open和FileAccess.ReadWrite)是有意义的。请参阅,以获取一个好的总体示例

  • 您确实需要知道要从流中读取的字节数。看
  • 从根本上说,如果要使用并在以后修改字节的内容,您必须在某个时候将字节读入内存。因此,您必须创建内存中的副本(如果您一次读取一个可变长度的块,那么使用Read方法是正确的方法)
  • 至于最佳实践,请在完成后始终处理流;e、 g:

    using (var stream = File.Open(FILE_NAME, FileMode.Open, FileAccess.ReadWrite))
    {
        //Do work with the FileStream here.
    }
    
    如果你要做大量的工作,你应该异步地做。(如果是这样,请告诉我们。)

    当然,在使用这些方法之前,还要检查FileStream.Read文档和

    读取字节的最佳方法是预先分配一个内存中的字节数组,该数组具有要读取的长度,然后读取这些字节。以下内容将读取您感兴趣的字节块,让您处理它,然后替换原始内容(假设块的长度没有更改):

    EDIT:根据变量范围上的注释,我添加了一个helper方法来处理区块。


    谢谢你的回复。最多我猜要修改的块的最大大小是2KB。我看不出它比那还要大。您认为我仍然需要异步执行此操作吗?我还希望能够以未知偏移量处理数据块中的数据,找到这些数据的方法是在该数据块中定位ASCII字。我会循环执行搜索和替换操作吗?这将如何影响块变量中的内存数据?(Scope现在让我有点困惑,我还在读它。)只有当应用程序性能太低时才需要异步(要么UI被不可接受地阻塞,要么你无法承受机器上的负载分布不均匀——比如说,因为你正在处理大量数据,可能以每分钟兆字节为单位)。一个2KB的操作是非常简单的-我向您保证,我的浏览器在呈现此评论框时使用的远远不止这些。:)至于在块中定位偏移量,可以从执行嵌套循环-O(nm)性能开始,n是字符串长度,m是搜索模式长度。有很多方法可以优化此功能-最后,请检查如何影响块中的内存数据:一旦调用FileStream.Read(),数组中就有了一个可变副本。您可以对内存中的数据执行任何操作,然后在最后覆盖源文件,如我在第二个代码段中所示。就作用域而言,请注意变量“chunk”仅在using{}块的作用域中,因此一旦该块退出,就不能修改它。(有道理,因为您已经关闭了文件。)您可以在//TODO:行中调用helper函数。将“chunk”作为“ref byte[]”传递给它。执行搜索的最佳方法几乎肯定是使用正则表达式(.NET BCL为此提供了Regex类)。让我看看是否可以找到一个使用带有字节数组的正则表达式的示例。。。
    using (var stream = File.Open(FILE_NAME, FileMode.Open, FileAccess.ReadWrite))
    {
        var chunk = new byte[numOfBytesInChunk];
        var offsetOfChunkInFile = stream.Position; // It sounds like you've already calculated this.
        stream.Read(chunk, 0, numOfBytesInChunk);
    
        DoWorkOnChunk(ref chunk);        
    
        stream.Seek(offsetOfChunkInFile, SeekOrigin.Begin);
        stream.Write(chunk, 0, numOfBytesInChunk);
    }
    
    private void DoWorkOnChunk(ref byte[] chunk)
    {
        //TODO: Any mutation done here to the data in 'chunk' will be written out to the stream.
    }