简体   繁体   English

将字节数组写入C#.NET中现有文件的中间位置

[英]Write byte array to middle of an existing file in C#.NET

Is it possible to write (Append - No Overwrite) to an existing binary file. 是否可以写入(附加 - 无覆盖)到现有的二进制文件。

I have to open a file in read write mode and then randomly write byte arrays to it at the position I specify in the file. 我必须在读写模式下打开一个文件,然后在文件中指定的位置随机写入字节数组。

I am from a Java Background and I use RandomAccessFile in Java to accomplish this, but C# left me nowhere without such inbuilt functions. 我来自Java背景,我在Java中使用RandomAccessFile来实现这一目标,但是C#在没有这种内置函数的情况下让我无处可去。

Any other workaround or solution would be highly appreciated. 任何其他解决方法或解决方案将受到高度赞赏。

-Adil. -Adil。

Is it possible to write (Append - No Overwrite) to an existing binary file. 是否可以写入(附加 - 无覆盖)到现有的二进制文件。

Appending would be adding data at the end. 追加将在最后添加数据。 That's fine. 没关系。 Just seek to the end of the stream after opening it in read/write mode. 在读/写模式下打开后,只需查找流的末尾即可。

It sounds like you want to insert data though, and that's not available. 听起来你想要插入数据,而这是不可用的。 It's not something file systems tend to support. 这不是文件系统倾向于支持的东西。 You'd need to copy the first part of the original file into a new file, write the new data, then copy the remainder of the original file. 您需要将原始文件的第一部分复制到新文件中,写入新数据,然后复制原始文件的其余部分。

Btw, RandomAccessFile doesn't support insertion either, so it's possible your Java code is broken too. 顺便说一句, RandomAccessFile也不支持插入,因此你的Java代码也可能被破坏。

EDIT: Okay, so if you want to just overwrite, that's easy: 编辑:好的,所以如果你想要覆盖,这很容易:

using (var stream = File.Open("file.dat", FileMode.Open))
{
    stream.Position = 100;
    // Assuming data is the data you want to write to the file
    stream.Write(data, 0, data.Length);
}

Here is an easy and quite fast solution to insert bytes in the middle of the file, just in case someone will search for inserting data and will find this question. 这是一个简单而快速的解决方案,可以在文件中间插入字节,以防有人搜索插入数据并找到这个问题。

public void ExpandFile(FileStream stream, long offset, int extraBytes)
{
  // http://stackoverflow.com/questions/3033771/file-io-with-streams-best-memory-buffer-size
  const int SIZE = 4096;
  var buffer = new byte[SIZE];
  var length = stream.Length;
  // Expand file
  stream.SetLength(length + extraBytes);
  var pos = length;
  int to_read;
  while (pos > offset)
  {
    to_read = pos - SIZE >= offset ? SIZE : (int)(pos - offset);
    pos -= to_read;
    stream.Position = pos;
    stream.Read(buffer, 0, to_read);
    stream.Position = pos + extraBytes;
    stream.Write(buffer, 0, to_read);
  }

Need to be checked, though... 需要检查,但......

There is no built-in function for doing that. 这样做没有内置功能。 If you seek the file to a particular position (offset) by setting the position field of the stream and then write your new byte array there, this will overwrite the existing bytes after that position. 如果通过设置流的位置字段来查找文件到特定位置(偏移量),然后在那里写入新的字节数组,这将覆盖该位置之后的现有字节。 You need to shift the existing bytes after the offset by the length of your intended byte array, and then write the byte array after the offset. 您需要将偏移量之后的现有字节移位到预期字节数组的长度,然后在偏移量之后写入字节数组。 Here is the code: 这是代码:

public static void InsertIntoFile(FileStream stream, long offset, byte[] extraBytes)
{
    if(offset < 0 || offset > stream.Length)
    {
        throw new ArgumentOutOfRangeException("Offset is out of range");
    }
    const int maxBufferSize = 1024 * 512;
    int bufferSize = maxBufferSize;
    long temp = stream.Length - offset;
    if(temp <= maxBufferSize)
    {
        bufferSize = (int) temp;
    }
    byte []buffer = new byte[bufferSize];
    long currentPositionToRead = fileStream.Length;
    int numberOfBytesToRead;
    while (true)
    {
        numberOfBytesToRead = bufferSize;
        temp = currentPositionToRead - offset;
        if(temp < bufferSize)
        {
            numberOfBytesToRead = (int) temp;
        }
        currentPositionToRead -= numberOfBytesToRead;
        stream.Position = currentPositionToRead; 
        stream.Read(buffer, 0, numberOfBytesToRead);
        stream.Position = currentPositionToRead + extraBytes.Length;
        stream.Write(buffer, 0, numberOfBytesToRead);
        if(temp <= bufferSize)
        {
            break; 
        }
    }
    stream.Position = offset;
    stream.Write(extraBytes, 0, extraBytes.Length);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM