mirror of
https://github.com/nlohmann/json.git
synced 2026-11-04 11:49:22 +00:00
Docs: clarify file reading speed, scope of file replacement, cross-device rename
- The 10 to 20 % figure compares parsing from a std::ifstream with reading the file into a string with one read() and parsing that; reading with istreambuf_iterator is about twice as slow as parsing from the stream. - Say that replacing a file is general C++ advice, not library behaviour. - std::filesystem::rename fails across file systems (EXDEV) instead of falling back to a copy. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
1 file changed
+11
-7
@@ -33,9 +33,10 @@ json read_json_file(const std::string& path)
|
|||||||
running program, which is often not the directory of the source file (see the
|
running program, which is often not the directory of the source file (see the
|
||||||
[FAQ](../home/faq.md#parsing-a-file-fails-with-unexpected-end-of-input)).
|
[FAQ](../home/faq.md#parsing-a-file-fails-with-unexpected-end-of-input)).
|
||||||
- **Don't read the file into a string first.** Parsing from a `#!cpp std::ifstream` is only about 10 to 20 % slower
|
- **Don't read the file into a string first.** Parsing from a `#!cpp std::ifstream` is only about 10 to 20 % slower
|
||||||
than parsing a string that holds the whole file, and it needs no memory for the copy (see
|
than reading the whole file into a string with one `read()` and parsing that, and it needs no memory for the copy (see
|
||||||
[input sources and performance](parsing/index.md#input-sources-and-performance)). Read the file into a string only if
|
[input sources and performance](parsing/index.md#input-sources-and-performance)). The common way to read a file with
|
||||||
you need the text itself, for example for an error message.
|
`#!cpp std::istreambuf_iterator<char>` is so slow that it takes about twice as long as parsing from the stream. Read
|
||||||
|
the file into a string only if you need the text itself, for example for an error message.
|
||||||
- `parse` requires the file to hold exactly one JSON value. Files with one value per line are read with
|
- `parse` requires the file to hold exactly one JSON value. Files with one value per line are read with
|
||||||
[JSON Lines](parsing/json_lines.md); files too large for memory are covered in
|
[JSON Lines](parsing/json_lines.md); files too large for memory are covered in
|
||||||
[Large, streamed, and partial input](parsing/large_and_partial_input.md).
|
[Large, streamed, and partial input](parsing/large_and_partial_input.md).
|
||||||
@@ -75,6 +76,9 @@ void write_json_file(const std::string& path, const json& j)
|
|||||||
|
|
||||||
## Replacing a file without corrupting it
|
## Replacing a file without corrupting it
|
||||||
|
|
||||||
|
The library never writes a file itself, so this section is not about the library. It is general C++ advice for a
|
||||||
|
problem users of the library keep running into.
|
||||||
|
|
||||||
A program that crashes or is killed while it writes leaves a truncated file behind. To make sure readers see either the
|
A program that crashes or is killed while it writes leaves a truncated file behind. To make sure readers see either the
|
||||||
old or the new contents, write to a temporary file in the same directory and rename it over the original
|
old or the new contents, write to a temporary file in the same directory and rename it over the original
|
||||||
(C++17, `#!cpp <filesystem>`):
|
(C++17, `#!cpp <filesystem>`):
|
||||||
@@ -92,10 +96,10 @@ void replace_json_file(const std::filesystem::path& path, const json& j)
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The temporary file must be in the same directory (more precisely, on the same file system) as the target, as a rename
|
The temporary file must be in the same directory (more precisely, on the same file system) as the target: a rename
|
||||||
across file systems is a copy. On POSIX systems, the rename atomically replaces the file. Standard C++ has no way to
|
across file systems does not fall back to a copy, it fails and throws `#!cpp std::filesystem::filesystem_error`. On
|
||||||
flush a file to the disk (`fsync`), so this protects against a crashed program, but not necessarily against a power
|
POSIX systems, the rename atomically replaces the file. Standard C++ has no way to flush a file to the disk (`fsync`),
|
||||||
loss.
|
so this protects against a crashed program, but not necessarily against a power loss.
|
||||||
|
|
||||||
## Binary formats
|
## Binary formats
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user