Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 761
user1244484 Avatar asked Dec 27 '22 05:12

user1244484


2 Answers

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);
}
like image 197
Jon Skeet Avatar answered Jan 05 '23 17:01

Jon Skeet


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);
}
like image 38
Diamond Avatar answered Jan 05 '23 15:01

Diamond