Как перезаписывать файл c
Перейти к содержимому

Как перезаписывать файл c

Как перезаписывать файл c

Нужно открывать фаил в fstream, копировать его содержимое в строку string, работать с ней как с буфером, а при условии, что она изменена, перезаписывать файл её содержимым.

Т.е. так. Открываем:

 char *fn; string *buf; fstream *fS; fS->open(fname, ios_base::in | ios_base::out); if(!fS->is_open()) < fS->open(fname, ios_base::in | ios_base::out | ios_base::trunc); if(!fS->is_open()) return 1; > this->defSize(); char *tstr = new char[this->size]; this->buf = new string(); fS->read(tstr, this->size); this->buf->insert(0, tstr);

А затем надо сохранить содержимое buf в файл fS.
Сначала необходимо удалить предыдущее содержимое. Пробовал двумя способами.
Первый:

 this->fS->clear();
 this->fS->close(); this->fS->open(this->fn, ios_base::in | ios_base::out | ios_base::trunc);

После чего запись:

 fS->seekg(0, ios_base::beg); char *tstr = new char[this->size]; strcpy(tstr, buf->data()); this->fS->write(tstr, size);

В первом случае, если содержимое буфера уменьшилось, то на конце файла будут символы ‘H’.
Во втором — на выходе оказывается пустой файл.

Как правильно перезаписать файл fstream?

Re: Перезаписать fstream

От: LaptevVV
Дата: 12.09.08 11:09
Оценка:

Здравствуйте, NordWest, Вы писали:

NW>Нужно открывать фаил в fstream, копировать его содержимое в строку string, работать с ней как с буфером, а при условии, что она изменена, перезаписывать файл её содержимым.

NW>Т.е. так. Открываем:
NW>

NW> char *fn; NW> string *buf; NW> fstream *fS; fS->>open(fname, ios_base::in | ios_base::out); NW> if(!fS->is_open()) NW> < fS->>open(fname, ios_base::in | ios_base::out | ios_base::trunc); NW> if(!fS->is_open()) return 1; NW> > this->>defSize(); NW> char *tstr = new char[this->size]; this->>buf = new string(); fS->>read(tstr, this->size); this->>buf->insert(0, tstr); NW>

Вопросы:
1. Зачем тотальное использование указателей? Почему нельзя объявить просто указатель на поток, а не указатель на него? Аналогично: почему указатель на строку, а не просто строка?
2. Файл по умолчанию текстовый. Читаешь ты его методом read — в символьный массив. А внутри символы ‘\n’ отсутствуют? А ноль на конце символьного массива есть? При вставке проблем не будет?
NW>А затем надо сохранить содержимое buf в файл fS.
NW>Сначала необходимо удалить предыдущее содержимое. Пробовал двумя способами.
NW>Первый:
NW>

 this->>fS->clear(); NW>

Это неверно. Метод clear очищает флаги, а не файл.
NW>Второй:
NW>

 this->>fS->close(); this->>fS->open(this->fn, ios_base::in | ios_base::out | ios_base::trunc); NW>

Гораздо проще записать в новый временный файл, а потом просто переименовать.
Хочешь быть счастливым — будь им!
Без булдырабыз.
Re: Перезаписать fstream

От: codelord
Дата: 15.09.08 08:40
Оценка: 3 (1)

Здравствуйте, NordWest, Вы писали:

NW>Нужно открывать фаил в fstream, копировать его содержимое в строку string, работать с ней как с буфером, а при условии, что она изменена, перезаписывать файл её содержимым.

Может конечно очень многословно, но вот например так:

#include #include size_t get_file_size( const char * filename ) < FILE *fp = fopen( filename, "rb" ); if ( !fp ) < return 0; > size_t res; fpos_t position; if ( fgetpos(fp, &position) ) //запоминаем текущую позицию < fclose(fp); return -1; > //ошибка получения текущей позиции файла fseek(fp, 0, SEEK_END); //смещаемся в конец файла res = ftell(fp); //читаем положение указателя в конце файла if ( fsetpos(fp, &position) ) //кладем откуда взяли (позицию файла) < fclose(fp); return -1; > //ошибка установки позиции файла fclose(fp); return res; > void file_to_buf( char *buf, size_t _len, std::string filename ) < std::ifstream infile( filename.c_str(), std::ios::binary ); if ( !infile ) < return; > infile.read( buf, _len ); infile.close(); > int main() < std::string filename = "infile.txt"; size_t fsize = get_file_size( filename.c_str() ); char *buf = new char[ fsize ]; file_to_buf( buf, fsize, filename ); //Работаем с буфером buf[0] = 'A'; //можем копировать буфер чтобы сравнивать до и после изменений //и в случае если изменилось перезаписать файл std::ofstream outfile( filename.c_str() ); outfile.write( buf, fsize ); >

