diff --git a/applications/test/OCountStream/Test-OCountStream.C b/applications/test/OCountStream/Test-OCountStream.C
index 9e5a5e84781014635c8a137093126337d5aa32d5..02594c2be0bbd33229133a08087590c2e27e3336 100644
--- a/applications/test/OCountStream/Test-OCountStream.C
+++ b/applications/test/OCountStream/Test-OCountStream.C
@@ -5,7 +5,7 @@
     \\  /    A nd           | www.openfoam.com
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
-    Copyright (C) 2017-2018 OpenCFD Ltd.
+    Copyright (C) 2017-2020 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -24,44 +24,88 @@ License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
 Description
+    Test null and counting output streams
 
 \*---------------------------------------------------------------------------*/
 
 #include "OCountStream.H"
 #include "StringStream.H"
+#include "Fstream.H"
 #include "IOstreams.H"
 #include "argList.H"
 
 using namespace Foam;
 
+template<class OS>
+void generateOutput(OS& os)
+{
+    for (label i = 0; i < 50; ++i)
+    {
+        os  << 1002 << " " << "abcd" << " "
+            << "def" << " " << 3.14159 << ";\n";
+    }
+}
+
+
+void printInfo(OSstream& os)
+{
+    Info<< "name: " << os.name() << " : " << os.stdStream().tellp() << nl;
+}
+
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 // Main program:
 
 int main(int argc, char *argv[])
 {
+    argList::addOption("write", "file", "test writing to file");
+
+    #include "setRootCase.H"
+
     OCountStream cnt;
     OStringStream str;
-
     ocountstream plain;
 
-    for (label i = 0; i < 50; ++i)
+    generateOutput(str);
+    generateOutput(cnt);
+    generateOutput(plain);
+
+    cnt.print(Info);
+
+    Info<< "counter state: " << (cnt.stdStream().rdstate()) << nl
+        << "via string-stream: " << str.str().size() << " chars" << nl
+        << "via ocountstream: " << plain.size() << " chars" << endl;
+
+    fileName outputName;
+    args.readIfPresent("write", outputName);
+
+    if (outputName.size())
     {
-        str
-            << 1002 << " " << "abcd" << " "
-            << "def" << " " << 3.14159 << ";\n";
+        IOstreamOption streamOpt;
 
-        cnt
-            << 1002 << " " << "abcd" << " "
-            << "def" << " " << 3.14159 << ";\n";
+        if (outputName.hasExt("gz"))
+        {
+            outputName.removeExt();
+            streamOpt.compression(IOstreamOption::COMPRESSED);
+        }
 
-        plain
-            << 1002 << " " << "abcd" << " "
-            << "def" << " " << 3.14159 << ";\n";
-    }
 
-    cnt.print(Info);
-    Info<< "via string-stream: " << str.str().size() << " chars" << endl;
-    Info<< "via ocountstream: " << plain.size() << " chars" << endl;
+        OFstream os1(outputName, streamOpt);
+        OFstream os2(nullptr);   // A /dev/null equivalent
+        OFstream os3("/dev/null");
+
+        // Doubled output
+        generateOutput(os1); generateOutput(os1);
+        generateOutput(os2); generateOutput(os2);
+        generateOutput(os3); generateOutput(os3);
+
+        Info<< nl
+            << "doubled output" << nl;
+
+        printInfo(os1);
+        printInfo(os2);
+        printInfo(os3);
+    }
 
     Info<< "\nEnd\n" << endl;
 
