OR-Tools  9.3
file_util.h
Go to the documentation of this file.
1// Copyright 2010-2021 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14#ifndef OR_TOOLS_UTIL_FILE_UTIL_H_
15#define OR_TOOLS_UTIL_FILE_UTIL_H_
16
17#include <limits>
18#include <vector>
19
20#include "absl/status/statusor.h"
21#include "absl/strings/string_view.h"
22#include "google/protobuf/message.h"
23#include "ortools/base/file.h"
25
26namespace operations_research {
27
28// Reads a file, optionally gzipped, to a string.
29absl::StatusOr<std::string> ReadFileToString(absl::string_view filename);
30
31// Reads a proto from a file. Supports the following formats: binary, text,
32// JSON, all of those optionally gzipped. Crashes on filesystem failures, e.g.
33// file unreadable. Returns false on format failures, e.g. the file could be
34// read, but the contents couldn't be parsed -- or maybe it was a valid JSON,
35// text proto, or binary proto, but not of the right proto message.
36// Returns true on success.
37bool ReadFileToProto(absl::string_view filename,
38 google::protobuf::Message* proto);
39
40template <typename Proto>
41Proto ReadFileToProtoOrDie(absl::string_view filename) {
42 Proto proto;
43 CHECK(ReadFileToProto(filename, &proto)) << "with file: '" << filename << "'";
44 return proto;
45}
46
47// Specifies how the proto should be formatted when writing it to a file.
48// kCanonicalJson converts field names to lower camel-case.
50
51// Writes a proto to a file. Supports the following formats: binary, text, JSON,
52// all of those optionally gzipped. Returns false on failure.
53// If 'proto_write_format' is kProtoBinary, ".bin" is appended to file_name. If
54// 'proto_write_format' is kJson or kCanonicalJson, ".json" is appended to
55// file_name. If 'gzipped' is true, ".gz" is appended to file_name.
56bool WriteProtoToFile(absl::string_view filename,
57 const google::protobuf::Message& proto,
58 ProtoWriteFormat proto_write_format, bool gzipped = false,
59 bool append_extension_to_file_name = true);
60
61namespace internal {
62// General method to read expected_num_records from a file. If
63// expected_num_records is -1, then reads all records from the file. If not,
64// dies if the file doesn't contain exactly expected_num_records.
65template <typename Proto>
66std::vector<Proto> ReadNumRecords(File* file, int expected_num_records) {
68 std::vector<Proto> protos;
69 Proto proto;
70 int num_read = 0;
71 while (num_read != expected_num_records &&
72 reader.ReadProtocolMessage(&proto)) {
73 protos.push_back(proto);
74 ++num_read;
75 }
76
77 CHECK(reader.Close())
78 << "File '" << file->filename()
79 << "'was not fully read, or something went wrong when closing "
80 "it. Is it the right format? (RecordIO of Protocol Buffers).";
81
82 if (expected_num_records >= 0) {
83 CHECK_EQ(num_read, expected_num_records)
84 << "There were less than the expected " << expected_num_records
85 << " in the file.";
86 }
87
88 return protos;
89}
90
91// Ditto, taking a filename as argument.
92template <typename Proto>
93std::vector<Proto> ReadNumRecords(absl::string_view filename,
94 int expected_num_records) {
95 return ReadNumRecords<Proto>(file::OpenOrDie(filename, "r", file::Defaults()),
96 expected_num_records);
97}
98} // namespace internal
99
100// Reads all records in Proto format in 'file'. Silently does nothing if the
101// file is empty. Dies if the file doesn't exist or contains something else than
102// protos encoded in RecordIO format.
103template <typename Proto>
104std::vector<Proto> ReadAllRecordsOrDie(absl::string_view filename) {
105 return internal::ReadNumRecords<Proto>(filename, -1);
106}
107template <typename Proto>
108std::vector<Proto> ReadAllRecordsOrDie(File* file) {
109 return internal::ReadNumRecords<Proto>(file, -1);
110}
111
112// Reads one record from file, which must be in RecordIO binary proto format.
113// Dies if the file can't be read, doesn't contain exactly one record, or
114// contains something else than the expected proto in RecordIO format.
115template <typename Proto>
116Proto ReadOneRecordOrDie(absl::string_view filename) {
117 Proto p;
118 p.Swap(&internal::ReadNumRecords<Proto>(filename, 1)[0]);
119 return p;
120}
121
122// Writes all records in Proto format to 'file'. Dies if it is unable to open
123// the file or write to it.
124template <typename Proto>
125void WriteRecordsOrDie(absl::string_view filename,
126 const std::vector<Proto>& protos) {
128 file::OpenOrDie(filename, "w", file::Defaults()));
129 for (const Proto& proto : protos) {
131 }
132 CHECK(writer.Close());
133}
134
135} // namespace operations_research
136
137#endif // OR_TOOLS_UTIL_FILE_UTIL_H_
#define CHECK(condition)
Definition: base/logging.h:495
#define CHECK_EQ(val1, val2)
Definition: base/logging.h:703
Definition: base/file.h:33
bool ReadProtocolMessage(P *const proto)
Definition: recordio.h:91
bool WriteProtocolMessage(const P &proto)
Definition: recordio.h:41
CpModelProto proto
int Defaults()
Definition: base/file.h:120
File * OpenOrDie(const absl::string_view &filename, const absl::string_view &mode, int flags)
Definition: base/file.cc:154
std::vector< Proto > ReadNumRecords(File *file, int expected_num_records)
Definition: file_util.h:66
Collection of objects used to extend the Constraint Solver library.
Proto ReadFileToProtoOrDie(absl::string_view filename)
Definition: file_util.h:41
absl::StatusOr< std::string > ReadFileToString(absl::string_view filename)
Definition: file_util.cc:34
bool WriteProtoToFile(absl::string_view filename, const google::protobuf::Message &proto, ProtoWriteFormat proto_write_format, bool gzipped, bool append_extension_to_file_name)
Definition: file_util.cc:106
void WriteRecordsOrDie(absl::string_view filename, const std::vector< Proto > &protos)
Definition: file_util.h:125
std::vector< Proto > ReadAllRecordsOrDie(absl::string_view filename)
Definition: file_util.h:104
bool ReadFileToProto(absl::string_view filename, google::protobuf::Message *proto)
Definition: file_util.cc:45
Proto ReadOneRecordOrDie(absl::string_view filename)
Definition: file_util.h:116