diff --git a/src/util/io-util.cpp b/src/util/io-util.cpp
new file mode 100644
index 0000000..0d02475
--- /dev/null
+++ b/src/util/io-util.cpp
@@ -0,0 +1,210 @@
+#include "util/io-util.hpp"
+
+#include "file-manifest.hpp"
+#include "torrent-file.hpp"
+
+#include <boost/filesystem.hpp>
+#include <boost/filesystem/fstream.hpp>
+
+#include <ndn-cxx/security/key-chain.hpp>
+#include <ndn-cxx/security/signing-helpers.hpp>
+
+namespace fs = boost::filesystem;
+
+using std::string;
+using std::vector;
+
+namespace ndn {
+namespace ntorrent {
+
+std::vector<ndn::Data>
+IoUtil::packetize_file(const fs::path& filePath,
+                       const ndn::Name& commonPrefix,
+                       size_t dataPacketSize,
+                       size_t subManifestSize,
+                       size_t subManifestNum)
+{
+  BOOST_ASSERT(0 < dataPacketSize);
+  size_t APPROX_BUFFER_SIZE = std::numeric_limits<int>::max(); // 2 * 1024 * 1024 *1024
+  auto file_size = fs::file_size(filePath);
+  auto start_offset = subManifestNum * subManifestSize * dataPacketSize;
+  // determine the number of bytes in this submanifest
+  auto subManifestLength = subManifestSize * dataPacketSize;
+  auto remainingFileLength = file_size - start_offset;
+  subManifestLength = remainingFileLength < subManifestLength
+                    ? remainingFileLength
+                    : subManifestLength;
+  vector<ndn::Data> packets;
+  packets.reserve(subManifestLength/dataPacketSize + 1);
+  fs::ifstream fs(filePath, fs::ifstream::binary);
+  if (!fs) {
+    BOOST_THROW_EXCEPTION(Data::Error("IO Error when opening" + filePath.string()));
+  }
+  // ensure that buffer is large enough to contain whole packets
+  // buffer size is either the entire file or the smallest number of data packets >= 2 GB
+  auto buffer_size =
+    subManifestLength < APPROX_BUFFER_SIZE   ?
+    subManifestLength                        :
+    APPROX_BUFFER_SIZE % dataPacketSize == 0 ?
+    APPROX_BUFFER_SIZE :
+    APPROX_BUFFER_SIZE + dataPacketSize - (APPROX_BUFFER_SIZE % dataPacketSize);
+  vector<char> file_bytes;
+  file_bytes.reserve(buffer_size);
+  size_t bytes_read = 0;
+  fs.seekg(start_offset);
+  while(fs && bytes_read < subManifestLength && !fs.eof()) {
+    // read the file into the buffer
+    fs.read(&file_bytes.front(), buffer_size);
+    auto read_size = fs.gcount();
+    if (fs.bad() || read_size < 0) {
+      BOOST_THROW_EXCEPTION(Data::Error("IO Error when reading" + filePath.string()));
+    }
+    bytes_read += read_size;
+    char *curr_start = &file_bytes.front();
+    for (size_t i = 0u; i < buffer_size; i += dataPacketSize) {
+      // Build a packet from the data
+      Name packetName = commonPrefix;
+      packetName.appendSequenceNumber(packets.size());
+      Data d(packetName);
+      auto content_length = i + dataPacketSize > buffer_size ? buffer_size - i : dataPacketSize;
+      d.setContent(encoding::makeBinaryBlock(tlv::Content, curr_start, content_length));
+      curr_start += content_length;
+      // append to the collection
+      packets.push_back(d);
+    }
+    file_bytes.clear();
+    // recompute the buffer_size
+    buffer_size =
+      subManifestLength - bytes_read < APPROX_BUFFER_SIZE ?
+      subManifestLength - bytes_read                      :
+      APPROX_BUFFER_SIZE % dataPacketSize == 0            ?
+      APPROX_BUFFER_SIZE                                  :
+      APPROX_BUFFER_SIZE + dataPacketSize - (APPROX_BUFFER_SIZE % dataPacketSize);
+  }
+  fs.close();
+  packets.shrink_to_fit();
+  ndn::security::KeyChain key_chain;
+  // sign all the packets
+  for (auto& p : packets) {
+    key_chain.sign(p, signingWithSha256());
+  }
+  return packets;
+}
+
+bool IoUtil::writeTorrentSegment(const TorrentFile& segment, const std::string& path)
+{
+  // validate that this torrent segment belongs to our torrent
+  auto segmentNum = segment.getSegmentNumber();
+  // write to disk at path
+  if (!fs::exists(path)) {
+    fs::create_directories(path);
+  }
+  auto filename = path + to_string(segmentNum);
+  // if there is already a file on disk for this torrent segment, determine if we should override
+  if (fs::exists(filename)) {
+    auto segmentOnDisk_ptr = io::load<TorrentFile>(filename);
+    if (nullptr != segmentOnDisk_ptr && *segmentOnDisk_ptr == segment) {
+      return false;
+    }
+  }
+  io::save(segment, filename);
+  // add to collection
+  return true;
+}
+
+bool IoUtil::writeFileManifest(const FileManifest& manifest, const std::string& path)
+{
+  auto subManifestNum = manifest.submanifest_number();
+  fs::path filename = path + manifest.file_name() + "/" + to_string(subManifestNum);
+
+  // write to disk at path
+  if (!fs::exists(filename.parent_path())) {
+    boost::filesystem::create_directories(filename.parent_path());
+  }
+  // if there is already a file on disk for this file manifest, determine if we should override
+  if (fs::exists(filename)) {
+    auto submanifestOnDisk_ptr = io::load<FileManifest>(filename.string());
+    if (nullptr != submanifestOnDisk_ptr && *submanifestOnDisk_ptr == manifest) {
+      return false;
+    }
+  }
+  io::save(manifest, filename.string());
+  return true;
+}
+bool
+IoUtil::writeData(const Data& packet, const FileManifest& manifest, size_t subManifestSize, fs::fstream& os)
+{
+  auto packetName = packet.getName();
+  auto packetNum = packetName.get(packetName.size() - 1).toSequenceNumber();
+  auto dataPacketSize = manifest.data_packet_size();
+  auto initial_offset = manifest.submanifest_number() * subManifestSize * dataPacketSize;
+  auto packetOffset =  initial_offset + packetNum * dataPacketSize;
+  // write data to disk
+  os.seekp(packetOffset);
+  try {
+    auto content = packet.getContent();
+    std::vector<char> data(content.value_begin(), content.value_end());
+    os.write(&data[0], data.size());
+    return true;
+  }
+  catch (io::Error &e) {
+    std::cerr << e.what() << std::endl;
+    return false;
+  }
+}
+
+std::shared_ptr<Data>
+IoUtil::readDataPacket(const Name& packetFullName,
+                       const FileManifest& manifest,
+                       size_t subManifestSize,
+                       fs::fstream& is)
+{
+  auto dataPacketSize = manifest.data_packet_size();
+  auto start_offset = manifest.submanifest_number() * subManifestSize * dataPacketSize;
+  auto packetNum = packetFullName.get(packetFullName.size() - 2).toSequenceNumber();
+  // seek to packet
+  is.sync();
+  is.seekg(start_offset + packetNum * dataPacketSize);
+  if (is.tellg() < 0) {
+    std::cerr << "bad seek" << std::endl;
+  }
+ // read contents
+ std::vector<char> bytes(dataPacketSize);
+ is.read(&bytes.front(), dataPacketSize);
+ auto read_size = is.gcount();
+ if (is.bad() || read_size < 0) {
+  std::cerr << "Bad read" << std::endl;
+  return nullptr;
+ }
+ // construct packet
+ auto packetName = packetFullName.getSubName(0, packetFullName.size() - 1);
+ auto d = make_shared<Data>(packetName);
+ d->setContent(encoding::makeBinaryBlock(tlv::Content, &bytes.front(), read_size));
+ ndn::security::KeyChain key_chain;
+ key_chain.sign(*d, signingWithSha256());
+ return d->getFullName() == packetFullName ? d : nullptr;
+}
+
+IoUtil::NAME_TYPE
+IoUtil::findType(const Name& name)
+{
+  NAME_TYPE rval = UNKNOWN;
+  if (name.get(name.size() - 2).toUri() == "torrent-file" ||
+      name.get(name.size() - 3).toUri() == "torrent-file") {
+    rval = TORRENT_FILE;
+  }
+  else if (name.get(name.size() - 2).isSequenceNumber() &&
+           name.get(name.size() - 3).isSequenceNumber()) {
+    rval = DATA_PACKET;
+  }
+  else if (name.get(name.size() - 2).isSequenceNumber() &&
+           !(name.get(name.size() - 3).isSequenceNumber())) {
+    rval = FILE_MANIFEST;
+  }
+  return rval;
+}
+
+
+
+} // namespace ntorrent
+} // namespace ndn}
