module more.file; import std.stdio : File; import std.typecons : Flag, Yes, No; // Reads the file into a string char[] readFile(const(char)[] filename, Flag!"addNull" addNull) { import std.format : format; auto file = File(filename, "rb"); scope(exit) file.close(); auto fileSize = file.size(); static if(fileSize.max > size_t.max) { size_t maxFileSize = size_t.max; if(addNull) { maxFileSize--; } if(fileSize > maxFileSize) { assert(0, format("file \"%s\" of size %s is too large to read into one buffer (max is %s)", filename, fileSize, maxFileSize)); } } auto contents = new char[cast(size_t)(fileSize + (addNull ? 1 : 0))]; auto readSize = file.rawRead(contents).length; assert(fileSize == readSize, format("rawRead only read %s bytes of %s byte file", readSize, fileSize)); if(addNull) { contents[cast(size_t)fileSize] = '\0'; return contents[0..$-1]; } return contents; } unittest { import more.test; mixin(scopedTest!"file"); import std.file : thisExePath; auto exePath = thisExePath(); auto exeContents = readFile(exePath, No.addNull); auto exeContentsWithNull = readFile(exePath, Yes.addNull); assert(exeContents.length == exeContentsWithNull.length); }