3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
9 * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
10 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
11 * Copyright (c) 2001-2009, The GROMACS development team,
12 * check out http://www.gromacs.org for more information.
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * If you want to redistribute modifications, please consider that
20 * scientific software is very special. Version control is crucial -
21 * bugs must be traceable. We will be happy to consider code for
22 * inclusion in the official distribution, but derived work must not
23 * be called official GROMACS. Details are found in the README & COPYING
24 * files - if they are missing, get the official version at www.gromacs.org.
26 * To help us fund GROMACS development, we humbly ask that you cite
27 * the papers on the package - you can find them in the top README file.
29 * For more info, check our website at http://www.gromacs.org
33 * Implements gmx::File.
35 * \author Teemu Murtola <teemu.murtola@cbr.su.se>
36 * \ingroup module_utility
47 #include "gromacs/utility/exceptions.h"
48 #include "gromacs/utility/gmxassert.h"
49 #include "gromacs/utility/format.h"
54 File::File(const char *filename, const char *mode)
60 File::File(const std::string &filename, const char *mode)
72 // TODO: Log the error somewhere
77 void File::open(const char *filename, const char *mode)
79 GMX_RELEASE_ASSERT(fp_ == NULL,
80 "Attempted to open the same file object twice");
81 // TODO: Port all necessary functionality from ffopen() here.
82 fp_ = fopen(filename, mode);
86 FileIOError(formatString("Could not open file '%s'", filename)),
91 void File::open(const std::string &filename, const char *mode)
93 open(filename.c_str(), mode);
98 GMX_RELEASE_ASSERT(fp_ != NULL,
99 "Attempted to close a file object that is not open");
100 bool bOk = (fclose(fp_) == 0);
104 GMX_THROW_WITH_ERRNO(
105 FileIOError("Error while closing file"), "fclose", errno);
111 GMX_RELEASE_ASSERT(fp_ != NULL,
112 "Attempted to access a file object that is not open");
116 void File::readBytes(void *buffer, size_t bytes)
118 GMX_RELEASE_ASSERT(fp_ != NULL,
119 "Attempted to access a file object that is not open");
121 // TODO: Retry based on errno or something else?
122 size_t bytesRead = std::fread(buffer, 1, bytes, fp_);
123 if (bytesRead != bytes)
127 GMX_THROW(FileIOError(
128 formatString("Premature end of file\n"
129 "Attempted to read: %d bytes\n"
130 "Successfully read: %d bytes",
131 static_cast<int>(bytes),
132 static_cast<int>(bytesRead))));
136 GMX_THROW_WITH_ERRNO(FileIOError("Error while reading file"),
143 std::string File::readToString(const char *filename)
145 // Binary mode is required on Windows to be able to determine a size
146 // that can be passed to fread().
147 File file(filename, "rb");
148 FILE *fp = file.handle();
150 if (std::fseek(fp, 0L, SEEK_END) != 0)
152 GMX_THROW_WITH_ERRNO(FileIOError("Seeking to end of file failed"),
155 long len = std::ftell(fp);
158 GMX_THROW_WITH_ERRNO(FileIOError("Reading file length failed"),
161 if (std::fseek(fp, 0L, SEEK_SET) != 0)
163 GMX_THROW_WITH_ERRNO(FileIOError("Seeking to start of file failed"),
167 std::vector<char> data(len);
168 file.readBytes(&data[0], len);
171 std::string result(&data[0], len);
172 // The below is necessary on Windows to make newlines stay as '\n' on a
174 result = replaceAll(result, "\r\n", "\n");
180 std::string File::readToString(const std::string &filename)
182 return readToString(filename.c_str());