Re[2]: Перезаписать fstream

От: codelord
Дата: 15.09.08 08:43
Оценка:

Здравствуйте, codelord, Вы писали:

C>Может конечно очень многословно, но вот например так:
Ой там в последнюю строчку надо

 delete [] buf;

Re[2]: Перезаписать fstream

От: NordWest
Дата: 15.09.08 15:47
Оценка:

Здравствуйте, codelord, Вы писали:

C> std::ofstream outfile( filename.c_str() );
C> outfile.write( buf, fsize );

fsize может поменяться.

Re[3]: Перезаписать fstream

От: codelord
Дата: 16.09.08 05:14
Оценка:

Здравствуйте, NordWest, Вы писали:

NW>Здравствуйте, codelord, Вы писали:

C>> std::ofstream outfile( filename.c_str() );
C>> outfile.write( buf, fsize );

NW>fsize может поменяться.

Ну так это же пример, меняйте

Re[4]: Перезаписать fstream

От: NordWest
Дата: 16.09.08 06:11
Оценка:

Здравствуйте, codelord, Вы писали:

C>Здравствуйте, NordWest, Вы писали:

NW>>Здравствуйте, codelord, Вы писали:

C>>> std::ofstream outfile( filename.c_str() );
C>>> outfile.write( buf, fsize );

NW>>fsize может поменяться.

C>Ну так это же пример, меняйте

Re[5]: Перезаписать fstream

От: Аноним
Дата: 16.09.08 11:51
Оценка:

Как перезаписывать файл c

Доброе время суток. ПОомгите пожалуйста с такой проблемой:
Нужно перезаписать текстовый файл содежимым листбокса по нажатию на клавишу, тоесть все что есть в файле стереть а туда записать строки листбокса.
Проблема в том что это нада сделать в Visual Studio на C++. Я почитал мануалы и нашол пару исходников, но применить в Visual C++ их не как не могу. Вот один из них:

#include #include void main( void ) < FILE *file; char* file_name = "file.txt"; char load_string[50] = "none"; file = fopen( file_name, "w" ); fputs( "string", file ); fclose( file ); file = fopen( file_name, "r" ); if( file != 0 ) < fgets( load_string, 50 , file ); cout else < cout fclose(file); >

Не понятно что в include, пробовал в Visual C++ писать команды fputs и так далее — ошибки выбивает.

Помогите мне разобратса как работать с файлами в Visual C++, а именно как их перезаписывать содержимым листбокса.

Как перезаписывать файл c

Здравсвуйте.
Решая математическую задачу, я получил текстовый файл, состоящий из символов(а именно цифр), идущих подряд. Количество символов — от 1 до нескольких десятков тысяч.
Необходимо записать в этот же файл эти же символы, но в обратном порядке. Мой вопрос — как сделать это наиболее эффективным способом.
Заранее спасибо.

Re: Перезапись файла в обратном порядке

От: Аноним
Дата: 13.04.06 06:17
Оценка:

Здравствуйте, Stolb, Вы писали:

S>Здравсвуйте.
S>Решая математическую задачу, я получил текстовый файл, состоящий из символов(а именно цифр), идущих подряд. Количество символов — от 1 до нескольких десятков тысяч.
S>Необходимо записать в этот же файл эти же символы, но в обратном порядке. Мой вопрос — как сделать это наиболее эффективным способом.
S>Заранее спасибо.

Курим Страуструпа. Решение подобной задачи приводится в книге.

Re: Перезапись файла в обратном порядке

От: ansi
Дата: 13.04.06 06:25
Оценка:

Здравствуйте, Stolb, Вы писали:

S>Здравсвуйте.
S>Решая математическую задачу, я получил текстовый файл, состоящий из символов(а именно цифр), идущих подряд. Количество символов — от 1 до нескольких десятков тысяч.
S>Необходимо записать в этот же файл эти же символы, но в обратном порядке. Мой вопрос — как сделать это наиболее эффективным способом.
S>Заранее спасибо.

