diff --git a/applications/test/OFstream/Test-OFstream.cxx b/applications/test/OFstream/Test-OFstream.cxx index ac108699b0..62d371ae8a 100644 --- a/applications/test/OFstream/Test-OFstream.cxx +++ b/applications/test/OFstream/Test-OFstream.cxx @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2022 OpenCFD Ltd. + Copyright (C) 2022-2024 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -32,10 +32,14 @@ Description #include "IOstreams.H" #include "OSspecific.H" #include "argList.H" +#include "clock.H" +#include "Switch.H" #include "ListOps.H" using namespace Foam; +std::string time_stamp; + void listFiles(const fileName& dir) { wordList files = ListOps::create @@ -55,25 +59,150 @@ void listFiles(const fileName& dir) } +OSstream& printInfo(OFstream& os) +{ + InfoErr + << "open: " << os.name() << nl + << "appending: " << Switch::name(os.is_appending()) + << " tellp: "<< os.stdStream().tellp() + << " gz: " << Switch::name(os.compression()) << nl; + + return InfoErr.stream(); +} + + +void withHeader(OFstream& os) +{ + const auto tellp = os.stdStream().tellp(); + + if (tellp <= 0) + { + InfoErr + << "Add header" << nl; + os << "HEADER: " << time_stamp.c_str() << nl; + } +} + + +template +void generateLines(OSstreamType& os, label count = 1) +{ + for (label line = 1; line <= count; ++line) + { + os << "[" << line + << "] =============================================" << nl; + } +} + + +template +void generateContent +( + OSstreamType& os, + const bool with_seekend, + const bool test_overwrite = false, + const int64_t seek_out = -1 +) +{ + if (with_seekend) + { + os.stdStream().seekp(0, std::ios_base::end); + // OR? os.seek_end(); + } + + printInfo(os); + + withHeader(os); + + if (test_overwrite && seek_out >= 0) + { + InfoErr<< "... seekp(" << seek_out << ")" << nl; + + auto& oss = os.stdStream(); + + // Actually std::streampos, but cannot increment that + + int64_t pos(seek_out); + + const int64_t tellp_end = oss.tellp(); + + if (pos >= 0 && pos < tellp_end) + { + InfoErr + << "... fill from " << label(pos) + << " to " << label(tellp_end) << nl; + + oss.seekp(pos); + + while (pos < tellp_end) + { + // Fill with char 'X', rely on streambuf buffering + oss << 'X'; + ++pos; + } + + oss.seekp(seek_out); + os << "More content [at " << seek_out << ']' << endl; + } + } + + generateLines(os, 4); + + printInfo(os) + << "... sleep" << endl; + + listFiles(os.name().path()); + + sleep(2); + + os << "[new content] +++++++++++++++++++++++++++++++++++" << endl; +} + + +template +void generateOverwriteContent +( + OSstreamType& os, + const bool with_seekend, + const int64_t seek_out = -1 +) +{ + generateContent(os, with_seekend, true, seek_out); +} + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // Main program: int main(int argc, char *argv[]) { argList::addBoolOption("gz", "Use compression"); - argList::addBoolOption("append", "Use append mode"); + argList::addBoolOption("append-app", "Use append app mode"); + argList::addBoolOption("append-ate", "Use append ate mode"); + argList::addBoolOption("seekend", "Seek to end after non-append open"); + argList::addOption("seek", "value", "Seek from start (default: 100)"); argList::addBoolOption("atomic", "Use atomic"); argList::addBoolOption("keep", "Do not remove test directory"); argList::addOption("write", "file", "test writing to file"); #include "setRootCase.H" + // Same time-stamp for all generated files + time_stamp = clock::dateTime(); + const fileName baseDir("Test-OFstream-directory"); Foam::mkDir(baseDir); InfoErr<< "mkdir: " << baseDir << endl; + Info<< "start:" << nl; + listFiles(baseDir); + + const bool with_seekend = args.found("seekend"); + + const int seek_out = args.getOrDefault("seek", 100); + IOstreamOption streamOpt; if (args.found("gz")) @@ -83,10 +212,11 @@ int main(int argc, char *argv[]) IOstreamOption::appendType append = ( - args.found("append") - ? IOstreamOption::APPEND - : IOstreamOption::NON_APPEND + args.found("append-app") ? IOstreamOption::APPEND_APP + : args.found("append-ate") ? IOstreamOption::APPEND_ATE + : IOstreamOption::NO_APPEND ); + IOstreamOption::atomicType atomic = ( args.found("atomic") @@ -97,7 +227,6 @@ int main(int argc, char *argv[]) { OFstream(baseDir/"dummy")() << "Some file content" << endl; - Foam::ln("dummy", baseDir/"Test2.txt"); Foam::ln("dummy", baseDir/"Test3.txt"); Foam::ln("dummy", baseDir/"Test4.txt"); Foam::ln("dummy", baseDir/"Test4.txt.gz"); @@ -114,16 +243,31 @@ int main(int argc, char *argv[]) append ); - os << "=========================" << endl; + generateOverwriteContent(os, with_seekend, seek_out); + } - InfoErr<< "open: " << os.name() << endl; - InfoErr<< "... sleep" << endl; + { + OFstream os + ( + atomic, + baseDir/"Test1-app.txt", + streamOpt, + IOstreamOption::APPEND_APP + ); - listFiles(baseDir); + generateOverwriteContent(os, with_seekend, seek_out); + } - sleep(2); + { + OFstream os + ( + atomic, + baseDir/"Test1-ate.txt", + streamOpt, + IOstreamOption::APPEND_ATE + ); - os << "+++++++++++++++++++++++++++++++++++" << endl; + generateOverwriteContent(os, with_seekend, seek_out); } { @@ -132,39 +276,21 @@ int main(int argc, char *argv[]) atomic, baseDir/"Test2.txt", streamOpt - // NON_APPEND ); - os << "=========================" << endl; - - InfoErr<< "open: " << os.name() << endl; - InfoErr<< "... sleep" << endl; - - listFiles(baseDir); - - sleep(2); - - os << "+++++++++++++++++++++++++++++++++++" << endl; + generateContent(os, with_seekend); } + { OFstream os ( atomic, baseDir/"Test3.txt", streamOpt, - IOstreamOption::APPEND + IOstreamOption::APPEND_APP ); - os << "=========================" << endl; - - InfoErr<< "open: " << os.name() << endl; - InfoErr<< "... sleep" << endl; - - listFiles(baseDir); - - sleep(2); - - os << "+++++++++++++++++++++++++++++++++++" << endl; + generateContent(os, with_seekend, with_seekend); } { OFstream os @@ -174,35 +300,17 @@ int main(int argc, char *argv[]) IOstreamOption::COMPRESSED ); - os << "=========================" << endl; - - InfoErr<< "open: " << os.name() << endl; - InfoErr<< "... sleep" << endl; - - listFiles(baseDir); - - sleep(2); - - os << "+++++++++++++++++++++++++++++++++++" << endl; + // No seekend with COMPRESSED + generateContent(os, false); } { OFstream os ( IOstreamOption::ATOMIC, baseDir/"Test5.txt" - // ASCII UNCOMPRESSED NON_APPEND ); - os << "=========================" << endl; - - InfoErr<< "open: " << os.name() << endl; - InfoErr<< "... sleep" << endl; - - listFiles(baseDir); - - sleep(2); - - os << "+++++++++++++++++++++++++++++++++++" << endl; + generateContent(os, with_seekend); } Info<< nl << "done:" << endl; diff --git a/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.H b/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.H index 244c2d361f..958af45aae 100644 --- a/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.H +++ b/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.H @@ -28,7 +28,8 @@ Class Foam::IFstream Description - Input from file stream, using an ISstream + Input from file stream as an ISstream, normally using \c std::ifstream + for the actual input. SourceFiles IFstream.C diff --git a/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.C b/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.C index bc162c94f3..e0bf8edec3 100644 --- a/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.C +++ b/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2017 OpenFOAM Foundation - Copyright (C) 2017-2023 OpenCFD Ltd. + Copyright (C) 2017-2024 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -66,7 +66,7 @@ Foam::OFstream::OFstream ( pathname, streamOpt, - (IOstreamOption::appendType::APPEND == append), + append, (IOstreamOption::atomicType::ATOMIC == atomic) ), OSstream(*(ofstreamPointer::get()), pathname, streamOpt) diff --git a/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.H b/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.H index ca0819ff43..e0c4a17a96 100644 --- a/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.H +++ b/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2017 OpenFOAM Foundation - Copyright (C) 2017-2023 OpenCFD Ltd. + Copyright (C) 2017-2024 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -28,7 +28,29 @@ Class Foam::OFstream Description - Output to file stream, using an OSstream + Output to file stream as an OSstream, normally using \c std::ofstream + for the actual output. + +Note + The atomic output works by creating an intermediate temporary file, + which is renamed as an atomic operation when closing. It is not + possible, or particularly desirable, to have an atomic in combination + with append behaviour. If both are specified, append has priority. + +Note + An output file can be opened in two different \c append modes, both of + which preserve existing files: + -# A common append mode is APPEND_APP, which corresponds to the + \c std::ios_base::app flag. + A seek-to-end is performed at \em every write. + It is thus not possible to use any manual seeks to overwrite parts + of the file. + -# The other append mode is APPEND_ATE, which roughly corresponds to the + \c std::ios_base::ate flag behaviour. + A seek-to-end is performed immediately after opening, + but not subsequently. + Manual seeks can be used to overwrite parts of the file. + . SourceFiles OFstream.C @@ -64,53 +86,55 @@ public: // Constructors - //- Construct a null output file stream. - // Behaves like \c /dev/null and is named accordingly + //- Construct a null output file stream that behaves like \c /dev/null explicit OFstream(std::nullptr_t); //- Construct with specified atomic behaviour - //- from pathname, stream option, optional append + //- from pathname, stream option, optional append (see note). OFstream ( IOstreamOption::atomicType atomic, const fileName& pathname, IOstreamOption streamOpt = IOstreamOption(), - IOstreamOption::appendType append = IOstreamOption::NON_APPEND + IOstreamOption::appendType append = IOstreamOption::NO_APPEND ); - //- Construct from pathname and other specifications + //- Construct from pathname and other specifications. + // See note on append mode. explicit OFstream ( const fileName& pathname, IOstreamOption streamOpt = IOstreamOption(), - IOstreamOption::appendType append = IOstreamOption::NON_APPEND + IOstreamOption::appendType append = IOstreamOption::NO_APPEND ) : OFstream(IOstreamOption::NON_ATOMIC, pathname, streamOpt, append) {} - //- Construct from pathname, format (uncompressed), optional append, + //- Construct from pathname, format (uncompressed), + //- optional append (see note), //- atomic behaviour as per system default OFstream ( const fileName& pathname, IOstreamOption::streamFormat fmt, IOstreamOption::compressionType cmp = IOstreamOption::UNCOMPRESSED, - IOstreamOption::appendType append = IOstreamOption::NON_APPEND + IOstreamOption::appendType append = IOstreamOption::NO_APPEND ) : OFstream(pathname, IOstreamOption(fmt, cmp), append) {} //- Construct with specified atomic behaviour - //- from pathname, format (uncompressed), optional append + //- from pathname, format (uncompressed), + //- optional append (see note). OFstream ( IOstreamOption::atomicType atomic, const fileName& pathname, IOstreamOption::streamFormat fmt, IOstreamOption::compressionType cmp = IOstreamOption::UNCOMPRESSED, - IOstreamOption::appendType append = IOstreamOption::NON_APPEND + IOstreamOption::appendType append = IOstreamOption::NO_APPEND ) : OFstream(atomic, pathname, IOstreamOption(fmt, cmp), append) @@ -141,6 +165,21 @@ public: virtual void rewind(); + // Output stream modes + + //- True if opened in append mode \em and file already existed + bool is_appending() const noexcept + { + return ofstreamPointer::is_appending(); + } + + //- True if file creation behaves as atomic + bool is_atomic() const noexcept + { + return ofstreamPointer::is_atomic(); + } + + // Print //- Print stream description @@ -158,7 +197,7 @@ public: IOstreamOption::streamFormat fmt, IOstreamOption::versionNumber ver, IOstreamOption::compressionType cmp = IOstreamOption::UNCOMPRESSED, - IOstreamOption::appendType append = IOstreamOption::NON_APPEND + IOstreamOption::appendType append = IOstreamOption::NO_APPEND ) : OFstream(pathname, IOstreamOption(fmt, ver, cmp), append) diff --git a/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointer.H b/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointer.H index e3c9890793..1fbbabb253 100644 --- a/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointer.H +++ b/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointer.H @@ -194,20 +194,37 @@ public: class ofstreamPointer { + // Private Data Types + + //- The file open/creation type (bitmask) + enum modeType : char + { + NONE = 0, // Regular open (truncates existing) + ATOMIC = 0x1, // Atomic file creation + APPENDING = 0x2 // Is appending to an existing file + }; + + // Private Data //- The stream pointer (ofstream | ogzstream | ocountstream, ...) std::unique_ptr ptr_; - //- Atomic file creation - bool atomic_; + //- File output/creation type (atomic, append etc) + char mode_; + + + // Private Member Functions + + //- Clear any output mode information + void clear_mode() noexcept { mode_ = modeType::NONE; } protected: // Protected Member Functions - //- Reopen for compressed/non-compressed + //- Reopen for compressed/non-compressed. Discards append status. void reopen(const std::string& pathname); //- Close stream and rename file @@ -245,16 +262,20 @@ public: //- Construct from pathname, option, append, file handling atomic // \param pathname The file name to open for writing // \param streamOpt Respects (UNCOMPRESSED | COMPRESSED) - // \param append Open in append mode + // \param append Open in specified append mode // \param atomic Write into temporary file (not target file). // This option should only be used with a stream wrapper // (eg, OFstream) that handles the final renaming. + // + // \note + // There are two different append modes: + // append at every write, or only append after opening. explicit ofstreamPointer ( const fileName& pathname, IOstreamOption streamOpt = IOstreamOption(), - const bool append = false, - const bool atomic = false + IOstreamOption::appendType append = IOstreamOption::NO_APPEND, + bool atomic = false ); //- Construct from pathname, compression, append, file handling atomic @@ -268,12 +289,12 @@ public: ( const fileName& pathname, IOstreamOption::compressionType comp, - const bool append = false, - const bool atomic = false + IOstreamOption::appendType append = IOstreamOption::NO_APPEND, + bool atomic = false ); - // Member Functions + // Static Functions //- True if compiled with libz support static bool supports_gz() noexcept; @@ -293,14 +314,34 @@ public: //- Which compression type? IOstreamOption::compressionType whichCompression() const; + //- True if opened in append mode \em and file already existed + bool is_appending() const noexcept + { + return (mode_ & modeType::APPENDING); + } + + //- True if file creation behaves as atomic + bool is_atomic() const noexcept + { + return (mode_ & modeType::ATOMIC); + } + // Edit - //- Return managed pointer and release ownership - std::ostream* release() noexcept { return ptr_.release(); } + //- Return managed pointer and release ownership. + std::ostream* release() noexcept + { + clear_mode(); + return ptr_.release(); + } //- Replace the managed pointer - void reset(std::ostream* ptr) noexcept { ptr_.reset(ptr); } + void reset(std::ostream* ptr) noexcept + { + clear_mode(); + ptr_.reset(ptr); + } // Operators diff --git a/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointers.C b/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointers.C index 01b9f460b6..7e8d3282f0 100644 --- a/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointers.C +++ b/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointers.C @@ -88,14 +88,14 @@ Foam::ifstreamPointer::ifstreamPointer Foam::ofstreamPointer::ofstreamPointer() noexcept : ptr_(), - atomic_(false) + mode_(modeType::NONE) {} Foam::ofstreamPointer::ofstreamPointer(std::nullptr_t) : ptr_(new Foam::ocountstream), - atomic_(false) + mode_(modeType::NONE) {} @@ -103,27 +103,44 @@ Foam::ofstreamPointer::ofstreamPointer ( const fileName& pathname, IOstreamOption streamOpt, - const bool append, - const bool atomic + IOstreamOption::appendType append, + bool atomic ) : ptr_(), - atomic_(atomic) + mode_(modeType::NONE) { - std::ios_base::openmode mode + // Leave std::ios_base::trunc implicitly handled to make things + // easier for append mode. + + std::ios_base::openmode openmode ( std::ios_base::out | std::ios_base::binary ); - if (append) + if (append == IOstreamOption::APPEND_APP) { - mode |= std::ios_base::app; + openmode |= std::ios_base::app; // Cannot append to gzstream streamOpt.compression(IOstreamOption::UNCOMPRESSED); // Cannot use append + atomic operation, without lots of extra work - atomic_ = false; + atomic = false; + } + else if (append == IOstreamOption::APPEND_ATE) + { + // Handle an "append-like" mode by opening "r+b" and NOT as "ab" + // - file already exists: Sets read position to start + // - file does not exist: Error + + openmode |= std::ios_base::in; // [SIC] - use read bit, not append! + + // Cannot append to gzstream + streamOpt.compression(IOstreamOption::UNCOMPRESSED); + + // Cannot use append + atomic operation, without lots of extra work + atomic = false; } @@ -146,9 +163,9 @@ Foam::ofstreamPointer::ofstreamPointer #ifdef HAVE_LIBZ // TBD: - // atomic_ = true; // Always treat COMPRESSED like an atomic + // atomic = true; // Always treat COMPRESSED like an atomic - const fileName& target = (atomic_ ? pathname_tmp : pathname_gz); + const fileName& target = (atomic ? pathname_tmp : pathname_gz); // Remove old uncompressed version (if any) fType = Foam::type(pathname, false); @@ -158,7 +175,7 @@ Foam::ofstreamPointer::ofstreamPointer } // Avoid writing into symlinked files (non-append mode) - if (!append || atomic_) + if (atomic || (append == IOstreamOption::NO_APPEND)) { fType = Foam::type(target, false); if (fType == fileName::SYMLINK) @@ -167,7 +184,7 @@ Foam::ofstreamPointer::ofstreamPointer } } - ptr_.reset(new ogzstream(target, mode)); + ptr_.reset(new ogzstream(target, openmode)); #else /* HAVE_LIBZ */ @@ -184,7 +201,7 @@ Foam::ofstreamPointer::ofstreamPointer if (IOstreamOption::COMPRESSED != streamOpt.compression()) { - const fileName& target = (atomic_ ? pathname_tmp : pathname); + const fileName& target = (atomic ? pathname_tmp : pathname); // Remove old compressed version (if any) fType = Foam::type(pathname_gz, false); @@ -194,7 +211,7 @@ Foam::ofstreamPointer::ofstreamPointer } // Avoid writing into symlinked files (non-append mode) - if (!append || atomic_) + if (atomic || (append == IOstreamOption::NO_APPEND)) { fType = Foam::type(target, false); if (fType == fileName::SYMLINK) @@ -203,7 +220,75 @@ Foam::ofstreamPointer::ofstreamPointer } } - ptr_.reset(new std::ofstream(target, mode)); + // File pointer (std::ofstream) + auto filePtr = std::make_unique(target, openmode); + + if (append == IOstreamOption::APPEND_APP) + { + // Final handling for append 'app' (always non-atomic) + + // Set output position to the end (like std::ios_base::ate) + // but only to test if the file had a size. + // No real performance problem since any subsequent write + // will do the same anyhow. + + filePtr->seekp(0, std::ios_base::end); + if (filePtr->tellp() <= 0) + { + // Did not open an existing file + append = IOstreamOption::NO_APPEND; + } + } + else if (append == IOstreamOption::APPEND_ATE) + { + // Final handling for append 'ate' (always non-atomic) + + if (filePtr->good()) + { + // Success if file already exists. + // Set output position to the end - like std::ios_base::ate + + filePtr->seekp(0, std::ios_base::end); + + if (filePtr->tellp() <= 0) + { + // Did not open an existing file + append = IOstreamOption::NO_APPEND; + } + } + else + { + // Error if file does not already exist. + // Reopen as regular output mode only. + + // Did not open an existing file + append = IOstreamOption::NO_APPEND; + + if (filePtr->is_open()) + { + filePtr->close(); + } + filePtr->clear(); + filePtr->open + ( + target, + (std::ios_base::out | std::ios_base::binary) + ); + } + } + ptr_.reset(filePtr.release()); + } + + // Is appending to an existing file + if (append != IOstreamOption::NO_APPEND) + { + mode_ = modeType::APPENDING; + } + + // An atomic output operation (normally not appending!) + if (atomic) + { + mode_ |= modeType::ATOMIC; } } @@ -212,8 +297,8 @@ Foam::ofstreamPointer::ofstreamPointer ( const fileName& pathname, IOstreamOption::compressionType comp, - const bool append, - const bool atomic + IOstreamOption::appendType append, + bool atomic ) : ofstreamPointer @@ -237,12 +322,12 @@ void Foam::ifstreamPointer::open // Forcibly close old stream (if any) ptr_.reset(nullptr); - const std::ios_base::openmode mode + const std::ios_base::openmode openmode ( std::ios_base::in | std::ios_base::binary ); - ptr_.reset(new std::ifstream(pathname, mode)); + ptr_.reset(new std::ifstream(pathname, openmode)); if (!ptr_->good()) { @@ -254,7 +339,7 @@ void Foam::ifstreamPointer::open { #ifdef HAVE_LIBZ - ptr_.reset(new igzstream(pathname_gz, mode)); + ptr_.reset(new igzstream(pathname_gz, openmode)); #else /* HAVE_LIBZ */ @@ -311,7 +396,7 @@ void Foam::ofstreamPointer::reopen(const std::string& pathname) gz->close(); gz->clear(); - if (atomic_) + if (mode_ & modeType::ATOMIC) { gz->open ( @@ -341,10 +426,11 @@ void Foam::ofstreamPointer::reopen(const std::string& pathname) } file->clear(); - // Don't need original request to append since rewind implies - // trashing that anyhow. + // Invalidate the appending into existing file information + // since rewind usually means overwrite + mode_ &= ~modeType::APPENDING; - if (atomic_) + if (mode_ & modeType::ATOMIC) { file->open ( @@ -367,7 +453,13 @@ void Foam::ofstreamPointer::reopen(const std::string& pathname) void Foam::ofstreamPointer::close(const std::string& pathname) { - if (!atomic_ || pathname.empty()) return; + // Invalidate the appending into existing file information + mode_ &= ~modeType::APPENDING; + + if (pathname.empty() || !(mode_ & modeType::ATOMIC)) + { + return; + } #ifdef HAVE_LIBZ auto* gz = dynamic_cast(ptr_.get()); diff --git a/src/OpenFOAM/db/IOstreams/Fstreams/masterOFstream.H b/src/OpenFOAM/db/IOstreams/Fstreams/masterOFstream.H index c139e00e0d..c8ee2618cd 100644 --- a/src/OpenFOAM/db/IOstreams/Fstreams/masterOFstream.H +++ b/src/OpenFOAM/db/IOstreams/Fstreams/masterOFstream.H @@ -107,7 +107,7 @@ public: const label comm, const fileName& pathname, IOstreamOption streamOpt = IOstreamOption(), - IOstreamOption::appendType append = IOstreamOption::NON_APPEND, + IOstreamOption::appendType append = IOstreamOption::NO_APPEND, const bool writeOnProc = true ); @@ -118,7 +118,7 @@ public: const label comm, const fileName& pathname, IOstreamOption streamOpt = IOstreamOption(), - IOstreamOption::appendType append = IOstreamOption::NON_APPEND, + IOstreamOption::appendType append = IOstreamOption::NO_APPEND, const bool writeOnProc = true ) : @@ -140,7 +140,7 @@ public: IOstreamOption::atomicType atomic, const fileName& pathname, IOstreamOption streamOpt = IOstreamOption(), - IOstreamOption::appendType append = IOstreamOption::NON_APPEND, + IOstreamOption::appendType append = IOstreamOption::NO_APPEND, const bool writeOnProc = true ) : @@ -161,7 +161,7 @@ public: ( const fileName& pathname, IOstreamOption streamOpt = IOstreamOption(), - IOstreamOption::appendType append = IOstreamOption::NON_APPEND, + IOstreamOption::appendType append = IOstreamOption::NO_APPEND, const bool writeOnProc = true ) : diff --git a/src/OpenFOAM/db/options/IOstreamOption.H b/src/OpenFOAM/db/options/IOstreamOption.H index 15f243eb24..5c9f6ebb8c 100644 --- a/src/OpenFOAM/db/options/IOstreamOption.H +++ b/src/OpenFOAM/db/options/IOstreamOption.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2015 OpenFOAM Foundation - Copyright (C) 2018-2023 OpenCFD Ltd. + Copyright (C) 2018-2024 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -36,9 +36,6 @@ Description The compression (UNCOMPRESSED | COMPRESSED) is typically controlled by switch values (true/false, on/off, ...). - Additionally, some enumerations are defined (APPEND, NON_APPEND, ...) - that are useful, verbose alternatives to bool values. - SourceFiles IOstreamOption.C @@ -84,11 +81,14 @@ public: COMPRESSED //!< compression = true }; - //- File appending (NON_APPEND | APPEND) + //- File appending (NO_APPEND | APPEND_APP | APPEND_ATE) enum appendType : char { - NON_APPEND = 0, //!< append = false - APPEND //!< append = true + NO_APPEND = 0, //!< no append (truncates existing) + APPEND_APP, //!< append (seek end each write) + APPEND_ATE, //!< append (seek end after open) + NON_APPEND = NO_APPEND, //!< old name for NO_APPEND + APPEND = APPEND_APP //!< old name for APPEND_APP }; //- Atomic operations (output) diff --git a/src/OpenFOAM/global/fileOperations/collatedFileOperation/OFstreamCollator.C b/src/OpenFOAM/global/fileOperations/collatedFileOperation/OFstreamCollator.C index 6ee4bb36a8..5aa41da120 100644 --- a/src/OpenFOAM/global/fileOperations/collatedFileOperation/OFstreamCollator.C +++ b/src/OpenFOAM/global/fileOperations/collatedFileOperation/OFstreamCollator.C @@ -80,7 +80,7 @@ bool Foam::OFstreamCollator::writeFile osPtr.reset(new OFstream(atomic, fName, streamOpt, append)); auto& os = *osPtr; - if (append == IOstreamOption::NON_APPEND) + if (append == IOstreamOption::NO_APPEND) { // No IOobject so cannot use IOobject::writeHeader diff --git a/src/OpenFOAM/global/fileOperations/collatedFileOperation/collatedFileOperation.C b/src/OpenFOAM/global/fileOperations/collatedFileOperation/collatedFileOperation.C index bb0b861f95..7130370495 100644 --- a/src/OpenFOAM/global/fileOperations/collatedFileOperation/collatedFileOperation.C +++ b/src/OpenFOAM/global/fileOperations/collatedFileOperation/collatedFileOperation.C @@ -190,7 +190,7 @@ bool Foam::fileOperations::collatedFileOperation::appendObject // UNCOMPRESSED (binary only) IOstreamOption(IOstreamOption::BINARY, streamOpt.version()), // Append on sub-ranks - (isIOmaster ? IOstreamOption::NON_APPEND : IOstreamOption::APPEND) + (isIOmaster ? IOstreamOption::NO_APPEND : IOstreamOption::APPEND_APP) ); if (!os.good()) @@ -384,7 +384,7 @@ bool Foam::fileOperations::collatedFileOperation::writeObject comm_, pathName, streamOpt, - IOstreamOption::NON_APPEND, + IOstreamOption::NO_APPEND, writeOnProc ); @@ -431,7 +431,7 @@ bool Foam::fileOperations::collatedFileOperation::writeObject comm_, pathName, streamOpt, - IOstreamOption::NON_APPEND, + IOstreamOption::NO_APPEND, writeOnProc ); diff --git a/src/OpenFOAM/global/fileOperations/collatedFileOperation/threadedCollatedOFstream.C b/src/OpenFOAM/global/fileOperations/collatedFileOperation/threadedCollatedOFstream.C index 57af56c268..d9b0ddc0bb 100644 --- a/src/OpenFOAM/global/fileOperations/collatedFileOperation/threadedCollatedOFstream.C +++ b/src/OpenFOAM/global/fileOperations/collatedFileOperation/threadedCollatedOFstream.C @@ -81,7 +81,7 @@ Foam::threadedCollatedOFstream::~threadedCollatedOFstream() str(), IOstreamOption(IOstreamOption::BINARY, version(), compression_), atomic_, - IOstreamOption::NON_APPEND, + IOstreamOption::NO_APPEND, useThread_, headerEntries_ ); diff --git a/src/OpenFOAM/global/fileOperations/masterUncollatedFileOperation/masterUncollatedFileOperation.C b/src/OpenFOAM/global/fileOperations/masterUncollatedFileOperation/masterUncollatedFileOperation.C index 20c9511aa0..1d61009690 100644 --- a/src/OpenFOAM/global/fileOperations/masterUncollatedFileOperation/masterUncollatedFileOperation.C +++ b/src/OpenFOAM/global/fileOperations/masterUncollatedFileOperation/masterUncollatedFileOperation.C @@ -2505,7 +2505,7 @@ Foam::fileOperations::masterUncollatedFileOperation::NewOFstream comm_, pathName, streamOpt, - IOstreamOption::NON_APPEND, + IOstreamOption::NO_APPEND, writeOnProc ) ); @@ -2529,7 +2529,7 @@ Foam::fileOperations::masterUncollatedFileOperation::NewOFstream comm_, pathName, streamOpt, - IOstreamOption::NON_APPEND, + IOstreamOption::NO_APPEND, writeOnProc ) ); diff --git a/src/lumpedPointMotion/movement/lumpedPointMovement.C b/src/lumpedPointMotion/movement/lumpedPointMovement.C index c749c856a1..524e2be769 100644 --- a/src/lumpedPointMotion/movement/lumpedPointMovement.C +++ b/src/lumpedPointMotion/movement/lumpedPointMovement.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2016-2023 OpenCFD Ltd. + Copyright (C) 2016-2024 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -1291,7 +1291,7 @@ bool Foam::lumpedPointMovement::writeData const Tuple2* timesWritten ) const { - if (!Pstream::master()) + if (!UPstream::master()) { return false; } @@ -1306,13 +1306,13 @@ bool Foam::lumpedPointMovement::writeData writeData(os, forces, moments, outputFormat_, timesWritten); } - // Log output + // Log output - simple append to existing { OFstream os ( coupler().resolveFile(logName_), IOstreamOption(), - IOstreamOption::APPEND + IOstreamOption::APPEND_ATE ); writeData(os, forces, moments, outputFormatType::PLAIN, timesWritten);