Qfile очистить содержимое файла
I am implementing a method in my class, which will write out data from a TableView Object to a CSV file. However when the program runs, the program writes the data to the file on a USB drive at a very slow rate(3 or 4 seconds), but works fine with the system's internal drive. Is this because i have not used flush() or close(), after writing the file ??
Here is my code
This was my code earlier, and now i plan to close the file stream, for a graceful exit. The Qt API for QFile::close() says
Calls QFile::flush() and closes the file. Errors from flush are ignored.
So should i just call close(), or is it better to call flush(), log any errors and then call close() ?
Is there any other modification, that i have to make, to improve the write operation ?
That sounds like horrible design, ignoring errors. If that's really what happens, then yes, you have to call flush first, and process the errors. (But in any reasonable design, close should propagate any errors from flush up.)
Throughout the codebase, Qt file stream classes are used, so just have to do the same to maintain project integrity.
If you're not working alone, yes. You have to maintain some sort of coherence in the project. (Although in the case of IO, it's not rare to use several different solutions, depending. The requirements for transaction processing and logging are radically different, and an io subsystem which meets one will rarely meet the other. But from the little you're showing here, I don't think that there's any justification for breaking with existing practice in the application.)
Reimplemented Public Functions
virtual QString | fileName() const override |
virtual bool | open(QIODevice::OpenMode mode) override |
virtual QFileDevice::Permissions | permissions() const override |
virtual bool | resize(qint64 sz) override |
virtual bool | setPermissions(QFileDevice::Permissions permissions) override |
virtual qint64 | size() const override |
Detailed Description
QFile is an I/O device for reading and writing text and binary files and resources. A QFile may be used by itself or, more conveniently, with a QTextStream or QDataStream.
The file name is usually passed in the constructor, but it can be set at any time using setFileName(). QFile expects the file separator to be '/' regardless of operating system. The use of other separators (e.g., '\') is not supported.
You can check for a file's existence using exists(), and remove a file using remove(). (More advanced file system related operations are provided by QFileInfo and QDir.)
The file is opened with open(), closed with close(), and flushed with flush(). Data is usually read and written using QDataStream or QTextStream, but you can also call the QIODevice-inherited functions read(), readLine(), readAll(), write(). QFile also inherits getChar(), putChar(), and ungetChar(), which work one character at a time.
The size of the file is returned by size(). You can get the current file position using pos(), or move to a new file position using seek(). If you've reached the end of the file, atEnd() returns true .
Platform Specific Issues
File permissions are handled differently on Unix-like systems and Windows. In a non writable directory on Unix-like systems, files cannot be created. This is not always the case on Windows, where, for instance, the 'My Documents' directory usually is not writable, but it is still possible to create files in it.
Qt's understanding of file permissions is limited, which affects especially the QFile::setPermissions() function. On Windows, Qt will set only the legacy read-only flag, and that only when none of the Write* flags are passed. Qt does not manipulate access control lists (ACLs), which makes this function mostly useless for NTFS volumes. It may still be of use for USB sticks that use VFAT file systems. POSIX ACLs are not manipulated, either.
Для вас это может быть интересно:
Public Types
Using Streams to Read Files
The next example uses QTextStream to read a text file line by line:
QDataStream is similar, in that you can use operator>() to read it back. See the class documentation for details.
On Unix, there are some special system files (e.g. in /proc ) for which size() will always return 0, yet you may still be able to read more data from such a file; the data is generated in direct response to you calling read(). In this case, however, you cannot use atEnd() to determine if there is more data to read (since atEnd() will return true for a file that claims to have size 0). Instead, you should either call readAll(), or call read() or readLine() repeatedly until no more data can be read. The next example uses QTextStream to read /proc/modules line by line:
Signals
Unlike other QIODevice implementations, such as QTcpSocket, QFile does not emit the aboutToClose(), bytesWritten(), or readyRead() signals. This implementation detail means that QFile is not suitable for reading and writing certain types of files, such as device files on Unix platforms.
Добавить комментарий Отменить ответ
Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.
Static Public Members
bool | copy(const QString &fileName, const QString &newName) |
QString | decodeName(const QByteArray &localFileName) |
QString | decodeName(const char *localFileName) |
QByteArray | encodeName(const QString &fileName) |
bool | exists(const QString &fileName) |
bool | link(const QString &fileName, const QString &linkName) |
bool | moveToTrash(const QString &fileName, QString *pathInTrash = nullptr) |
QFileDevice::Permissions | permissions(const QString &fileName) |
bool | remove(const QString &fileName) |
bool | rename(const QString &oldName, const QString &newName) |
bool | resize(const QString &fileName, qint64 sz) |
bool | setPermissions(const QString &fileName, QFileDevice::Permissions permissions) |
QString | symLinkTarget(const QString &fileName) |
typedef QFile:: DecoderFn
Beginner
Join Date Sep 2008 Location Slovakia, Nitra Posts 15 Thanks 9 Qt products Platforms
Reading Files Directly
The following example reads a text file line by line:
The QIODevice::Text flag passed to open() tells Qt to convert Windows-style line terminators ("\r\n") into C++-style terminators ("\n"). By default, QFile assumes binary, i.e. it doesn't perform any conversion on the bytes stored in the file.
QFile и файлы. Чтение и запись строк в файл. : 4 комментария
Помогло разобраться с классом, хорошо изложено! 🙂
Не понимаю, где будут сохраняться эти файлы
если просто имя — в директорию с проектом
если полный путь — в директорию указанную в пути
Public Functions
QFile(const QString &name, QObject *parent) | |
QFile(QObject *parent) | |
QFile(const QString &name) | |
QFile() | |
virtual | ~QFile() |
bool | copy(const QString &newName) |
bool | exists() const |
bool | link(const QString &linkName) |
bool | moveToTrash() |
bool | open(FILE *fh, QIODevice::OpenMode mode, QFileDevice::FileHandleFlags handleFlags = DontCloseHandle) |
bool | open(int fd, QIODevice::OpenMode mode, QFileDevice::FileHandleFlags handleFlags = DontCloseHandle) |
bool | remove() |
bool | rename(const QString &newName) |
void | setFileName(const QString &name) |
QString | symLinkTarget() const |
how can i clear a file?
Hi,
How can I clear content of a file?!
For example a write to file.dat string ("how are you doing?"), after that i seek it in to begining, then i write some shorter string ("hello"), after that i get in file.dat something like: "hellore you doing?"
I checked the documentation of qt, but i don't understand very well to english, also tried a many version of potential code, but nothing worked for me
- from the (quint64) 10 to (quint64) 220
- from (quint64) 10 to end of line?
Sorry for that stupid questions, but i played with it a long time without any succes. - also sorry for my english!
Novice
Join Date Dec 2008 Location Czech Posts 44 Thanks 2 Thanked 8 Times in 8 Posts Qt products Platforms
Hi,
I guess u use something like this:
QFile file("file.dat");
file.open(QIODevice::ReadOnly);
QDataStream in(&file);
if you want to clear content of file.dat u should creat QDataStream object with open mode like this
QDataStream in(&file, QIODevice::Truncate);
This should help
Member Type Documentation
2 Answers 2
The flush() vs. close() is a red herring, it doesn't impact your performance at all.
Destruction of a QTextStream forces a flush of the file. Flushing the file is slow. You're destroying your text stream every time you iterate through the loop! Create the stream outside of the loop!
Here's the source, from Qt 5.1.1:
On Qt 5.1 or newer, you should be using QSaveFile if you want to ensure that the disk buffers are flushed once the file is closed. Only this gives you assurance that once you think you're done saving, the data is in fact on the disk.
QTextStream has its own buffers. So, if you want to catch errors while flushing, you need to use the flush() method on the stream itself, not on the QFile .
It's a very bad idea to do any file access from the GUI thread. Any time anything blocks, your UI thread blocks as well.
Now the question is: how do you make your model safe to access from another thread? If you use a custom model, you probably only need to switch the model into a read-only mode for the duration of writing the file. The read-only mode would be a custom property of the model, such that all setData calls would fail. You'd of course need to indicate this to the user. The views of the model would be read-only, but that's much more friendly than blocking the entire GUI.
If you think that merely preventing concurrent access to the model with a QMutex would be enough, think again. Any modifications made to the model may potentially change its structure, so your writer would need to properly handle all signals emitted by model. This would make the writer much more complex. A temporarily read-only model lets you have responsive GUI with a temporary inconvenience to the user, at a minimal increase in code complexity.
Добрый день!
Мне пришлось изменять программу, которую писал не я. Я локализовал место в коде и знаю, чего от него хочу, но не знаю, что надо изменить, поэтому обращаюсь за помощью.
Код выглядит следующим образом:
Здесь происходит замещение содержимого файла нулями, для невозможности восстановления его после удаления. Погуглив я пришел к двум выводам, либо не происходит действительной записи в файл, либо он пишет новые данные в другие секторы, а старые остаются на месте. Как сделать так, что бы содержимое файла действительно заменялось нулями, для невозможности их восстановления.
Очень прошу помощи!
Заранее благодарю!
Изменение содержимого файла
Суть такова: имеются два файла index.html и index.php. Файл html для ввода данных, которые.
Изменение содержимого файла hosts
Возможно ли с помощью cmd-файла изменить содержимое файла Hosts, в частности добавление в него.
Изменение содержимого файла без вызова write
С новым годом всех и всем привет. Вопрос следующий: Есть ли возможность записывать изменения в.
Байт, внес предложенное изменение, но файл все равно удается восстановить. То есть решение не помогло(
По крайней мере так будет однозначно понятно, что мы пишем в файл массив размером block заполненный символами '0'.
alexey_rage, сделал так, как вы сказали! Старый блок закомментировал. Результат тот же.(( Файл удаляется, но его все равно можно восстановить. Использую программу ontrack, восстановление Raw.
Старый блок закомментировал. Результат тот же.(( Файл удаляется, но его все равно можно восстановить. Использую программу ontrack, восстановление Raw.
То есть после восстановления файл заполнен не нулями, а информацией, которая содержалась в нем до этого?
alexey_rage, совершенно верно! Я тестировал на примере картинки, после восстановления я вижу содержимое картинки полноценно, могу ее посмотреть, пересохранить.
zabachok, в общем вроде удалось выяснить суть проблемы.
Дело в то, что при открытии файла с флагом QIODevice::WriteOnly - файл не перезаписывается.
Файл удаляется, а вместо него создается новый файл с тем же именем в который потом и производится запись. Соответственно информация об удаленном файле сохраняется в файловой системе и его можно восстановить.
На данный момент в голову приходят два возможных варианта решения проблемы (опять таки не гарантировано, что это сработает):
1. Попробовать открыть файл для записи с флагом file.open(QIODevice::ReadWrite|QIODevice::Truncate) и записать в файл нули.
2. Открыть файл с флагом QIODevice::Append, затем переместить позицию указателя в ноль (seek) и записать в файл нули.
Спасибо Вам большое, что так помогаете!
Попробовал первый пункт. Если я правильно понял, то я просто изменяю флаги при открытии файла, остальное оставляю прежним?
Во втором случае я открываю файл так:
bool ok = file.open(QIODevice::Append);
и перед циклом перемещаю указатель так:
file.seek(0);
Все верно? Если да, то не помогает( Файл все равно с легкостью удается восстановить. Может быть это не очень то и возможно?
zabachok, попробуйте поэкспериментировать с флагами.
Нужно посмотреть запомнить дату создания оригинала.
Затем записать в файл нули, но не удалять, а посмотреть дату (и время) создания (именно создания, а не последнего изменения) файла после записи. Если даты будут различаться, значит старый файл удален, а потом создан новый с тем же именем. Ну и откройте перезаписанный файл через какой-то hex -редактор, чтобы хотя бы убедиться, что там действительно одни нули, а не что-то другое.
Нужно добиться того, чтобы файл действительно перезаписывался, а не создавался новый.
Как этого добиться, пока точно не знаю. Постараюсь сегодня найти время, чтобы разобраться с этим.
kamre, спасибо! Я попытался интуитивно воспользоватся мэпом, но что-то я делаю не так, компилятор говорит, что мэп не объявлен:
Как им пользоваться?
И еще не ясно про него. Как я понимаю, мэп копирует содержимое файла в оперативную память для дальнейшей работы с ним. Если он копирует в оперативную память, то наверняка при сохранении затирает старый и пишет рядом новый. Или нет?
в общем вроде удалось выяснить суть проблемы.
Дело в то, что при открытии файла с флагом QIODevice::WriteOnly - файл не перезаписывается.
Файл удаляется, а вместо него создается новый файл с тем же именем в который потом и производится запись. Соответственно информация об удаленном файле сохраняется в файловой системе и его можно восстановить.
Странно только, что программа восстановления находит файл с картинкой, а не с нолями, хотя оба были удалены.
Добавлено через 31 минуту
Если вручную удалять (не черз remove()), минуя корзину, то работает. Получается, что дело в remove().
Но компилятор выдает ошибку "ошибка: 'fsync' was not declared in this scope", как это решить?
Я использую Qt Creator 2.6.0, основан на Qt 4.8.3 (32-х битной), на платформе Windows 7.
Тестировал на дисках разного размера и с фалами разного расширения. txt удаляется в любой ситуации и навсегда. mp3 не удаляется ни при каких условиях, даже если удалить диск, создать другой, другого размера с другой буквой и отформатировать его(не быстрое форматирование), то он все равно восстанавливается. На диске размером в 50 мегабайт, достаточно подождать пол минуты и файлы любого типа не восстанавливаются. На диске в 2 гигабайта любой файл восстанавливается даже через сутки.
Опытным путем я пришел к выводу, что на возможность восстановить файлы влияют два фактора:
1. Время прошедшее после удаления. Прочитав темы, на которые вы ссылаетесь, я узнал, что есть три уровня кэша. Какое-то время информация там хранится и надо подождать пока кэш ее забудет.
2. Размер диска, чем меньше диск тем вероятнее затрется старая информация.
Может быть есть готовые библиотеки, которые можно подключить и удалять файлы действительно безвозвратно и не задумываться как она это делает?
Изменение содержимого exe -файла при каждой компиляции
Сограждане, простветите: Visual Studio 2013. При компиляции (Release) простенького проекта .
Как в папке WinSxS выполнить изменение содержимого файла и сохранить его?
В последних версиях Windows есть папка WinSxS. Нужно изменить содержание файла в этой папке и.
Изменение содержимого в JList
Привет! использую jListLog класса JList для ведения журнала действий; однако содержимое jListLog.
Изменение содержимого CHtmlView
Можно ли изменить документ открытый в CHtmlView. Например добиться такого же результата что и после.
Note: All functions in this class are reentrant.
The following user says thank you to radek.z for this useful post:
The "Q"
Join Date Jan 2006 Location Warsaw, Poland Posts 33,365 Thanks 3 Thanked 5,014 Times in 4,792 Posts Qt products Platforms Wiki edits 10
Let's make something clear first - you can't "remove" some part in the middle of a file, you can only overwrite or truncate it. The former you do with just calling write() with new data and the latter with using QFile::resize(). So in your situation, you can either reopen the file in truncate mode:
На сегодняшний день подавляющее большинство компьютерных программ работают с файлами, а поэтому важно уметь пользоваться функциями или классами, которые позволяют открывать и закрывать, записывать и считывать информацию из файлов. В этой статье я немного расскажу о файлах и о классе QFile, а также покажу пример использования этого класса.
Файл — это именованная область данных, которая хранится на накопителе информации. То есть понятно, что на накопителе есть участок памяти, который содержит последовательность бит, у этого участка есть своё уникальное имя(пример: /home/nick/Desktop/file.txt или C:\\Downloads\file.txt — это полные имена файлов). По имени можно обращаться к этому участку памяти.
Полное имя файла, дерево файловой системы.
Существует такое понятие, как относительное имя файла. Относительное имя файла не содержит полного пути к нему. Его имя относительно к текущей рабочей директории, например из которой запущена программа, которая работает с файлами.
. — это ссылка, которая содержит адрес на текущую директорию
.. — это ссылка, которая содержит адрес на предыдущую директорию
Если мы хотим обратиться к файлу /text.txt, находясь в директории /etc/, то необходимо писать ../text.txt
Если к файлу в текущей директории, то text.txt или ./text.txt
Обычно, когда говорят об имени файла, то подразумевают ту часть, где опущен полный путь к нему, т.е. просто file.txt. Путь к файлу и полное имя файл понятия взаимозаменяемые.
Более подробную информацию о файлах можно найти в сети.
Обратите внимание, что на сайте имеется очень похожая статья статья про реализацию чтения из файлов на C++, но без использования фреймворка Qt.
Класс QFile наследует класс QIODevice, который для работы с файлами предоставляет методы: открытия и закрытия файлов, для записи и чтения из файла, для создания и удаления файлов.
Чтобы создать объект для работы с файлом, нужно передать в конструктор имя файла.
Можно не передавать имя файла в конструктор, а установить его в объекте методом setName().
Часто при работе с файлами требуется узнать, открыт ли файл. Метод QIODevice::isOpen() возвращает значение true, если файл открыт и false в противном случае. А так как QFile унаследован от него, то мы можем проверить, открыт ли файл.
Для закрытия файла нужно вызвать метод QFile::close()
Обратите внимание, что данные сразу не записываются в файл на накопителе, они записываются в буфер в оперативной памяти. После закрытия файла данные из буфера записываются в файл на носителе. Это сделано для того, чтобы не нагружать жесткий диск или любой другой тип накопителя, на котором находится файл. Информацию из буфера в файл можно записать принудительно без закрытия файла, вызвав метод QFile::flush()
Существует очень полезный метод QFile::exists(). Он принимает на вход строку с именем файла и возвращает значение true, если такой файл существует. Существует статический и нестатический методы. Для работы со статическим методом необходимо указать имя файла.
Для работы с нестатическим достаточно просто его вызвать.
Для возможности записи или чтения необходимо открыть файл с указанием флага чтения QIODevice::ReadOnly или записи QIODevice::WriteOnly. Пример открытия файла для записи:
Есть разные способы чтения из фалов и записи. Можно считать или записать всю информацию за один раз, а можно по одному символу или блоками.
Для примера напишем программу, которая считывает из файла блок из первых 10-ти символов, а потом вставляет в другой файл.
Я создал файл filein.txt и внёс в него произвольный текст с помощью текстового редактора. После запуска программы я открыл filein.txt и fileout.txt в текстовом редакторе.
Первые 10 символов
Можно было считать все байты, тогда всё содержимое первого файла копировалось во второй. Для полного считывания строку
Нужно заменить на строку
В результате программа считает все байты в массив block, а после запишет их во второй файл.
Мы можем записывать информацию в файл строками, для этого его нужно открыть в текстовом режиме.
После передать адрес в конструктор нового объекста класса QTextStream.
Пример программы, в которая записывает в файл fileout.txt строку «Text, text, text.»
Содержимое fileout.txt после запуска программы
Содержимое файла fileout.txt
Запись в конец файла
Предыдущий метод полностью перезаписывал данные в файле, то есть очищал всё его содержимое и записывал новые данные. Перезаписи можно избежать и записывать новые данные в конец файла.
Флаг QIODevice::Append помещает указатель для записи (seek) в конец файла, в итоге входящий поток записывается сразу после имеющейся информации в файле. Пример фрагмента использования:
В примере вместо QIODevice::WriteOnly используется QIODevice::Append. Если сделать такое изменение в предыдущей программе, то после нескольких запусков в файле fileout.txt будет храниться строчка
Text, text, text.Text, text, text.Text, text, text.
Итак, мы рассмотрели основные методы для работы с файлами. Более подробную информацию обо всех методах класса QFile и QIODevice можно найти в официальной документации Qt и в сети.
Читайте также: