Neel Basu
Neel Basu

Reputation: 12904

overwrite in the middle of a File

The Problem is I am in the Middle of a File with fseek Next exists some Bytes of Length m that I want to replace with Bytes of length n. simple write will keep m-n bytes still there. If m > n and if m < n some Bytes (n-m) that I am not willing to change will be overwritten.

I just want to replace a known startPos to endPos Byte Stream with variable length Bytes. What is the Best Solution.

-- EDIT -- Though It can be done by taking a Backup. do there exists any direct solution ? This is too Messy ? and Kind of Poor Coding.

o = fopen(original, 'r')
b = fopen(backup, 'w')
while(fpos(o) <= startPos){
    buffer += fgetc(o)
}
fwrite(b, buffer)
fwrite(b, replaceMentBytes)
buffer = ""
fseek(o, endPos)
while(!feof(o)){
    buffer += fgetc(o)
}
fwrite(b, buffer)

//now Copy backup to original

Upvotes: 5

Views: 876

Answers (2)

RageD
RageD

Reputation: 6823

Using the fstream library, here is a simple implementation of what the others might be saying

/**
 * Overwrite a file while replacing certain positions
 */

#include <iostream>
#include <fstream>

using namespace std;

int readFile(char* filename,int& len,char*& result)
{
    ifstream in(filename); // Open the file
    if(!in.is_open())
        return 1;

    // Get file length
    in.seekg(0,ios::end);
    len = (int)in.tellg();
    in.seekg(0,ios::beg);

    // Initialize result
    result = new char[len+1];

    // Read the file and return its value
    in.read(result,len);

    // Close the file
    in.close();

    return 0;
}

void writeFile(char* filename,char* data,int from,int to,int origdata,int trunc)
{
    ofstream out;
    (trunc == 1) ? out.open(filename,ios::trunc) : out.open(filename,ios::app); // Simple ternary statement to figure out what we need to do

    // Find position if we're not starting from the beginning
    if(trunc == 1)
        out.seekp(from);
     else // Otherwise send us to the beginning
        out.seekp(0,ios::beg);

    if(origdata == 1) // If we need to start in the middle of the data, let's do so
        for(int i=0;i<(to-from);++i)
            data[i] = data[from+i]; // Reverse copy

    out.write(data,(to-from));

    out.close();
}

int main()
{
    char* read;
    int len = 0;
    if(readFile("something.txt",len,read) != 0)
    {
        cout<< "An error occurred!" << endl;
        return 0;
    }

    // Example to make this work
    cout<< "Writing new file...\r\n";
    writeFile("something.txt",read,0,20,1,1); // Initial write
    writeFile("something.txt","\r\nsome other mumbo jumbo",21,45,0,0);
    writeFile("something.txt",read,46,100,1,0); // Replace the rest of the file back

    cout<< "Done!\r\n";
    cin.get(); // Pause
    delete [] read;
    return 0;
}

You would could do all your seeking in the readFile function OR simply in the char array (in this case read). From there, you can store the positions and use the writeFile() function appropriately.

Good luck!
Dennis M.

Upvotes: 0

Thanatos
Thanatos

Reputation: 44256

The most robust solution is to re-write the whole file, from scratch. Most operating systems will only let you overwrite bytes, not insert or remove them, from a file, so to accomplish that, you have to essentially copy the file, replacing the target bytes during the copy.

Upvotes: 5

Related Questions