Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
file_util.h
Go to the documentation of this file.
1// Copyright 2010-2024 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 <string>
18#include <vector>
19
20#include "absl/log/check.h"
21#include "absl/status/statusor.h"
22#include "absl/strings/string_view.h"
23#include "google/protobuf/message.h"
24#include "ortools/base/file.h"
28
29namespace operations_research {
30
31// Reads a file, optionally gzipped, to a string.
32absl::StatusOr<std::string> ReadFileToString(absl::string_view filename);
33
34// Reads a proto from a file. Supports the following formats: binary, text,
35// JSON, all of those optionally gzipped. Returns errors as expected: filesystem
36// error, parsing errors, or type error: maybe it was a valid JSON, text proto,
37// or binary proto, but not of the right proto message (this is not an exact
38// science, but the heuristics used should work well in practice).
39absl::Status ReadFileToProto(
40 absl::string_view filename, google::protobuf::Message* proto,
41 // If true, unset required fields don't cause errors. This
42 // boolean doesn't work for JSON inputs.
43 bool allow_partial = false);
44
45// Exactly like ReadFileToProto(), but directly from the contents.
46absl::Status StringToProto(absl::string_view data,
47 google::protobuf::Message* proto,
48 bool allow_partial = false);
49
50template <typename Proto>
51absl::StatusOr<Proto> ReadFileToProto(absl::string_view filename,
52 bool allow_partial = false) {
53 Proto proto;
54 RETURN_IF_ERROR(ReadFileToProto(filename, &proto, allow_partial))
55 << "filename=" << filename;
56 return proto;
57}
58
59// Specifies how the proto should be formatted when writing it to a file.
60// kCanonicalJson converts field names to lower camel-case.
62
63// Writes a proto to a file. Supports the following formats: binary, text, JSON,
64// all of those optionally gzipped.
65// If 'proto_write_format' is kProtoBinary, ".bin" is appended to file_name. If
66// 'proto_write_format' is kJson or kCanonicalJson, ".json" is appended to
67// file_name. If 'gzipped' is true, ".gz" is appended to file_name.
68absl::Status WriteProtoToFile(absl::string_view filename,
69 const google::protobuf::Message& proto,
70 ProtoWriteFormat proto_write_format,
71 bool gzipped = false,
72 bool append_extension_to_file_name = true);
73
74namespace internal {
75// General method to read expected_num_records from a file. If
76// expected_num_records is -1, then reads all records from the file. If not,
77// dies if the file doesn't contain exactly expected_num_records.
78template <typename Proto>
79std::vector<Proto> ReadNumRecords(File* file, int expected_num_records) {
81 std::vector<Proto> protos;
82 Proto proto;
83 int num_read = 0;
84 while (num_read != expected_num_records &&
85 reader.ReadProtocolMessage(&proto)) {
86 protos.push_back(proto);
87 ++num_read;
88 }
89
90 CHECK(reader.Close())
91 << "File '" << file->filename()
92 << "'was not fully read, or something went wrong when closing "
93 "it. Is it the right format? (RecordIO of Protocol Buffers).";
94
95 if (expected_num_records >= 0) {
96 CHECK_EQ(num_read, expected_num_records)
97 << "There were less than the expected " << expected_num_records
98 << " in the file.";
99 }
100
101 return protos;
102}
103
104// Ditto, taking a filename as argument.
105template <typename Proto>
106std::vector<Proto> ReadNumRecords(absl::string_view filename,
107 int expected_num_records) {
109 expected_num_records);
110}
111} // namespace internal
112
113// Reads all records in Proto format in 'file'. Silently does nothing if the
114// file is empty. Dies if the file doesn't exist or contains something else than
115// protos encoded in RecordIO format.
116template <typename Proto>
117std::vector<Proto> ReadAllRecordsOrDie(absl::string_view filename) {
118 return internal::ReadNumRecords<Proto>(filename, -1);
119}
120template <typename Proto>
121std::vector<Proto> ReadAllRecordsOrDie(File* file) {
123}
124
125// Reads one record from file, which must be in RecordIO binary proto format.
126// Dies if the file can't be read, doesn't contain exactly one record, or
127// contains something else than the expected proto in RecordIO format.
128template <typename Proto>
129Proto ReadOneRecordOrDie(absl::string_view filename) {
130 Proto p;
131 p.Swap(&internal::ReadNumRecords<Proto>(filename, 1)[0]);
132 return p;
133}
134
135// Writes all records in Proto format to 'file'. Dies if it is unable to open
136// the file or write to it.
137template <typename Proto>
138void WriteRecordsOrDie(absl::string_view filename,
139 const std::vector<Proto>& protos) {
141 file::OpenOrDie(filename, "w", file::Defaults()));
142 for (const Proto& proto : protos) {
143 CHECK(writer.WriteProtocolMessage(proto));
144 }
145 CHECK(writer.Close());
146}
147
148} // namespace operations_research
149
150#endif // OR_TOOLS_UTIL_FILE_UTIL_H_
#define RETURN_IF_ERROR(expr)
Definition file.h:30
bool Close()
Closes the underlying file.
Definition recordio.cc:54
bool ReadProtocolMessage(P *const proto)
Definition recordio.h:91
bool Close()
Closes the underlying file.
Definition recordio.cc:29
bool WriteProtocolMessage(const P &proto)
Definition recordio.h:41
CpModelProto proto
The output proto.
Definition file.cc:169
Options Defaults()
Definition file.h:109
File * OpenOrDie(absl::string_view filename, absl::string_view mode, Options options)
Definition file.cc:182
std::vector< Proto > ReadNumRecords(File *file, int expected_num_records)
Definition file_util.h:79
In SWIG mode, we don't want anything besides these top-level includes.
void WriteRecordsOrDie(absl::string_view filename, const std::vector< Proto > &protos)
Definition file_util.h:138
absl::StatusOr< std::string > ReadFileToString(absl::string_view filename)
Reads a file, optionally gzipped, to a string.
Definition file_util.cc:42
absl::Status StringToProto(absl::string_view data, google::protobuf::Message *proto, bool allow_partial)
Exactly like ReadFileToProto(), but directly from the contents.
Definition file_util.cc:62
std::vector< Proto > ReadAllRecordsOrDie(absl::string_view filename)
Definition file_util.h:117
Proto ReadOneRecordOrDie(absl::string_view filename)
Definition file_util.h:129
absl::Status 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:142
absl::Status ReadFileToProto(absl::string_view filename, google::protobuf::Message *proto, bool allow_partial)
Definition file_util.cc:53