Несколько десятков килобайт — это мелочь. Можешь считать его целиком и потом reverse из stl. Сделал и забыл.

Re: Перезапись файла в обратном порядке

От: Abandoned
Дата: 13.04.06 07:32
Оценка:

>Решая математическую задачу, я получил текстовый файл, состоящий из символов(а именно цифр), идущих подряд. Количество символов — от 1 до нескольких десятков тысяч.
>Необходимо записать в этот же файл эти же символы, но в обратном порядке. Мой вопрос — как сделать это наиболее эффективным способом.
мапишь файл в память и strrev

Re: Перезапись файла в обратном порядке

От: FoolS.Top
Дата: 13.04.06 07:39
Оценка:

Здравствуйте, Stolb, Вы писали:

S>Здравсвуйте.
S>Решая математическую задачу, я получил текстовый файл, состоящий из символов(а именно цифр), идущих подряд. Количество символов — от 1 до нескольких десятков тысяч.
S>Необходимо записать в этот же файл эти же символы, но в обратном порядке. Мой вопрос — как сделать это наиболее эффективным способом.
S>Заранее спасибо.

У Рихтера есть пример, с использованием memory-mapped file.

Feierlich, misterioso
Re: Перезапись файла в обратном порядке

От: LaptevVV
Дата: 13.04.06 07:41
Оценка:

Здравствуйте, Stolb, Вы писали:

S>Здравсвуйте.
S>Решая математическую задачу, я получил текстовый файл, состоящий из символов(а именно цифр), идущих подряд. Количество символов — от 1 до нескольких десятков тысяч.
S>Необходимо записать в этот же файл эти же символы, но в обратном порядке. Мой вопрос — как сделать это наиболее эффективным способом.
S>Заранее спасибо.

void ReadFile(ifstream &f) < char s[100]; //--буфер для строки getline(f,s); //--читаем строку cout собственно здесь - в новый файл записываешь if (!f.eof()) //-пока не конец файла ReadFile(f); //--рекурсивный вызов > int main(void) < ifstream f("recurs.cpp"); ReadFile(f); f.close(); return 0; >

Это реверсирование текствого файла, разбитого на строки.
Если буфер — на 1 символ, то самое оно и есть. :

Хочешь быть счастливым — будь им!
Без булдырабыз.
Re[2]: Перезапись файла в обратном порядке

От: Аноним
Дата: 13.04.06 12:05
Оценка: +1

Здравствуйте, LaptevVV, Вы писали:

Ухх лучше не надо такого советовать, а то ведь иные так и станут делать!

Глубина рекурсии, равная длине файла — это жестоко! Тем более что и не нужна тут рекурсия, итеративно все реализуется очевидным образом.