diff --git a/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.C b/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.C
index dede1ed7a0b7b59142cf638345a7688ffa6fb11e..d218df92ed62d3ac58471b6dc5d16da9b354b741 100644
--- a/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.C
+++ b/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.C
@@ -39,6 +39,21 @@ namespace Foam
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
+Foam::OFstream::OFstream
+(
+    std::nullptr_t
+)
+:
+    Foam::ofstreamPointer(nullptr),
+    OSstream(*(ofstreamPointer::get()), "/dev/null")
+{
+    setState(ofstreamPointer::get()->rdstate());
+    setOpened();
+
+    lineNumber_ = 1;
+}
+
+
 Foam::OFstream::OFstream
 (
     const fileName& pathname,
diff --git a/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.H b/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.H
index b1a144b5c688f4a8b367b82343d8ee06926f34a9..a9a7629d1a891b16a55991a863e9b29e563f5141 100644
--- a/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.H
+++ b/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.H
@@ -64,6 +64,10 @@ public:
 
     // Constructors
 
+        //- Construct a null output file stream.
+        //  Behaves like \c /dev/null and is named accordingly
+        explicit OFstream(std::nullptr_t);
+
         //- Construct from pathname
         explicit OFstream
         (
diff --git a/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointer.H b/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointer.H
index 8e5c2c3b2c021a13a2b5cba8ec86c7a10fca33d1..02cd3eb47c210665a80903e922a24c62e8ff6a94 100644
--- a/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointer.H
+++ b/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointer.H
@@ -82,7 +82,7 @@ protected:
     // Protected Member Functions
 
         //- Special 'rewind' method for compressed stream
-        void reopen_gz(const fileName& pathname_gz);
+        void reopen_gz(const std::string& pathname_gz);
 
 public:
 
@@ -164,7 +164,7 @@ class ofstreamPointer
 {
     // Private Data
 
-        //- The stream pointer (ofstream or ogzstream)
+        //- The stream pointer (ofstream | ogzstream | ocountstream)
         std::unique_ptr<std::ostream> ptr_;
 
 public:
@@ -192,6 +192,9 @@ public:
 
     // Constructors
 
+        //- Construct as null output stream using Foam::ocountstream
+        explicit ofstreamPointer(std::nullptr_t);
+
         //- Construct from pathname, with specified append option
         ofstreamPointer(const fileName& pathname, const bool append)
         :
diff --git a/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointers.C b/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointers.C
index be4316e01276d934d6a6cac50688f1a0949a3f3c..8fd7021828c3f6962eb8f26220f6810733996367 100644
--- a/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointers.C
+++ b/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointers.C
@@ -27,6 +27,7 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "fstreamPointer.H"
+#include "OCountStream.H"
 #include "OSspecific.H"
 
 // HAVE_LIBZ defined externally
@@ -131,6 +132,12 @@ Foam::ifstreamPointer::ifstreamPointer
 }
 
 
+Foam::ofstreamPointer::ofstreamPointer(std::nullptr_t)
+:
+    ptr_(new Foam::ocountstream)
+{}
+
+
 Foam::ofstreamPointer::ofstreamPointer
 (
     const fileName& pathname,
@@ -184,7 +191,7 @@ Foam::ofstreamPointer::ofstreamPointer
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-void Foam::ifstreamPointer::reopen_gz(const fileName& pathname_gz)
+void Foam::ifstreamPointer::reopen_gz(const std::string& pathname_gz)
 {
     #ifdef HAVE_LIBZ
     igzstream* gz = dynamic_cast<igzstream*>(ptr_.get());
diff --git a/src/OpenFOAM/db/IOstreams/IOstreams.C b/src/OpenFOAM/db/IOstreams/IOstreams.C
index ff0935c317e090a76d8d9cd6d39d6ee9f3961afa..f3e73e1d404dbc899df636596756a00cb5d9f5c4 100644
--- a/src/OpenFOAM/db/IOstreams/IOstreams.C
+++ b/src/OpenFOAM/db/IOstreams/IOstreams.C
@@ -6,7 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011 OpenFOAM Foundation
-    Copyright (C) 2018 OpenCFD Ltd.
+    Copyright (C) 2018-2020 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -49,7 +49,7 @@ unsigned int Foam::IOstream::precision_
 Foam::ISstream Foam::Sin(std::cin, "Sin");
 Foam::OSstream Foam::Sout(std::cout, "Sout");
 Foam::OSstream Foam::Serr(std::cerr, "Serr");
-Foam::OFstream Foam::Snull("/dev/null");
+Foam::OFstream Foam::Snull(nullptr);  // A "/dev/null" equivalent
 
 Foam::prefixOSstream Foam::Pout(std::cout, "Pout");
 Foam::prefixOSstream Foam::Perr(std::cerr, "Perr");
diff --git a/src/OpenFOAM/db/IOstreams/IOstreams.H b/src/OpenFOAM/db/IOstreams/IOstreams.H
index 9174f8ec91a5e7fb3c5c368fd3ae1443e7758e79..dff627a53b94609988d2de9f5afba06c41247546 100644
--- a/src/OpenFOAM/db/IOstreams/IOstreams.H
+++ b/src/OpenFOAM/db/IOstreams/IOstreams.H
@@ -6,6 +6,7 @@
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
     Copyright (C) 2011 OpenFOAM Foundation
+    Copyright (C) 2020 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -49,19 +50,19 @@ Description
 
 namespace Foam
 {
-    //- An Istream wrapper for std::cin
+    //- ISstream wrapped stdin (std::cin)
     extern ISstream Sin;
 
-    //- An Ostream wrapper for std::cout
+    //- OSstream wrapped stdout (std::cout)
     extern OSstream Sout;
 
-    //- An Ostream wrapper for std::cerr
+    //- OSstream wrapped stderr (std::cerr)
     extern OSstream Serr;
 
-    //- An Ostream wrapper for parallel output to std::cout
+    //- OSstream wrapped stdout (std::cout) with parallel prefix
     extern prefixOSstream Pout;
 
-    //- An Ostream wrapper for parallel output to std::cerr
+    //- OSstream wrapped stderr (std::cerr) with parallel prefix
     extern prefixOSstream Perr;
 }
 
diff --git a/src/OpenFOAM/db/IOstreams/memory/OCountStream.H b/src/OpenFOAM/db/IOstreams/memory/OCountStream.H
index cc1d325695fb2525a29dc0f912ef8e9e88539ce3..162a9df9416b359f68a8117233f8eaaf73b47d8f 100644
--- a/src/OpenFOAM/db/IOstreams/memory/OCountStream.H
+++ b/src/OpenFOAM/db/IOstreams/memory/OCountStream.H
@@ -56,45 +56,83 @@ class countstreambuf
 
 protected:
 
-    //- Handle output counting via overflow
-    virtual int overflow(int c = EOF)
+    //- Set position pointer to relative position
+    virtual std::streampos seekoff
+    (
+        std::streamoff off,
+        std::ios_base::seekdir way,
+        std::ios_base::openmode which = std::ios_base::in|std::ios_base::out
+    )
     {
-        if (c != EOF)
+        if (which & std::ios_base::out)
         {
-            ++size_;
+            if (way == std::ios_base::beg)
+            {
+                size_ = off;
+            }
+            else if (way == std::ios_base::cur)
+            {
+                size_ += off;
+            }
+            else if (way == std::ios_base::end)
+            {
+                // not really possible
+            }
+
+            return size_; // tellp()
         }
-        return c;
+
+        return -1;
     }
 
+
     //- Set position pointer to absolute position
-    //  For the counter, any positioning is ignored and it always acts like
-    //  seekpos(0), which resets the count.
+    //  For the counter, adjust the count accordingly.
     virtual std::streampos seekpos
     (
-        std::streampos,
+        std::streampos pos,
         std::ios_base::openmode which = std::ios_base::in|std::ios_base::out
     )
     {
-        size_ = 0;
-        return 0;
+        return seekoff(pos, std::ios_base::beg, which);
+    }
+
+
+    //- Handle output counting via overflow
+    virtual int overflow(int c = EOF)
+    {
+        if (c != EOF)
+        {
+            ++size_;
+        }
+        return c;
+    }
+
+
+    //- Put sequence of characters
+    virtual std::streamsize xsputn(const char* s, std::streamsize n)
+    {
+        size_ += n;
+        return n;
     }
 
+
 public:
 
     //- Default construct, or with precount size
-    countstreambuf(std::streamsize precount=0)
+    explicit countstreambuf(std::streamsize precount=0)
     :
         size_(precount)
     {}
 
-    //- \return The number of bytes counted
-    std::streamsize size() const
+    //- \return The buffer put position == number of bytes counted.
+    std::streamsize tellp() const
     {
         return size_;
     }
 
     //- Some information about the number of bytes counted
-    inline void printBufInfo(Ostream& os) const
+    void printBufInfo(Ostream& os) const
     {
         os << "count=" << size_;
     }
@@ -124,8 +162,14 @@ public:
     {}
 
 
+    //- \return The buffer put position == number of bytes counted.
+    using countstreambuf::tellp;
+
     //- \return The number of bytes counted
-    using countstreambuf::size;
+    std::streamsize size() const
+    {
+        return countstreambuf::tellp();
+    }
 
     //- Rewind the stream, reset the count
     void rewind()
@@ -183,7 +227,7 @@ public:
         //- The number of bytes counted
         std::streamsize size() const
         {
-            return buf_.size();
+            return buf_.tellp();
         }
 
         //- Rewind the stream, reset the count