Directories in Cilk
Here’s the translation of the Go code to Cilk, with explanations in Markdown format suitable for Hugo:
#include <cilk/cilk.h>
#include <iostream>
#include <string>
#include <vector>
#include <filesystem>
#include <fstream>
namespace fs = std::filesystem;
void check(const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
std::exit(1);
}
void createEmptyFile(const std::string& name) {
std::ofstream file(name);
if (!file) {
check(std::runtime_error("Failed to create file: " + name));
}
}
void visit(const fs::path& path, const fs::directory_entry& entry) {
std::cout << " " << path.string() << " " << fs::is_directory(entry) << std::endl;
}
int main() {
try {
// Create a new sub-directory in the current working directory.
fs::create_directory("subdir");
// When creating temporary directories, it's good practice to remove them after use.
// We'll use a try-catch block to ensure cleanup.
try {
createEmptyFile("subdir/file1");
// We can create a hierarchy of directories, including parents.
fs::create_directories("subdir/parent/child");
createEmptyFile("subdir/parent/file2");
createEmptyFile("subdir/parent/file3");
createEmptyFile("subdir/parent/child/file4");
// List directory contents
std::cout << "Listing subdir/parent" << std::endl;
for (const auto& entry : fs::directory_iterator("subdir/parent")) {
std::cout << " " << entry.path().filename().string() << " " << entry.is_directory() << std::endl;
}
// Change the current working directory
fs::current_path("subdir/parent/child");
// Now we'll see the contents of subdir/parent/child when listing the current directory.
std::cout << "Listing subdir/parent/child" << std::endl;
for (const auto& entry : fs::directory_iterator(".")) {
std::cout << " " << entry.path().filename().string() << " " << entry.is_directory() << std::endl;
}
// Change back to where we started
fs::current_path("../../..");
// We can also visit a directory recursively, including all its sub-directories.
std::cout << "Visiting subdir" << std::endl;
for (const auto& entry : fs::recursive_directory_iterator("subdir")) {
visit(entry.path(), entry);
}
}
catch (...) {
// Ensure cleanup even if an exception occurs
fs::remove_all("subdir");
throw;
}
// Clean up
fs::remove_all("subdir");
}
catch (const std::exception& e) {
check(e);
}
return 0;
}
This Cilk program demonstrates working with directories in the file system. Here’s a breakdown of the functionality:
We use the
<filesystem>
library, which provides similar functionality to Go’s file and directory operations.The
createEmptyFile
function creates an empty file with the given name.We create a directory structure using
fs::create_directory
andfs::create_directories
.We list directory contents using
fs::directory_iterator
.We change the current working directory using
fs::current_path
.We recursively visit all files and directories using
fs::recursive_directory_iterator
.We use a try-catch block to ensure cleanup of the created directory structure, even if an exception occurs.
To compile and run this program:
$ g++ -fcilkplus -std=c++17 directories.cpp -o directories
$ ./directories
This will output the directory structure and file information similar to the Go example.
Note that Cilk extends C++ with parallel programming constructs, but in this example, we’re not using any parallel features. The filesystem operations are performed sequentially.