И, кстати, в примере ошибка. В приведенном виде он дублирует исходный файл, а не реверсирует его. Чтобы исправить, надо переставить запись строки (cout после рекурсивного вызова.

Re[3]: Перезапись файла в обратном порядке

От: LaptevVV
Дата: 13.04.06 12:17
Оценка:

Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, LaptevVV, Вы писали:

А>[]

А>Ухх лучше не надо такого советовать, а то ведь иные так и станут делать!

А>Глубина рекурсии, равная длине файла — это жестоко! Тем более что и не нужна тут рекурсия, итеративно все реализуется очевидным образом.

А>И, кстати, в примере ошибка. В приведенном виде он дублирует исходный файл, а не реверсирует его. Чтобы исправить, надо переставить запись строки (cout после рекурсивного вызова.

Да, конечно.
Хотелось не совсем тривиальное привести что-нить.

Хочешь быть счастливым — будь им!
Без булдырабыз.
Re: Перезапись файла в обратном порядке

От: Аноним
Дата: 13.04.06 12:34
Оценка:

Здравствуйте, Stolb, Вы писали:

А вообще нужно ли переписывать, не проще ли его с конца считывать?

Re: Перезапись файла в обратном порядке

От: Ranger_XL
Дата: 14.04.06 11:12
Оценка:

Здравствуйте, Stolb, Вы писали:

S>Здравсвуйте.
S>Решая математическую задачу, я получил текстовый файл, состоящий из символов(а именно цифр), идущих подряд. Количество символов — от 1 до нескольких десятков тысяч.
S>Необходимо записать в этот же файл эти же символы, но в обратном порядке. Мой вопрос — как сделать это наиболее эффективным способом.

Что подразумевается под эффективностью? Скорость? Краткость кода?
Следующий фрагмент реверсирует файл в 1 Мб примерно за 1 секунду.
Использует binary режим, чтобы избежать проблем с ‘\n’

#include #include using namespace std; const int MAX_SIZE = 1000000; char buf[ MAX_SIZE + 1]; int main() < ifstream fin ("1.txt", ios::in | ios::binary); fin.read (buf, MAX_SIZE); int num_read = fin.gcount(); fin.close(); reverse (buf, buf + num_read); ofstream fout ("1.txt", ios::out | ios::binary); fout.write (buf, num_read); fout.close(); >

File. Write All Text Метод

Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.

Создает новый файл, записывает в него содержимое и затем закрывает файл. Если целевой файл уже существует, он усекается и перезаписывается.

Перегрузки

Создает новый файл, записывает в него указанную строку и затем закрывает файл. Если целевой файл уже существует, он усекается и перезаписывается.

Создает новый файл, записывает указанную строку в этот файл, используя заданную кодировку, и затем закрывает файл. Если целевой файл уже существует, он усекается и перезаписывается.

WriteAllText(String, String)

Создает новый файл, записывает в него указанную строку и затем закрывает файл. Если целевой файл уже существует, он усекается и перезаписывается.

public: static void WriteAllText(System::String ^ path, System::String ^ contents);
public static void WriteAllText (string path, string contents);
public static void WriteAllText (string path, string? contents);
static member WriteAllText : string * string -> unit
Public Shared Sub WriteAllText (path As String, contents As String)
Параметры

Файл, в который осуществляется запись.

Строка, которую нужно записать в файл.

Исключения

платформа .NET Framework и .NET Core версий старше 2.1: path строка нулевой длины, содержит только пробелы или содержит один или несколько недопустимых символов. Вы можете запросить недопустимые символы с помощью метода GetInvalidPathChars().

path имеет значение null .

Указанный путь, имя файла или оба значения превышают максимальную длину, заданную в системе.

Указан недопустимый путь (например, он ведет на несопоставленный диск).

При открытии файла произошла ошибка ввода-вывода.

Параметр path указывает файл, доступный только для чтения.

path указывает файл, который скрыт.

Эта операция не поддерживается на текущей платформе.

Параметр path определяет каталог.

У вызывающего объекта отсутствует необходимое разрешение.

Параметр path задан в недопустимом формате.

У вызывающего объекта отсутствует необходимое разрешение.

Примеры

В следующем примере кода показано использование метода для WriteAllText записи текста в файл. В этом примере создается файл, если он еще не существует, и в него добавляется текст.

using System; using System.IO; using System.Text; class Test < public static void Main() < string path = @"c:\temp\MyTest.txt"; // This text is added only once to the file. if (!File.Exists(path)) < // Create a file to write to. string createText = "Hello and Welcome" + Environment.NewLine; File.WriteAllText(path, createText); >// This text is always added, making the file longer over time // if it is not deleted. string appendText = "This is extra text" + Environment.NewLine; File.AppendAllText(path, appendText); // Open the file to read from. string readText = File.ReadAllText(path); Console.WriteLine(readText); > > 
open System open System.IO let path = @"c:\temp\MyTest.txt" // This text is added only once to the file. if File.Exists path |> not then // Create a file to write to. let createText = "Hello and Welcome" + Environment.NewLine File.WriteAllText(path, createText) // This text is always added, making the file longer over time // if it is not deleted. let appendText = "This is extra text" + Environment.NewLine File.AppendAllText(path, appendText) // Open the file to read from. let readText = File.ReadAllText path printfn $"" 
Imports System.IO Imports System.Text Public Class Test Public Shared Sub Main() Dim path As String = "c:\temp\MyTest.txt" ' This text is added only once to the file. If File.Exists(path) = False Then ' Create a file to write to. Dim createText As String = "Hello and Welcome" + Environment.NewLine File.WriteAllText(path, createText) End If ' This text is always added, making the file longer over time ' if it is not deleted. Dim appendText As String = "This is extra text" + Environment.NewLine File.AppendAllText(path, appendText) ' Open the file to read from. Dim readText As String = File.ReadAllText(path) Console.WriteLine(readText) End Sub End Class 

Комментарии

Этот метод использует кодировку UTF-8 без Byte-Order Mark (BOM), поэтому при использовании GetPreamble метода возвращается пустой массив байтов. Если необходимо включить идентификатор UTF-8, например метку порядка байтов, в начале файла, используйте перегрузку WriteAllText(String, String, Encoding) метода с UTF8 кодировкой.

При использовании строки и пути к файлу этот метод открывает указанный файл, записывает строку в файл, а затем закрывает файл.

Применяется к

WriteAllText(String, String, Encoding)

Создает новый файл, записывает указанную строку в этот файл, используя заданную кодировку, и затем закрывает файл. Если целевой файл уже существует, он усекается и перезаписывается.

public: static void WriteAllText(System::String ^ path, System::String ^ contents, System::Text::Encoding ^ encoding);
public static void WriteAllText (string path, string contents, System.Text.Encoding encoding);
public static void WriteAllText (string path, string? contents, System.Text.Encoding encoding);
static member WriteAllText : string * string * System.Text.Encoding -> unit
Public Shared Sub WriteAllText (path As String, contents As String, encoding As Encoding)
Параметры

Файл, в который осуществляется запись.

Строка, которую нужно записать в файл.

Кодировка, которую необходимо применить к строке.

Исключения

платформа .NET Framework и .NET Core версий старше 2.1: path строка нулевой длины, содержит только пробелы или содержит один или несколько недопустимых символов. Вы можете запросить недопустимые символы с помощью метода GetInvalidPathChars().

path имеет значение null .

Указанный путь, имя файла или оба значения превышают максимальную длину, заданную в системе.

Указан недопустимый путь (например, он ведет на несопоставленный диск).

При открытии файла произошла ошибка ввода-вывода.

Параметр path указывает файл, доступный только для чтения.

path указывает файл, который скрыт.

Эта операция не поддерживается на текущей платформе.

Параметр path определяет каталог.

У вызывающего объекта отсутствует необходимое разрешение.

Параметр path задан в недопустимом формате.

У вызывающего объекта отсутствует необходимое разрешение.

Примеры

В следующем примере кода показано использование метода для WriteAllText записи текста в файл. В этом примере создается файл, если он еще не существует, и в него добавляется текст.

using System; using System.IO; using System.Text; class Test < public static void Main() < string path = @"c:\temp\MyTest.txt"; // This text is added only once to the file. if (!File.Exists(path)) < // Create a file to write to. string createText = "Hello and Welcome" + Environment.NewLine; File.WriteAllText(path, createText, Encoding.UTF8); >// This text is always added, making the file longer over time // if it is not deleted. string appendText = "This is extra text" + Environment.NewLine; File.AppendAllText(path, appendText, Encoding.UTF8); // Open the file to read from. string readText = File.ReadAllText(path); Console.WriteLine(readText); > > 
open System open System.IO open System.Text let path = @"c:\temp\MyTest.txt" // This text is added only once to the file. if File.Exists path |> not then // Create a file to write to. let createText = "Hello and Welcome" + Environment.NewLine File.WriteAllText(path, createText, Encoding.UTF8) // This text is always added, making the file longer over time // if it is not deleted. let appendText = "This is extra text" + Environment.NewLine File.AppendAllText(path, appendText, Encoding.UTF8) // Open the file to read from. let readText = File.ReadAllText path printfn $"" 
Imports System.IO Imports System.Text Public Class Test Public Shared Sub Main() Dim path As String = "c:\temp\MyTest.txt" Dim sw As StreamWriter ' This text is added only once to the file. If File.Exists(path) = False Then ' Create a file to write to. Dim createText As String = "Hello and Welcome" + Environment.NewLine File.WriteAllText(path, createText, Encoding.UTF8) End If ' This text is always added, making the file longer over time ' if it is not deleted. Dim appendText As String = "This is extra text" + Environment.NewLine File.AppendAllText(path, appendText, Encoding.UTF8) ' Open the file to read from. Dim readText As String = File.ReadAllText(path) Console.WriteLine(readText) End Sub End Class 

Комментарии

При использовании строки и пути к файлу этот метод открывает указанный файл, записывает строку в файл с использованием указанной кодировки, а затем закрывает файл. Этот метод гарантированно закрывает дескриптор файла, даже если возникают исключения.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *