mirror of
https://github.com/boostorg/boostlook.git
synced 2026-02-25 16:22:12 +00:00
833 lines
33 KiB
HTML
833 lines
33 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1">
|
|
<style>html.fonts-loading{visibility:hidden;opacity:0}</style>
|
|
<script>document.documentElement.classList.add('fonts-loading');</script>
|
|
|
|
<link rel="preload" href="../_/font/NotoSansDisplay.woff2" as="font" type="font/woff2" crossorigin="anonymous" />
|
|
<link rel="preload" href="../_/font/NotoSansDisplay-Italic.woff2" as="font" type="font/woff2" crossorigin="anonymous" />
|
|
<link rel="preload" href="../_/font/MonaspaceNeon-Var.woff2" as="font" type="font/woff2" crossorigin="anonymous" />
|
|
<link rel="preload" href="../_/font/MonaspaceXenon-Var.woff2" as="font" type="font/woff2" crossorigin="anonymous" />
|
|
|
|
<script>
|
|
(function() {
|
|
'use strict';
|
|
|
|
var revealed = false;
|
|
|
|
var reveal = function() {
|
|
if (revealed) return;
|
|
revealed = true;
|
|
document.documentElement.classList.remove('fonts-loading');
|
|
};
|
|
|
|
setTimeout(reveal, 3000);
|
|
|
|
if (!('FontFace' in window) || !('fonts' in document)) {
|
|
setTimeout(reveal, 100);
|
|
return;
|
|
}
|
|
|
|
var uiRoot = '../_';
|
|
var fonts = [
|
|
{
|
|
family: 'Noto Sans',
|
|
url: uiRoot + '/font/NotoSansDisplay.woff2',
|
|
descriptors: { style: 'normal', weight: '100 900', stretch: '62.5% 100%' }
|
|
},
|
|
{
|
|
family: 'Noto Sans',
|
|
url: uiRoot + '/font/NotoSansDisplay-Italic.woff2',
|
|
descriptors: { style: 'italic', weight: '100 900', stretch: '62.5% 100%' }
|
|
},
|
|
{
|
|
family: 'Monaspace Neon',
|
|
url: uiRoot + '/font/MonaspaceNeon-Var.woff2',
|
|
descriptors: { style: 'normal', weight: '400' }
|
|
},
|
|
{
|
|
family: 'Monaspace Xenon',
|
|
url: uiRoot + '/font/MonaspaceXenon-Var.woff2',
|
|
descriptors: { style: 'italic', weight: '400' }
|
|
}
|
|
];
|
|
|
|
var loadPromises = fonts.map(function(f) {
|
|
try {
|
|
var face = new FontFace(f.family, 'url("' + f.url + '")', f.descriptors);
|
|
return face.load().then(function(loaded) {
|
|
document.fonts.add(loaded);
|
|
return loaded;
|
|
}).catch(function() {
|
|
return null;
|
|
});
|
|
} catch (e) {
|
|
return Promise.resolve(null);
|
|
}
|
|
});
|
|
|
|
Promise.all(loadPromises)
|
|
.then(function() {
|
|
return document.fonts.ready;
|
|
})
|
|
.then(reveal)
|
|
.catch(reveal);
|
|
})();
|
|
</script> <title>System Components :: Boost Site Docs</title>
|
|
<link rel="canonical" href="https://boost.revsys.dev/user-guide/task-system.html">
|
|
<link rel="prev" href="task-simulation.html">
|
|
<link rel="next" href="testing-debugging.html">
|
|
<meta name="generator" content="Antora 3.1.14">
|
|
<link rel="stylesheet" href="../_/css/boostlook.css">
|
|
<link rel="stylesheet" href="../_/css/site.css">
|
|
<link rel="stylesheet" href="../_/css/vendor/tabs.css">
|
|
<script>
|
|
(function() {
|
|
if (window.self !== window.top) return;
|
|
var theme = localStorage.getItem('antora-theme');
|
|
if (!theme && window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
|
theme = 'dark';
|
|
}
|
|
if (theme === 'dark') document.documentElement.classList.add('dark');
|
|
})();
|
|
</script>
|
|
<script>var uiRootPath = '../_'</script>
|
|
<link rel="icon" href="../_/img/favicons/favicon.ico" type="image/x-icon">
|
|
<!-- Favicon configuration -->
|
|
<link rel="apple-touch-icon" sizes="180x180" href="../_/img/favicons/apple-touch-icon.png">
|
|
<link rel="icon" type="image/png" sizes="32x32" href="../_/img/favicons/favicon-32x32.png">
|
|
<link rel="icon" type="image/png" sizes="16x16" href="../_/img/favicons/favicon-16x16.png">
|
|
<link rel="manifest" href="../_/img/favicons/site.webmanifest">
|
|
<link rel="shortcut icon" href="../_/img/favicons/favicon.ico">
|
|
</head>
|
|
<body class="article toc2 toc-left">
|
|
<div class="boostlook">
|
|
<script type="module">import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs'; mermaid.initialize({"startOnLoad":true});</script> <div id="header">
|
|
<div id="toc" class="nav-container toc2" data-component="user-guide" data-version="">
|
|
<aside class="nav">
|
|
<button class="nav-close"></button>
|
|
<div class="panels">
|
|
<div class="nav-panel-menu is-active" data-panel="menu">
|
|
<nav class="nav-menu">
|
|
<div class="title-row">
|
|
<h3 class="title"><a href="index.html">User Guide</a></h3>
|
|
<button class="theme-toggle" aria-label="Toggle dark mode" title="Toggle theme" style="display:none">
|
|
<i class="fas fa-sun theme-icon-light"></i>
|
|
<i class="fas fa-moon theme-icon-dark"></i>
|
|
</button> </div>
|
|
<ul class="nav-list">
|
|
<ul class="nav-list">
|
|
<li class="" data-depth="1">
|
|
<a class="nav-link" href="intro.html">Introduction</a>
|
|
</li>
|
|
<li class="" data-depth="1">
|
|
<a class="nav-link" href="getting-started.html">Getting Started</a>
|
|
</li>
|
|
<li class="" data-depth="1">
|
|
<a class="nav-link" href="explore-the-content.html">Explore the Content</a>
|
|
</li>
|
|
<li class="" data-depth="1">
|
|
<a class="nav-link" href="faq.html">FAQ</a>
|
|
</li>
|
|
<li class="" data-depth="1">
|
|
<a class="nav-link" href="building-with-cmake.html">Building with CMake</a>
|
|
</li>
|
|
<li class="" data-depth="1">
|
|
<span class="nav-text">Common Scenarios</span>
|
|
</li>
|
|
<ul class="nav-list">
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="common-introduction.html">Introduction</a>
|
|
</li>
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="task-finance.html">Finance</a>
|
|
</li>
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="task-networking.html">Networking</a>
|
|
</li>
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="task-ai-client.html">AI Client</a>
|
|
</li>
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="task-simulation.html">Simulation</a>
|
|
</li>
|
|
<li class=" is-current-page" data-depth="2">
|
|
<a class="nav-link" href="task-system.html">System</a>
|
|
</li>
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="testing-debugging.html">Testing and Debugging</a>
|
|
</li>
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="task-text-processing.html">Text Processing</a>
|
|
</li>
|
|
</ul>
|
|
<li class="" data-depth="1">
|
|
<span class="nav-text">Advanced Scenarios</span>
|
|
</li>
|
|
<ul class="nav-list">
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="advanced-introduction.html">Introduction</a>
|
|
</li>
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="task-database.html">Database Engine</a>
|
|
</li>
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="task-machine-learning.html">Machine Learning</a>
|
|
</li>
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="task-metaprogramming.html">Metaprogramming</a>
|
|
</li>
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="task-natural-language-parsing.html">Natural Language</a>
|
|
</li>
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="task-parallel-computation.html">Parallel Computation</a>
|
|
</li>
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="task-quantum-computing.html">Quantum Computing</a>
|
|
</li>
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="task-aeronautical-engineering.html">Aeronautical Engineering</a>
|
|
</li>
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="task-bio-tech-engineering.html">Bio-Tech Engineering</a>
|
|
</li>
|
|
</ul>
|
|
<li class="" data-depth="1">
|
|
<span class="nav-text">Development</span>
|
|
</li>
|
|
<ul class="nav-list">
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="boost-macros.html">Macros</a>
|
|
</li>
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="generic-programming.html">Generic Programming</a>
|
|
</li>
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="exception-safety.html">Exception-Safety</a>
|
|
</li>
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="counted-body.html">Counted Body</a>
|
|
</li>
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="implementation-variations.html">Implementation Variations</a>
|
|
</li>
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="reduce-dependencies.html">Reduce Dependencies</a>
|
|
</li>
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="diagnostics.html">Diagnostics</a>
|
|
</li>
|
|
</ul>
|
|
<li class="" data-depth="1">
|
|
<span class="nav-text">User Community</span>
|
|
</li>
|
|
<ul class="nav-list">
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="user-community-introduction.html">Introduction</a>
|
|
</li>
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="reporting-issues.html">Reporting Issues</a>
|
|
</li>
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="discussion-policy.html">Discussion Policy</a>
|
|
</li>
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="bsl.html">The Boost Software License</a>
|
|
</li>
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="release-process.html">Release Process</a>
|
|
</li>
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="boost-history.html">History</a>
|
|
</li>
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="in-memoriam-beman-dawes.html">In Memoriam: Beman Dawes</a>
|
|
</li>
|
|
</ul>
|
|
<li class="" data-depth="1">
|
|
<span class="nav-text">Resources</span>
|
|
</li>
|
|
<ul class="nav-list">
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="resources.html">Resources</a>
|
|
</li>
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="glossary.html">Glossary</a>
|
|
</li>
|
|
</ul>
|
|
<li class="" data-depth="1">
|
|
<span class="nav-text">Reference</span>
|
|
</li>
|
|
<ul class="nav-list">
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="library-naming.html">Library Names and Organization</a>
|
|
</li>
|
|
<li class="" data-depth="2">
|
|
<a class="nav-link" href="header-organization-compilation.html">Header Organization and Compiled Binaries</a>
|
|
</li>
|
|
</ul>
|
|
</ul>
|
|
</ul>
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
</aside>
|
|
</div>
|
|
</div> <div id="content">
|
|
<article class="doc max-width-reset">
|
|
<div class="toolbar" role="navigation">
|
|
<button class="nav-toggle"></button>
|
|
<nav class="breadcrumbs" aria-label="breadcrumbs">
|
|
<ul>
|
|
<li>
|
|
<a href="index.html" aria-label="Home: User Guide">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="1rem" height="1rem" viewBox="0 -960 960 960" fill="#000000" aria-hidden="true"><path d="M160-120v-480l320-240 320 240v480H560v-280H400v280H160Z"/></svg>
|
|
</a>
|
|
</li>
|
|
<li>Common Scenarios</li>
|
|
<li><a href="task-system.html">System</a></li>
|
|
</ul>
|
|
</nav>
|
|
<div class="spirit-nav">
|
|
<a accesskey="p" href="task-simulation.html">
|
|
<span class="material-symbols-outlined" title="Previous: Simulation">arrow_back</span>
|
|
</a>
|
|
<a class="disabled" accesskey="u" aria-disabled="true" tabindex="-1">
|
|
<span class="material-symbols-outlined" title="Up:">arrow_upward</span>
|
|
</a>
|
|
<a accesskey="n" href="testing-debugging.html">
|
|
<span class="material-symbols-outlined" title="Next: Testing and Debugging">arrow_forward</span>
|
|
</a>
|
|
</div></div>
|
|
<h1 class="page">System Components</h1>
|
|
<div id="preamble">
|
|
<div class="sectionbody">
|
|
<div class="paragraph">
|
|
<p>Developing a system component for an operating system in C++ involves a wide range of low-level tasks. The relevant Boost libraries will largely depend on the specifics of your project. Some operating systems may not support all of the features of these libraries, and for low-level tasks, it may be more appropriate to use system APIs directly. For higher-level system operations, or cross-platform tasks, Boost libraries have a lot to offer.</p>
|
|
</div>
|
|
<div class="ulist square">
|
|
<ul class="square">
|
|
<li>
|
|
<p><a href="#_libraries">Libraries</a></p>
|
|
</li>
|
|
<li>
|
|
<p><a href="#_sample_system_file_and_error_handling">Sample System File and Error Handling</a></p>
|
|
</li>
|
|
<li>
|
|
<p><a href="#_support_configuration_settings">Support Configuration Settings</a></p>
|
|
</li>
|
|
<li>
|
|
<p><a href="#_time_the_system_operations">Time the System Operations</a></p>
|
|
</li>
|
|
<li>
|
|
<p><a href="#_see_also">See Also</a></p>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect1">
|
|
<h2 id="_libraries"><a class="anchor" href="#_libraries"></a>Libraries</h2>
|
|
<div class="sectionbody">
|
|
<div class="paragraph">
|
|
<p>Here are some Boost libraries that are useful in building system components:</p>
|
|
</div>
|
|
<div class="ulist circle">
|
|
<ul class="circle">
|
|
<li>
|
|
<p><a href="https://www.boost.org/libs/filesystem">Boost.Filesystem</a> : This library provides a portable way of querying and manipulating paths, files, and directories. It can be very helpful for system-level tasks that need to interact with the file system.</p>
|
|
</li>
|
|
<li>
|
|
<p><a href="https://www.boost.org/libs/program_options">Boost.ProgramOptions</a> : This library allows program options to be defined, with types and default values, and their values to be retrieved from the command line, from config files, and programmatically.</p>
|
|
</li>
|
|
<li>
|
|
<p><a href="https://www.boost.org/libs/system">Boost.System</a> : This library provides simple, light-weight error_code objects that encapsulate system-specific "error codes", distinct from C++ exceptions.</p>
|
|
</li>
|
|
<li>
|
|
<p><a href="https://www.boost.org/libs/chrono">Boost.Chrono</a> : This library provides a set of handy features for measuring time, which might be useful for system-level tasks that need to measure or manipulate time.</p>
|
|
</li>
|
|
<li>
|
|
<p><a href="https://www.boost.org/libs/asio">Boost.Asio</a> : This library provides a consistent asynchronous model using a modern C++ approach for network and low-level I/O programming. This might be useful for network-related components or any component that interacts with hardware.</p>
|
|
</li>
|
|
<li>
|
|
<p><a href="https://www.boost.org/libs/interprocess">Boost.Interprocess</a> : This library provides a way of sharing memory and communicating between processes. It’s useful for creating shared memory regions, handling inter-process communication, managing shared objects, and synchronizing processes.</p>
|
|
</li>
|
|
<li>
|
|
<p><a href="https://www.boost.org/libs/thread">Boost.Thread</a> : This library provides a portable interface for multithreading. It includes features for creating and managing threads, mutexes, condition variables, and futures.</p>
|
|
</li>
|
|
<li>
|
|
<p><a href="https://www.boost.org/libs/fiber">Boost.Fiber</a> : A fiber is a lightweight thread of execution. <a href="https://www.boost.org/libs/fiber">Boost.Fiber</a> provides a framework for creating and managing fibers, which can be useful in some system-level programming tasks.</p>
|
|
</li>
|
|
<li>
|
|
<p><a href="https://www.boost.org/libs/container">Boost.Container</a> : This provides advanced data structures beyond the ones provided by the C++ standard library, which may be useful in certain scenarios.</p>
|
|
</li>
|
|
<li>
|
|
<p><a href="https://www.boost.org/libs/process">Boost.Process</a> : This library allows you to create child processes, setup their environment and provides means to communicate with them asynchronously through various streams.</p>
|
|
<div class="dlist">
|
|
<dl>
|
|
<dt class="hdlist1">Note</dt>
|
|
<dd>
|
|
<p>The code in this tutorial was written and tested using Microsoft Visual Studio (Visual C++ 2022, Console App project) with Boost version 1.88.0.</p>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect1">
|
|
<h2 id="_sample_system_file_and_error_handling"><a class="anchor" href="#_sample_system_file_and_error_handling"></a>Sample System File and Error Handling</h2>
|
|
<div class="sectionbody">
|
|
<div class="paragraph">
|
|
<p>Two core features of most systems are in file handling and robust error reporting. For a simpler sample we’ll create an app that uses <a href="https://www.boost.org/libs/filesystem">Boost.Filesystem</a> to manipulate files and directories, and <a href="https://www.boost.org/libs/system">Boost.System</a> to capture and display specific errors.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The following sample creates a directory (<code>example_directory</code>) if it does not exist, writes a file (<code>example_file.txt.</code>) to the directory, reads from the file, and handles system-specific errors. Finally, it cleans up by deleting the file and directory, still handling any errors.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>For examples of networking and threading code, refer to <a href="task-networking.html" class="xref page">Networking</a> and <a href="task-parallel-computation.html" class="xref page">Parallel Computation</a>.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-cpp hljs" data-lang="cpp">#include <boost/filesystem.hpp>
|
|
#include <boost/system/error_code.hpp>
|
|
#include <iostream>
|
|
#include <fstream>
|
|
|
|
namespace fs = boost::filesystem;
|
|
namespace sys = boost::system;
|
|
|
|
// Check and report system-specific errors
|
|
void handle_error(const sys::error_code& ec, const std::string& action) {
|
|
if (ec) {
|
|
std::cerr << "Error while " << action << ": " << ec.message()
|
|
<< " (Code: " << ec.value() << ")\n";
|
|
}
|
|
else
|
|
{
|
|
std::cout << "All OK while " << action << '\n';
|
|
}
|
|
}
|
|
|
|
int main() {
|
|
fs::path dir = "example_directory";
|
|
fs::path file = dir / "example_file.txt";
|
|
sys::error_code ec;
|
|
|
|
// Create directory if it doesn't exist
|
|
if (!fs::exists(dir)) {
|
|
fs::create_directory(dir, ec);
|
|
handle_error(ec, "creating directory");
|
|
}
|
|
|
|
// Write to the file
|
|
{
|
|
std::ofstream ofs(file.string());
|
|
if (!ofs) {
|
|
std::cerr << "Failed to open file for writing!\n";
|
|
return 1;
|
|
}
|
|
ofs << "Hello, Boost.Filesystem!\n";
|
|
}
|
|
|
|
// Read from the file
|
|
{
|
|
std::ifstream ifs(file.string());
|
|
if (!ifs) {
|
|
std::cerr << "Failed to open file for reading!\n";
|
|
return 1;
|
|
}
|
|
std::string content;
|
|
std::getline(ifs, content);
|
|
std::cout << "File content: " << content << '\n';
|
|
}
|
|
|
|
// Remove file
|
|
fs::remove(file, ec);
|
|
handle_error(ec, "removing file");
|
|
|
|
// Remove directory
|
|
fs::remove(dir, ec);
|
|
handle_error(ec, "removing directory");
|
|
|
|
return 0;
|
|
}</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="dlist">
|
|
<dl>
|
|
<dt class="hdlist1">Note</dt>
|
|
<dd>
|
|
<p><a href="https://www.boost.org/libs/filesystem">Boost.Filesystem</a> ensures directory and file management is platform-independent.</p>
|
|
</dd>
|
|
<dt class="hdlist1">Tip</dt>
|
|
<dd>
|
|
<p>The first time you run this code, comment out the code to remove the file and directory at the end. After running the code, locate <code>example_directory</code>, then you can both verify the content of <code>example_file.txt</code> and record the parent directory of <code>example_directory</code> - which you will need in later examples.</p>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect1">
|
|
<h2 id="_support_configuration_settings"><a class="anchor" href="#_support_configuration_settings"></a>Support Configuration Settings</h2>
|
|
<div class="sectionbody">
|
|
<div class="paragraph">
|
|
<p>We are now going to include <a href="https://www.boost.org/libs/program_options">Boost.ProgramOptions</a> to allow configuration settings via command-line arguments and configuration files.</p>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The code now allows users to specify directory and file names, reads settings from a <code>config.ini</code> file, and uses default values when one is not specified or located.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-cpp hljs" data-lang="cpp">#include <boost/filesystem.hpp>
|
|
#include <boost/system/error_code.hpp>
|
|
#include <boost/program_options.hpp>
|
|
#include <iostream>
|
|
#include <fstream>
|
|
|
|
namespace fs = boost::filesystem;
|
|
namespace sys = boost::system;
|
|
namespace po = boost::program_options;
|
|
|
|
// Check and report system-specific errors
|
|
void handle_error(const sys::error_code& ec, const std::string& action) {
|
|
if (ec) {
|
|
std::cerr << "Error while " << action << ": " << ec.message()
|
|
<< " (Code: " << ec.value() << ")\n";
|
|
}
|
|
else
|
|
{
|
|
std::cout << "All OK while " << action << '\n';
|
|
}
|
|
}
|
|
|
|
int main(int argc, char* argv[]) {
|
|
// Default configuration values
|
|
std::string dir = "default_directory";
|
|
std::string filename = "default_file.txt";
|
|
std::string config_file = "config.ini";
|
|
|
|
// Define command-line options
|
|
po::options_description desc("Allowed options");
|
|
desc.add_options()
|
|
("help,h", "Show help message")
|
|
("dir,d", po::value<std::string>(&dir), "Directory name")
|
|
("file,f", po::value<std::string>(&filename), "File name")
|
|
("config,c", po::value<std::string>(&config_file)->default_value("config.ini"), "Configuration file");
|
|
|
|
// Parse command-line options
|
|
po::variables_map vm;
|
|
po::store(po::parse_command_line(argc, argv, desc), vm);
|
|
po::notify(vm);
|
|
|
|
if (vm.count("help")) {
|
|
std::cout << desc << std::endl;
|
|
return 0;
|
|
}
|
|
|
|
// Read options from configuration file (if available)
|
|
std::ifstream ifs(config_file);
|
|
if (ifs) {
|
|
po::store(po::parse_config_file(ifs, desc), vm);
|
|
po::notify(vm);
|
|
}
|
|
|
|
fs::path directory(dir);
|
|
fs::path file = directory / filename;
|
|
sys::error_code ec;
|
|
|
|
// Create directory if it doesn't exist
|
|
if (!fs::exists(directory)) {
|
|
fs::create_directory(directory, ec);
|
|
handle_error(ec, "creating directory");
|
|
}
|
|
|
|
// Write to the file
|
|
{
|
|
std::ofstream ofs(file.string());
|
|
if (!ofs) {
|
|
std::cerr << "Failed to open file for writing!\n";
|
|
return 1;
|
|
}
|
|
ofs << "Hello, Boost.Program_Options and Boost.Filesystem!\n";
|
|
}
|
|
|
|
// Read from the file
|
|
{
|
|
std::ifstream ifs(file.string());
|
|
if (!ifs) {
|
|
std::cerr << "Failed to open file for reading!\n";
|
|
return 1;
|
|
}
|
|
std::string content;
|
|
std::getline(ifs, content);
|
|
std::cout << "File content: " << content << '\n';
|
|
}
|
|
|
|
// Remove file
|
|
fs::remove(file, ec);
|
|
handle_error(ec, "removing file");
|
|
|
|
// Remove directory
|
|
fs::remove(directory, ec);
|
|
handle_error(ec, "removing directory");
|
|
|
|
return 0;
|
|
}</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The command line options accepted by the sample are:</p>
|
|
</div>
|
|
<table class="tableblock frame-none grid-all stripes-even stretch">
|
|
<colgroup>
|
|
<col style="width: 25%;">
|
|
<col style="width: 75%;">
|
|
</colgroup>
|
|
<thead>
|
|
<tr>
|
|
<th class="tableblock halign-left valign-top">Option</th>
|
|
<th class="tableblock halign-left valign-top">Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>--dir</code> or <code>-d</code></p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify the directory.</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>--file</code> or <code>-f</code></p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify the filename.</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>--config</code> or <code>-c</code></p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">Specify the configuration file.</p></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>--help</code> or <code>-h</code></p></td>
|
|
<td class="tableblock halign-left valign-top"><p class="tableblock">Display available options.</p></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<div class="paragraph">
|
|
<p>The following is an example <code>config.ini</code> file, create it and store it to the parent directory you recorded in the previous example.</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-text hljs" data-lang="text">dir = my_directory
|
|
file = my_file.txt</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The following command lines show how to run with defaults, run with options specified manually, and then run with a config file:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-text hljs" data-lang="text">./program
|
|
|
|
./program --dir=my_data --file=data.txt
|
|
|
|
./program --config=my_config.ini</code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect1">
|
|
<h2 id="_time_the_system_operations"><a class="anchor" href="#_time_the_system_operations"></a>Time the System Operations</h2>
|
|
<div class="sectionbody">
|
|
<div class="paragraph">
|
|
<p>It might be important to record the time taken for system operations, both in testing and in the operation of a system app. So, let’s integrate <a href="https://www.boost.org/libs/chrono">Boost.Chrono</a> to measure the time taken for key filesystem operations, such as creating directories, writing to files, reading files, and deleting files.</p>
|
|
</div>
|
|
<div class="imageblock">
|
|
<div class="content">
|
|
<img src="_images/system-timing.png" alt="system timing">
|
|
</div>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-cpp hljs" data-lang="cpp">#include <boost/filesystem.hpp>
|
|
#include <boost/system/error_code.hpp>
|
|
#include <boost/program_options.hpp>
|
|
#include <boost/chrono.hpp>
|
|
#include <iostream>
|
|
#include <fstream>
|
|
|
|
namespace fs = boost::filesystem;
|
|
namespace sys = boost::system;
|
|
namespace po = boost::program_options;
|
|
namespace chrono = boost::chrono;
|
|
|
|
// Check and report system-specific errors
|
|
void handle_error(const sys::error_code& ec, const std::string& action) {
|
|
if (ec) {
|
|
std::cerr << "Error while " << action << ": " << ec.message()
|
|
<< " (Code: " << ec.value() << ")\n";
|
|
}
|
|
else
|
|
{
|
|
std::cout << "All OK while " << action << '\n';
|
|
}
|
|
}
|
|
|
|
int main(int argc, char* argv[]) {
|
|
|
|
// Default configuration values
|
|
std::string dir = "default_directory";
|
|
std::string filename = "default_file.txt";
|
|
std::string config_file = "config.ini";
|
|
|
|
// Define command-line options
|
|
po::options_description desc("Allowed options");
|
|
desc.add_options()
|
|
("help,h", "Show help message")
|
|
("dir,d", po::value<std::string>(&dir), "Directory name")
|
|
("file,f", po::value<std::string>(&filename), "File name")
|
|
("config,c", po::value<std::string>(&config_file)->default_value("config.ini"), "Configuration file");
|
|
|
|
// Parse command-line options
|
|
po::variables_map vm;
|
|
po::store(po::parse_command_line(argc, argv, desc), vm);
|
|
po::notify(vm);
|
|
|
|
if (vm.count("help")) {
|
|
std::cout << desc << std::endl;
|
|
return 0;
|
|
}
|
|
|
|
// Read options from configuration file (if available)
|
|
std::ifstream ifs_config(config_file);
|
|
if (ifs_config) {
|
|
po::store(po::parse_config_file(ifs_config, desc), vm);
|
|
po::notify(vm);
|
|
}
|
|
|
|
fs::path directory(dir);
|
|
fs::path file = directory / filename;
|
|
sys::error_code ec;
|
|
|
|
// Measure time for directory creation
|
|
auto start = chrono::steady_clock::now();
|
|
if (!fs::exists(directory)) {
|
|
fs::create_directory(directory, ec);
|
|
handle_error(ec, "creating directory");
|
|
}
|
|
auto end = chrono::steady_clock::now();
|
|
std::cout << "Directory creation took: "
|
|
<< chrono::duration_cast<chrono::microseconds>(end - start).count()
|
|
<< " microseconds\n";
|
|
|
|
// Measure time for writing to file
|
|
start = chrono::steady_clock::now();
|
|
{
|
|
std::ofstream ofs(file.string());
|
|
if (!ofs) {
|
|
std::cerr << "Failed to open file for writing!\n";
|
|
return 1;
|
|
}
|
|
ofs << "Hello, Boost.Program_Options, Boost.Filesystem, and Boost.Chrono!\n";
|
|
}
|
|
end = chrono::steady_clock::now();
|
|
std::cout << "File writing took: "
|
|
<< chrono::duration_cast<chrono::microseconds>(end - start).count()
|
|
<< " microseconds\n";
|
|
|
|
// Measure time for reading from file
|
|
start = chrono::steady_clock::now();
|
|
{
|
|
std::ifstream ifs(file.string());
|
|
if (!ifs) {
|
|
std::cerr << "Failed to open file for reading!\n";
|
|
return 1;
|
|
}
|
|
std::string content;
|
|
std::getline(ifs, content);
|
|
std::cout << "File content: " << content << '\n';
|
|
}
|
|
end = chrono::steady_clock::now();
|
|
std::cout << "File reading took: "
|
|
<< chrono::duration_cast<chrono::microseconds>(end - start).count()
|
|
<< " microseconds\n";
|
|
|
|
// Measure time for file deletion
|
|
start = chrono::steady_clock::now();
|
|
fs::remove(file, ec);
|
|
handle_error(ec, "removing file");
|
|
end = chrono::steady_clock::now();
|
|
std::cout << "File deletion took: "
|
|
<< chrono::duration_cast<chrono::microseconds>(end - start).count()
|
|
<< " microseconds\n";
|
|
|
|
// Measure time for directory deletion
|
|
start = chrono::steady_clock::now();
|
|
fs::remove(directory, ec);
|
|
handle_error(ec, "removing directory");
|
|
end = chrono::steady_clock::now();
|
|
std::cout << "Directory deletion took: "
|
|
<< chrono::duration_cast<chrono::microseconds>(end - start).count()
|
|
<< " microseconds\n";
|
|
|
|
return 0;
|
|
}</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>The following is example output from running the sample:</p>
|
|
</div>
|
|
<div class="listingblock">
|
|
<div class="content">
|
|
<pre class="highlightjs highlight"><code class="language-text hljs" data-lang="text">All OK while creating directory
|
|
Directory creation took: 459 microseconds
|
|
File writing took: 631 microseconds
|
|
File content: Hello, Boost.Program_Options, Boost.Filesystem, and Boost.Chrono!
|
|
File reading took: 1385 microseconds
|
|
All OK while removing file
|
|
File deletion took: 339 microseconds
|
|
All OK while removing directory
|
|
Directory deletion took: 386 microseconds</code></pre>
|
|
</div>
|
|
</div>
|
|
<div class="paragraph">
|
|
<p>Adding timing features to your system operations will help you maintain more robust and performance-aware code, so as code is updated you will have built in the checks and balances so that if something goes awry - you will be able to capture and correct it early in the development cycle.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sect1">
|
|
<h2 id="_see_also"><a class="anchor" href="#_see_also"></a>See Also</h2>
|
|
<div class="sectionbody">
|
|
<div class="ulist">
|
|
<ul>
|
|
<li>
|
|
<p><a href="https://www.boost.org/doc/libs/latest/libs/libraries.htm#Memory">Category: Memory</a></p>
|
|
</li>
|
|
<li>
|
|
<p><a href="https://www.boost.org/doc/libs/latest/libs/libraries.htm#Miscellaneous">Category: Miscellaneous</a></p>
|
|
</li>
|
|
<li>
|
|
<p><a href="https://www.boost.org/doc/libs/latest/libs/libraries.htm#System">Category: System</a></p>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="edit-this-page">
|
|
<a href="file:///Users/julio/dev/website-v2-docs/user-guide/modules/ROOT/pages/task-system.adoc">Edit this Page</a>
|
|
</div>
|
|
<nav class="pagination">
|
|
<span class="prev"><a href="task-simulation.html">Simulation</a></span>
|
|
<span class="next"><a href="testing-debugging.html">Testing and Debugging</a></span>
|
|
</nav>
|
|
</article>
|
|
</div>
|
|
<div id="footer">
|
|
<script id="site-script" src="../_/js/site.js" data-ui-root-path="../_"></script>
|
|
<script async src="../_/js/vendor/highlight.js"></script>
|
|
<script async src="../_/js/vendor/tabs.js" data-sync-storage-key="preferred-tab"></script>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|