diff --git a/common/cpp/include/system_wrappers/io.h b/common/cpp/include/system_wrappers/io.h
index 0e9ec9e65920e9d4015e8a9f2fa20c4247ab27a6..6d63c27472a5441a0b9ea41089a189672a7510e9 100644
--- a/common/cpp/include/system_wrappers/io.h
+++ b/common/cpp/include/system_wrappers/io.h
@@ -105,6 +105,7 @@ class IO {
      */
     virtual void            Close           (FileDescriptor fd, IOErrors* err) const = 0;
 
+    virtual size_t          Read            (FileDescriptor fd, void* buf, size_t length, IOErrors* err) const = 0;
     virtual size_t          Write           (FileDescriptor fd, const void* buf, size_t length, IOErrors* err) const = 0;
 
     virtual void            CreateDirectory(const std::string& directory_name, hidra2::IOErrors* err) const = 0;
diff --git a/common/cpp/include/system_wrappers/system_io.h b/common/cpp/include/system_wrappers/system_io.h
index ee0e29877704eb3a81d1adabeb0e7b2e265dd49b..1c3824cb7559c48e3e921ca76c1637c66eff9534 100644
--- a/common/cpp/include/system_wrappers/system_io.h
+++ b/common/cpp/include/system_wrappers/system_io.h
@@ -44,8 +44,8 @@ class SystemIO final : public IO {
      */
     FileDescriptor  Open(const std::string& filename, int open_flags, IOErrors* err) const;
     void            Close(FileDescriptor fd, IOErrors* err) const;
+    size_t          Read(FileDescriptor fd, void* buf, size_t length, IOErrors* err) const;
     size_t          Write(FileDescriptor fd, const void* buf, size_t length, IOErrors* err) const;
-    uint64_t        Read(int fd, uint8_t* array, uint64_t fsize, IOErrors* err) const;
     void            CreateDirectory(const std::string& directory_name, hidra2::IOErrors* err) const;
 
 };
diff --git a/common/cpp/src/system_io_linux.cpp b/common/cpp/src/system_io_linux.cpp
index d4d7b83ddb8f83db2aec84f75ef6bba838adf1bc..85dcf4cf3e75a9864abe03bf466174cd2a10d143 100644
--- a/common/cpp/src/system_io_linux.cpp
+++ b/common/cpp/src/system_io_linux.cpp
@@ -392,6 +392,7 @@ hidra2::FileDescriptor hidra2::SystemIO::Open(const std::string& filename,
 }
 
 void hidra2::SystemIO::Close(hidra2::FileDescriptor fd, hidra2::IOErrors* err) const {
+    *err = IOErrors::kNoError;
     int status = ::close(fd);
     if(!err) {
         return;
@@ -401,25 +402,47 @@ void hidra2::SystemIO::Close(hidra2::FileDescriptor fd, hidra2::IOErrors* err) c
         *err = IOErrorsFromErrno();
     }
 }
+
+size_t hidra2::SystemIO::Read(FileDescriptor fd, void* buf, size_t length, IOErrors* err) const {
+    *err = hidra2::IOErrors::kNoError;
+
+    size_t already_read = 0;
+
+    while(already_read < length) {
+        ssize_t received_amount = ::recv(fd, (uint8_t*)buf + already_read, length - already_read, 0);
+        if(received_amount == 0) {
+            *err = IOErrors::kEndOfFile;
+            return already_read;
+        }
+        if(received_amount == -1) {
+            *err = IOErrorsFromErrno();
+            return already_read;
+        }
+        already_read += received_amount;
+    }
+
+    return already_read;
+}
+
 size_t hidra2::SystemIO::Write(FileDescriptor fd, const void* buf, size_t length, IOErrors* err) const {
     *err = hidra2::IOErrors::kNoError;
 
-    size_t already_sent = 0;
+    size_t already_wrote = 0;
 
-    while(already_sent < length) {
-        ssize_t send_amount = ::write(fd, (uint8_t*)buf + already_sent, length - already_sent);
+    while(already_wrote < length) {
+        ssize_t send_amount = ::write(fd, (uint8_t*)buf + already_wrote, length - already_wrote);
         if(send_amount == 0) {
             *err = IOErrors::kEndOfFile;
-            return already_sent;
+            return already_wrote;
         }
         if(send_amount == -1) {
             *err = IOErrorsFromErrno();
-            return already_sent;
+            return already_wrote;
         }
-        already_sent += send_amount;
+        already_wrote += send_amount;
     }
 
-    return already_sent;
+    return already_wrote;
 }
 void hidra2::SystemIO::CreateDirectory(const std::string& directory_name, hidra2::IOErrors* err) const {
     *err = IOErrors::kNoError;
diff --git a/common/cpp/unittests/MockIO.h b/common/cpp/unittests/MockIO.h
index c556ef240402b97db2922fa19577bff0c1edcd8d..9f480ee1b62dae8d45525ba467eae2dd84c2e976 100644
--- a/common/cpp/unittests/MockIO.h
+++ b/common/cpp/unittests/MockIO.h
@@ -30,6 +30,7 @@ class MockIO : public IO {
     MOCK_CONST_METHOD3(Skip, void(FileDescriptor socket_fd, size_t length, IOErrors* err));
     MOCK_CONST_METHOD3(Open, FileDescriptor(const std::string& filename, int open_flags, IOErrors* err));
     MOCK_CONST_METHOD2(Close, void(FileDescriptor, IOErrors*));
+    MOCK_CONST_METHOD4(Read, size_t(FileDescriptor fd, void* buf, size_t length, IOErrors* err));
     MOCK_CONST_METHOD4(Write, size_t(FileDescriptor fd, const void* buf, size_t length, IOErrors* err));
     MOCK_CONST_METHOD2(CreateDirectory, void(const std::string& directory_name, hidra2::IOErrors* err));
 };