File indexing completed on 2024-11-03 09:52:32
0001 /* 0002 This file is part of the KDE libraries 0003 Copyright 1999 Waldo Bastian <bastian@kde.org> 0004 Copyright 2006 Jaison Lee <lee.jaison@gmail.com> 0005 0006 This library is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU Library General Public 0008 License version 2 as published by the Free Software Foundation. 0009 0010 This library is distributed in the hope that it will be useful, 0011 but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 Library General Public License for more details. 0014 0015 You should have received a copy of the GNU Library General Public License 0016 along with this library; see the file COPYING.LIB. If not, write to 0017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 Boston, MA 02110-1301, USA. 0019 */ 0020 0021 #ifndef KSAVEFILE_H 0022 #define KSAVEFILE_H 0023 0024 #include <kdelibs4support_export.h> 0025 0026 #include "kbackup.h" 0027 0028 #include <QFile> 0029 #include <QString> 0030 0031 /** 0032 * \class KSaveFile ksavefile.h <KSaveFile> 0033 * 0034 * @brief Class to allow for atomic file I/O, as well as utility functions. 0035 * 0036 * The KSaveFile class has been made to write out changes to an existing 0037 * file atomically. This means that either <b>ALL</b> changes will be written 0038 * to the file, or <b>NO</b> changes have been written, and the original file 0039 * (if any) has been unchanged. This is useful if you have lots of 0040 * time-consuming processing to perform during which an interruption could 0041 * occur, or if any error in the file structure will cause the entire file 0042 * to be corrupt. 0043 * 0044 * When you create a KSaveFile for a given file, a temporary file is instead 0045 * created and all your I/O occurs in the save file. Once you call finalize() 0046 * the temporary file is renamed to the target file, so that all your changes 0047 * happen at once. If abort() is called then the temporary file is removed and 0048 * the target file is untouched. KSaveFile derives from QFile so you can use 0049 * it just as you would a normal QFile. 0050 * 0051 * This class also includes several static utility functions available that 0052 * can help ensure data integrity. See the individual functions for details. 0053 * 0054 * Here is a quick example of how to use KSaveFile: 0055 * 0056 * First we create the KSaveFile and open it. 0057 * 0058 * @code 0059 * KSaveFile saveFile; 0060 * saveFile.setFileName("/lib/foo/bar.dat"); 0061 * if ( !saveFile.open() ) { 0062 * //Handle error 0063 * } 0064 * @endcode 0065 * 0066 * At this point the file "/lib/foo/bar.dat" has not been altered in any way. 0067 * Now, let's write out some data to the file. 0068 * 0069 * @code 0070 * QTextStream stream ( &saveFile ); 0071 * stream << "Add some data."; 0072 * // Perform long processing 0073 * stream << "Add some more data."; 0074 * stream.flush(); 0075 * @endcode 0076 * 0077 * Even after writing this data, the target file "/lib/foo/bar.dat" still has 0078 * not been altered in any way. Now that we are done writing our data, we can 0079 * write out all the changes that we have made by calling finalize(). 0080 * 0081 * @code 0082 * if ( !saveFile.finalize() ) { 0083 * //Handle error 0084 * } 0085 * @endcode 0086 * 0087 * If a user interruption or error occurred while we were writing out our 0088 * changes, we would instead call abort() to cancel all the I/O without 0089 * affecting the target file. 0090 * 0091 * @see QFile 0092 * 0093 * @author Jaison Lee <lee.jaison@gmail.com> 0094 * @author Waldo Bastian <bastian@kde.org> 0095 * 0096 * @deprecated since 5.0, port to QSaveFile. 0097 */ 0098 class KDELIBS4SUPPORT_DEPRECATED_EXPORT KSaveFile : public QFile 0099 { 0100 public: 0101 /** 0102 * Default constructor. 0103 */ 0104 KSaveFile(); 0105 0106 /** 0107 * Creates a new KSaveFile and sets the target file to @p filename. 0108 * 0109 * @param filename the path of the file 0110 */ 0111 KDELIBS4SUPPORT_DEPRECATED explicit KSaveFile(const QString &filename); 0112 0113 /** 0114 * Destructor. 0115 * @note If the file has been opened but not yet finalized, the 0116 * destructor will call finalize(). If you do not want the target file 0117 * to be affected you need to call abort() before destroying the object. 0118 **/ 0119 ~KSaveFile() override; 0120 0121 /** 0122 * @brief Set the target filename for the save file. 0123 * You must use this to set the filename of the target file if you do 0124 * not use the contructor that does so. 0125 * @param filename Name of the target file. 0126 */ 0127 void setFileName(const QString &filename); 0128 0129 /** 0130 * @brief Returns the name of the target file. 0131 * This function returns the name of the target file, or an empty 0132 * QString if it has not yet been set. 0133 * @returns The name of the target file. 0134 */ 0135 QString fileName() const override; 0136 0137 /** 0138 * @brief Returns the last error that occurred. 0139 * Use this function to check for errors. 0140 * @returns The last error that occurred, or QFile::NoError. 0141 */ 0142 QFile::FileError error() const; 0143 0144 /** 0145 * @brief Returns a human-readable description of the last error. 0146 * Use this function to get a human-readable description of the 0147 * last error that occurred. 0148 * @return A string describing the last error that occurred. 0149 */ 0150 QString errorString() const; 0151 0152 /** 0153 * @brief Open the save file. 0154 * This function will open the save file by creating a temporary file to write 0155 * to. It will also check to ensure that there are sufficient permissions to 0156 * write to the target file. 0157 * 0158 * @param flags Sets the QIODevice::OpenMode. It should contain the write flag, otherwise you 0159 * have a save file you cannot save to. 0160 * 0161 * @return true if successful, or false if an error has occurred. 0162 */ 0163 bool open(OpenMode flags = QIODevice::ReadWrite) override; 0164 0165 /** 0166 * @brief Discard changes without affecting the target file. 0167 * This will discard all changes that have been made to this file. 0168 * The target file will not be altered in any way. 0169 **/ 0170 void abort(); 0171 0172 /** 0173 * @brief Finalize changes to the file. 0174 * This will commit all the changes that have been made to the file. 0175 * @return true if successful, or false if an error has occurred. 0176 **/ 0177 bool finalize(); 0178 0179 /** 0180 * Allows writing over the existing file if necessary. 0181 * 0182 * QSaveFile creates a temporary file in the same directory as the final 0183 * file and atomically renames it. However this is not possible if the 0184 * directory permissions do not allow creating new files. 0185 * In order to preserve atomicity guarantees, open() fails when it 0186 * cannot create the temporary file. 0187 * 0188 * In order to allow users to edit files with write permissions in a 0189 * directory with restricted permissions, call setDirectWriteFallback() with 0190 * \a enabled set to true, and the following calls to open() will fallback to 0191 * opening the existing file directly and writing into it, without the use of 0192 * a temporary file. 0193 * This does not have atomicity guarantees, i.e. an application crash or 0194 * for instance a power failure could lead to a partially-written file on disk. 0195 * It also means cancelWriting() has no effect, in such a case. 0196 * 0197 * Typically, to save documents edited by the user, call setDirectWriteFallback(true), 0198 * and to save application internal files (configuration files, data files, ...), keep 0199 * the default setting which ensures atomicity. 0200 * 0201 * @since 4.10.3 0202 */ 0203 void setDirectWriteFallback(bool enabled); 0204 0205 /** 0206 * Returns true if the fallback solution for saving files in read-only 0207 * directories is enabled. 0208 * 0209 * @since 4.10.3 0210 */ 0211 bool directWriteFallback() const; 0212 0213 private: 0214 Q_DISABLE_COPY(KSaveFile) 0215 0216 class Private; 0217 Private *const d; 0218 }; 0219 0220 #endif