перезаписать в середине файла - PullRequest
5 голосов
/ 21 декабря 2010

Проблема в том, что я нахожусь в середине файла с fseek Далее существует несколько байтов длины m, которые я хочу заменить байтами длины n.простой write будет держать m-n байтов все еще там.Если m > n и m < n, то некоторые байты (n-m), которые я не хочу менять, будут перезаписаны.

Я просто хочу заменить известный startPos to endPos поток байтов байтами переменной длины.Какое лучшее решение.

- РЕДАКТИРОВАТЬ - Хотя это можно сделать, сделав резервную копию.существует ли какое-либо прямое решение?Это слишком грязно?и вид плохого кодирования.

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)

// теперь Скопируйте резервную копию в оригинал

Ответы [ 2 ]

5 голосов
/ 21 декабря 2010

Самое надежное решение - переписать весь файл с нуля. Большинство операционных систем позволяют вам перезаписывать байты, а не вставлять или удалять их из файла, поэтому для этого вам необходимо скопировать файл, заменяя целевые байты во время копирования.

0 голосов
/ 21 декабря 2010

Используя библиотеку fstream, вот простая реализация того, что говорят другие

/**
 * 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;
}

Вы могли бы выполнять все свои поиски в функции readFile ИЛИ просто в массиве char (в данном случае read) Оттуда вы можете сохранить позиции и использовать функцию writeFile () соответствующим образом.

Удачи!
Деннис М.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...