简体   繁体   中英

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.

Any other workaround or solution would be highly appreciated.

-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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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