🎯 Exemplos recomendados
Balanced sample collections from various categories for you to explore
Operações de Arquivos Windows - Exemplos C++
Exemplos abrangentes de operações de arquivo em C++ para plataforma Windows incluindo E/S de texto, cópia de arquivos e travessia de diretórios
💻 Operações de Leitura e Escrita de Arquivos de Texto cpp
🟢 simple
⭐⭐
Operações de arquivo de texto básicas e avançadas usando fluxos de arquivo C++ e APIs do Windows
⏱️ 20 min
🏷️ cpp, file, io, windows
Prerequisites:
Basic C++, File streams, STL containers
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sstream>
#include <filesystem>
#include <windows.h>
#include <codecvt>
#include <locale>
namespace fs = std::filesystem;
// 1. Basic text file writing
void WriteSimpleText()
{
std::cout << "=== Basic Text File Writing ===" << std::endl;
std::string filename = "simple.txt";
std::string content = "Hello, Windows! This is a simple text file written in C++.\n";
content += "This file contains multiple lines of text.\n";
content += "C++ file operations are powerful and flexible.\n";
std::ofstream outFile(filename);
if (outFile.is_open())
{
outFile << content;
outFile.close();
std::cout << "Successfully wrote to " << filename << std::endl;
}
else
{
std::cerr << "Error: Unable to open " << filename << " for writing" << std::endl;
}
}
// 2. Writing with different character encodings
void WriteWithEncoding()
{
std::cout << "\n=== Writing with UTF-8 Encoding ===" << std::endl;
std::string filename = "utf8_text.txt";
std::wstring content = L"Unicode text: 你好世界 🌍\n";
content += L"Special characters: é ñ ü ß\n";
content += L"Emojis: 😀 🎉 🚀\n";
// Convert wide string to UTF-8
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
std::string utf8Content = converter.to_bytes(content);
std::ofstream outFile(filename, std::ios::binary);
if (outFile.is_open())
{
outFile.write(utf8Content.c_str(), utf8Content.length());
outFile.close();
std::cout << "Successfully wrote UTF-8 text to " << filename << std::endl;
}
else
{
std::cerr << "Error: Unable to open " << filename << " for writing" << std::endl;
}
}
// 3. Appending to files
void AppendToFile()
{
std::cout << "\n=== Appending to Files ===" << std::endl;
std::string filename = "append_log.txt";
// Create initial file
std::ofstream outFile(filename);
if (outFile.is_open())
{
outFile << "Log started at: " << GetCurrentTimeString() << std::endl;
outFile.close();
std::cout << "Created initial log file: " << filename << std::endl;
}
// Append multiple entries
for (int i = 1; i <= 3; i++)
{
std::ofstream appendFile(filename, std::ios::app);
if (appendFile.is_open())
{
appendFile << "Log entry " << i << " at: " << GetCurrentTimeString() << std::endl;
appendFile.close();
}
}
std::cout << "Appended log entries to " << filename << std::endl;
}
// 4. Reading entire file
void ReadEntireFile()
{
std::cout << "\n=== Reading Entire File ===" << std::endl;
std::string filename = "simple.txt";
if (!fs::exists(filename))
{
std::cerr << "Error: File " << filename << " does not exist" << std::endl;
return;
}
std::ifstream inFile(filename);
if (inFile.is_open())
{
std::stringstream buffer;
buffer << inFile.rdbuf();
std::string content = buffer.str();
inFile.close();
std::cout << "File content (" << content.length() << " characters):" << std::endl;
std::cout << "---" << std::endl;
std::cout << content;
std::cout << "---" << std::endl;
}
else
{
std::cerr << "Error: Unable to open " << filename << " for reading" << std::endl;
}
}
// 5. Reading file line by line
void ReadFileByLines()
{
std::cout << "\n=== Reading File Line by Line ===" << std::endl;
std::string filename = "append_log.txt";
if (!fs::exists(filename))
{
std::cerr << "Error: File " << filename << " does not exist" << std::endl;
return;
}
std::ifstream inFile(filename);
if (inFile.is_open())
{
std::string line;
int lineNumber = 0;
std::cout << "Reading " << filename << " line by line:" << std::endl;
while (std::getline(inFile, line))
{
lineNumber++;
std::cout << "Line " << lineNumber << ": " << line << std::endl;
}
inFile.close();
std::cout << "Total lines read: " << lineNumber << std::endl;
}
else
{
std::cerr << "Error: Unable to open " << filename << " for reading" << std::endl;
}
}
// 6. Reading with error handling
void ReadWithErrorHandling()
{
std::cout << "\n=== Reading with Error Handling ===" << std::endl;
std::string filename = "nonexistent.txt";
try
{
std::ifstream inFile(filename);
if (!inFile)
{
throw std::runtime_error("Failed to open file: " + filename);
}
inFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
std::string content;
inFile >> content;
std::cout << "Successfully read: " << content << std::endl;
inFile.close();
}
catch (const std::exception& e)
{
std::cerr << "Error reading file: " << e.what() << std::endl;
}
}
// 7. Reading UTF-8 encoded files
void ReadUtf8File()
{
std::cout << "\n=== Reading UTF-8 File ===" << std::endl;
std::string filename = "utf8_text.txt";
if (!fs::exists(filename))
{
std::cerr << "Error: File " << filename << " does not exist" << std::endl;
return;
}
// Read as binary
std::ifstream inFile(filename, std::ios::binary);
if (inFile.is_open())
{
// Get file size
inFile.seekg(0, std::ios::end);
size_t fileSize = inFile.tellg();
inFile.seekg(0, std::ios::beg);
// Read file content
std::string content(fileSize, '\0');
inFile.read(&content[0], fileSize);
inFile.close();
// Convert UTF-8 to wide string for display
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
std::wstring wideContent;
try
{
wideContent = converter.from_bytes(content);
std::wcout << L"UTF-8 content: " << wideContent << std::endl;
}
catch (const std::exception& e)
{
std::cout << "Error converting UTF-8: " << e.what() << std::endl;
std::cout << "Raw UTF-8 bytes: " << content << std::endl;
}
}
else
{
std::cerr << "Error: Unable to open " << filename << " for reading" << std::endl;
}
}
// 8. File seeking and random access
void DemonstrateFileSeeking()
{
std::cout << "\n=== File Seeking and Random Access ===" << std::endl;
std::string filename = "random_access.txt";
// Create a file with structured data
{
std::ofstream outFile(filename);
if (outFile.is_open())
{
outFile << "Line 1: First line\n";
outFile << "Line 2: Second line\n";
outFile << "Line 3: Third line\n";
outFile << "Line 4: Fourth line\n";
outFile << "Line 5: Fifth line\n";
outFile.close();
}
}
// Demonstrate seeking
std::ifstream inFile(filename);
if (inFile.is_open())
{
// Get file size
inFile.seekg(0, std::ios::end);
long fileSize = inFile.tellg();
std::cout << "File size: " << fileSize << " bytes" << std::endl;
// Seek to middle
long middlePos = fileSize / 2;
inFile.seekg(middlePos);
std::string content;
std::getline(inFile, content);
std::cout << "Content from middle position: " << content << std::endl;
// Seek back to beginning
inFile.seekg(0, std::ios::beg);
std::getline(inFile, content);
std::cout << "First line: " << content << std::endl;
inFile.close();
}
}
// 9. Binary file operations
void BinaryFileOperations()
{
std::cout << "\n=== Binary File Operations ===" << std::endl;
std::string filename = "data.bin";
// Write binary data
{
std::ofstream outFile(filename, std::ios::binary);
if (outFile.is_open())
{
int intValue = 42;
double doubleValue = 3.14159;
std::string stringValue = "Binary Data";
outFile.write(reinterpret_cast<const char*>(&intValue), sizeof(intValue));
outFile.write(reinterpret_cast<const char*>(&doubleValue), sizeof(doubleValue));
// Write string with length prefix
size_t stringLength = stringValue.length();
outFile.write(reinterpret_cast<const char*>(&stringLength), sizeof(stringLength));
outFile.write(stringValue.c_str(), stringLength);
outFile.close();
std::cout << "Wrote binary data to " << filename << std::endl;
}
}
// Read binary data
{
std::ifstream inFile(filename, std::ios::binary);
if (inFile.is_open())
{
int intValue;
double doubleValue;
std::string stringValue;
inFile.read(reinterpret_cast<char*>(&intValue), sizeof(intValue));
inFile.read(reinterpret_cast<char*>(&doubleValue), sizeof(doubleValue));
size_t stringLength;
inFile.read(reinterpret_cast<char*>(&stringLength), sizeof(stringLength));
stringValue.resize(stringLength);
inFile.read(&stringValue[0], stringLength);
std::cout << "Read binary data:" << std::endl;
std::cout << " Integer: " << intValue << std::endl;
std::cout << " Double: " << doubleValue << std::endl;
std::cout << " String: " << stringValue << std::endl;
inFile.close();
}
}
}
// 10. High-performance file reading
void HighPerformanceFileReading()
{
std::cout << "\n=== High-Performance File Reading ===" << std::endl;
std::string filename = "large_file.txt";
// Create a large file
{
std::ofstream outFile(filename);
if (outFile.is_open())
{
for (int i = 1; i <= 1000; i++)
{
outFile << "Line " << i << ": This is a test line with some content for demonstration purposes. ";
outFile << "The line number is " << i << ". ";
outFile << "Random data: " << (rand() % 1000) << "\n";
}
outFile.close();
std::cout << "Created large file with 1000 lines" << std::endl;
}
}
// Read with buffering
{
auto start = std::chrono::high_resolution_clock::now();
std::ifstream inFile(filename);
inFile.rdbuf()->pubsetbuf(nullptr, 0); // No buffering for comparison
std::string content;
content.reserve(100000); // Pre-allocate memory
char buffer[8192];
while (inFile.read(buffer, sizeof(buffer)))
{
content.append(buffer, sizeof(buffer));
}
content.append(buffer, inFile.gcount());
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "Read " << content.length() << " characters in " << duration.count() << " ms" << std::endl;
inFile.close();
}
}
// Helper function to get current time string
std::string GetCurrentTimeString()
{
auto now = std::chrono::system_clock::now();
auto time_t = std::chrono::system_clock::to_time_t(now);
auto tm = *std::localtime(&time_t);
std::ostringstream oss;
oss << std::put_time(&tm, "%Y-%m-%d %H:%M:%S");
return oss.str();
}
// Cleanup function
void CleanupFiles()
{
std::cout << "\n=== Cleaning Up Files ===" << std::endl;
std::vector<std::string> filesToCleanup = {
"simple.txt", "utf8_text.txt", "append_log.txt",
"random_access.txt", "data.bin", "large_file.txt"
};
for (const auto& file : filesToCleanup)
{
try
{
if (fs::exists(file))
{
fs::remove(file);
std::cout << "Deleted: " << file << std::endl;
}
}
catch (const std::exception& e)
{
std::cerr << "Error deleting " << file << ": " << e.what() << std::endl;
}
}
}
int main()
{
std::cout << "=== C++ Windows File Operations Demo ===" << std::endl;
std::cout << "Demonstrating various file operations using C++\n" << std::endl;
try
{
// Basic file operations
WriteSimpleText();
ReadEntireFile();
// Encoding operations
WriteWithEncoding();
ReadUtf8File();
// Appending operations
AppendToFile();
ReadFileByLines();
// Error handling
ReadWithErrorHandling();
// Advanced operations
DemonstrateFileSeeking();
BinaryFileOperations();
HighPerformanceFileReading();
std::cout << "\nAll file operations completed successfully!" << std::endl;
}
catch (const std::exception& e)
{
std::cerr << "Unexpected error: " << e.what() << std::endl;
return 1;
}
// Clean up
CleanupFiles();
return 0;
}
💻 Operações de Cópia e Movimento de Arquivos cpp
🟡 intermediate
⭐⭐
Operações de cópia, movimento e lote de arquivos com rastreamento de progresso e tratamento de erros
⏱️ 25 min
🏷️ cpp, file, copy, windows
Prerequisites:
C++ file streams, STL filesystem, Windows API basics
#include <iostream>
#include <fstream>
#include <filesystem>
#include <vector>
#include <string>
#include <chrono>
#include <iomanip>
#include <windows.h>
#include <shlobj.h>
namespace fs = std::filesystem;
// Progress callback type
using ProgressCallback = std::function<void(long long, long long)>;
// 1. Simple file copy
bool SimpleFileCopy(const std::string& sourcePath, const std::string& destPath)
{
std::cout << "=== Simple File Copy ===" << std::endl;
std::cout << "Source: " << sourcePath << std::endl;
std::cout << "Destination: " << destPath << std::endl;
try
{
if (!fs::exists(sourcePath))
{
std::cerr << "Error: Source file does not exist" << std::endl;
return false;
}
// Create destination directory if it doesn't exist
fs::path destFilePath(destPath);
fs::create_directories(destFilePath.parent_path());
// Check if destination already exists
if (fs::exists(destPath))
{
std::cout << "Warning: Destination file already exists, overwriting..." << std::endl;
fs::remove(destPath);
}
// Copy file
fs::copy_file(sourcePath, destPath, fs::copy_options::overwrite_existing);
// Verify copy
if (fs::exists(destPath))
{
auto sourceSize = fs::file_size(sourcePath);
auto destSize = fs::file_size(destPath);
if (sourceSize == destSize)
{
std::cout << "File copied successfully! Size: " << sourceSize << " bytes" << std::endl;
return true;
}
else
{
std::cerr << "Error: File size mismatch after copy" << std::endl;
return false;
}
}
else
{
std::cerr << "Error: Destination file was not created" << std::endl;
return false;
}
}
catch (const std::exception& e)
{
std::cerr << "Error copying file: " << e.what() << std::endl;
return false;
}
}
// 2. File copy with progress tracking
bool CopyFileWithProgress(const std::string& sourcePath, const std::string& destPath, ProgressCallback progressCallback = nullptr)
{
std::cout << "\n=== File Copy with Progress ===" << std::endl;
try
{
if (!fs::exists(sourcePath))
{
std::cerr << "Error: Source file does not exist" << std::endl;
return false;
}
long long fileSize = fs::file_size(sourcePath);
std::cout << "Copying file: " << fileSize << " bytes" << std::endl;
// Create destination directory
fs::path destFilePath(destPath);
fs::create_directories(destFilePath.parent_path());
// Open source and destination files
std::ifstream source(sourcePath, std::ios::binary);
std::ofstream dest(destPath, std::ios::binary);
if (!source.is_open() || !dest.is_open())
{
std::cerr << "Error: Unable to open source or destination file" << std::endl;
return false;
}
// Copy with buffer and progress tracking
const int BUFFER_SIZE = 64 * 1024; // 64KB buffer
std::vector<char> buffer(BUFFER_SIZE);
long long totalCopied = 0;
auto startTime = std::chrono::high_resolution_clock::now();
while (source)
{
source.read(buffer.data(), BUFFER_SIZE);
std::streamsize bytesRead = source.gcount();
if (bytesRead > 0)
{
dest.write(buffer.data(), bytesRead);
totalCopied += bytesRead;
// Report progress
if (progressCallback)
{
progressCallback(totalCopied, fileSize);
}
// Show progress in console
double progress = (double)totalCopied / fileSize * 100.0;
std::cout << "\rProgress: " << std::fixed << std::setprecision(1) << progress << "% ("
<< totalCopied << "/" << fileSize << " bytes)";
std::cout.flush();
}
}
auto endTime = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime);
source.close();
dest.close();
std::cout << "\nCopy completed in " << duration.count() << " ms" << std::endl;
// Calculate speed
double speedMBps = (totalCopied / (1024.0 * 1024.0)) / (duration.count() / 1000.0);
std::cout << "Speed: " << std::fixed << std::setprecision(2) << speedMBps << " MB/s" << std::endl;
return true;
}
catch (const std::exception& e)
{
std::cerr << "\nError during copy: " << e.what() << std::endl;
return false;
}
}
// 3. Safe file move with rollback
bool SafeFileMove(const std::string& sourcePath, const std::string& destPath)
{
std::cout << "\n=== Safe File Move with Rollback ===" << std::endl;
std::string tempPath = destPath + ".tmp";
try
{
if (!fs::exists(sourcePath))
{
std::cerr << "Error: Source file does not exist" << std::endl;
return false;
}
if (fs::exists(destPath))
{
std::cerr << "Error: Destination file already exists" << std::endl;
return false;
}
// Create destination directory
fs::path destFilePath(destPath);
fs::create_directories(destFilePath.parent_path());
// Step 1: Copy to temporary location
std::cout << "Step 1: Copying to temporary location..." << std::endl;
if (!CopyFileWithProgress(sourcePath, tempPath))
{
return false;
}
// Step 2: Verify temporary copy
std::cout << "Step 2: Verifying temporary copy..." << std::endl;
if (!VerifyFileCopy(sourcePath, tempPath))
{
fs::remove(tempPath);
std::cerr << "Error: Temporary copy verification failed" << std::endl;
return false;
}
// Step 3: Move to final destination
std::cout << "Step 3: Moving to final destination..." << std::endl;
fs::rename(tempPath, destPath);
// Step 4: Remove original
std::cout << "Step 4: Removing original file..." << std::endl;
fs::remove(sourcePath);
std::cout << "File move completed successfully!" << std::endl;
return true;
}
catch (const std::exception& e)
{
std::cerr << "Error during move: " << e.what() << std::endl;
// Rollback: remove temporary file if it exists
if (fs::exists(tempPath))
{
fs::remove(tempPath);
std::cout << "Rollback: Removed temporary file" << std::endl;
}
return false;
}
}
// 4. Verify file copy integrity
bool VerifyFileCopy(const std::string& sourcePath, const std::string& destPath)
{
try
{
if (!fs::exists(sourcePath) || !fs::exists(destPath))
{
return false;
}
auto sourceSize = fs::file_size(sourcePath);
auto destSize = fs::file_size(destPath);
if (sourceSize != destSize)
{
std::cout << "Size mismatch: source=" << sourceSize << ", dest=" << destSize << std::endl;
return false;
}
// For small files, verify content
if (sourceSize < 1024 * 1024) // < 1MB
{
std::ifstream source(sourcePath, std::ios::binary);
std::ifstream dest(destPath, std::ios::binary);
if (!source.is_open() || !dest.is_open())
{
return false;
}
const int BUFFER_SIZE = 4096;
std::vector<char> sourceBuffer(BUFFER_SIZE);
std::vector<char> destBuffer(BUFFER_SIZE);
while (source && dest)
{
source.read(sourceBuffer.data(), BUFFER_SIZE);
dest.read(destBuffer.data(), BUFFER_SIZE);
if (source.gcount() != dest.gcount())
{
return false;
}
if (memcmp(sourceBuffer.data(), destBuffer.data(), source.gcount()) != 0)
{
std::cout << "Content mismatch detected" << std::endl;
return false;
}
}
}
return true;
}
catch (const std::exception& e)
{
std::cerr << "Error verifying file copy: " << e.what() << std::endl;
return false;
}
}
// 5. Batch file operations
void BatchFileOperations()
{
std::cout << "\n=== Batch File Operations ===" << std::endl;
// Create test files
std::string sourceDir = "batch_source";
std::string destDir = "batch_dest";
fs::create_directories(sourceDir);
fs::create_directories(destDir);
std::cout << "Creating test files..." << std::endl;
for (int i = 1; i <= 5; i++)
{
std::string filename = sourceDir + "/file" + std::to_string(i) + ".txt";
std::ofstream outFile(filename);
outFile << "This is test file " << i << std::endl;
outFile << "Content for batch operations demonstration." << std::endl;
for (int j = 1; j <= 10; j++)
{
outFile << "Line " << j << " of file " << i << std::endl;
}
outFile.close();
}
// Batch copy with progress tracking
std::cout << "\nStarting batch copy..." << std::endl;
int copiedFiles = 0;
int totalFiles = 0;
// Count total files
for (const auto& entry : fs::directory_iterator(sourceDir))
{
if (entry.is_regular_file())
{
totalFiles++;
}
}
// Copy files with progress
int fileIndex = 0;
for (const auto& entry : fs::directory_iterator(sourceDir))
{
if (entry.is_regular_file())
{
fileIndex++;
std::string sourcePath = entry.path().string();
std::string destPath = destDir + "/" + entry.path().filename().string();
std::cout << "\nCopying file " << fileIndex << "/" << totalFiles << ": " << entry.path().filename().string() << std::endl;
if (SimpleFileCopy(sourcePath, destPath))
{
copiedFiles++;
std::cout << "✓ Successfully copied" << std::endl;
}
else
{
std::cout << "✗ Failed to copy" << std::endl;
}
}
}
std::cout << "\nBatch copy completed: " << copiedFiles << "/" << totalFiles << " files copied" << std::endl;
}
// 6. Directory copy (recursive)
bool CopyDirectory(const std::string& sourceDir, const std::string& destDir, ProgressCallback progressCallback = nullptr)
{
std::cout << "\n=== Recursive Directory Copy ===" << std::endl;
try
{
if (!fs::exists(sourceDir))
{
std::cerr << "Error: Source directory does not exist" << std::endl;
return false;
}
// Create destination directory
fs::create_directories(destDir);
long long totalFiles = 0;
long long copiedFiles = 0;
// Count total files first
for (const auto& entry : fs::recursive_directory_iterator(sourceDir))
{
if (entry.is_regular_file())
{
totalFiles++;
}
}
std::cout << "Found " << totalFiles << " files to copy" << std::endl;
// Copy directory recursively
for (const auto& entry : fs::recursive_directory_iterator(sourceDir))
{
if (entry.is_regular_file())
{
std::string relativePath = fs::relative(entry.path(), sourceDir).string();
std::string destPath = destDir + "/" + relativePath;
std::cout << "Copying: " << relativePath << std::endl;
if (SimpleFileCopy(entry.path().string(), destPath))
{
copiedFiles++;
// Report progress
if (progressCallback)
{
progressCallback(copiedFiles, totalFiles);
}
}
}
else if (entry.is_directory())
{
// Create corresponding directory structure
std::string relativePath = fs::relative(entry.path(), sourceDir).string();
std::string destPath = destDir + "/" + relativePath;
fs::create_directories(destPath);
}
}
std::cout << "Directory copy completed: " << copiedFiles << " files copied" << std::endl;
return true;
}
catch (const std::exception& e)
{
std::cerr << "Error copying directory: " << e.what() << std::endl;
return false;
}
}
// 7. Windows-specific file operations using Win32 API
void WindowsFileOperations()
{
std::cout << "\n=== Windows-Specific File Operations ===" << std::endl;
std::string sourceFile = "win32_test.txt";
std::string destFile = "win32_copy.txt";
// Create test file
{
std::ofstream outFile(sourceFile);
outFile << "This file will be copied using Win32 API" << std::endl;
outFile << "Content for Win32 API demonstration" << std::endl;
}
// Use CopyFile Win32 API
BOOL result = CopyFileA(sourceFile.c_str(), destFile.c_str(), FALSE);
if (result)
{
std::cout << "Win32 CopyFile succeeded" << std::endl;
// Get file attributes
DWORD attributes = GetFileAttributesA(destFile.c_str());
if (attributes != INVALID_FILE_ATTRIBUTES)
{
std::cout << "File attributes: " << std::hex << attributes << std::dec << std::endl;
if (attributes & FILE_ATTRIBUTE_READONLY)
std::cout << " - Read-only" << std::endl;
if (attributes & FILE_ATTRIBUTE_HIDDEN)
std::cout << " - Hidden" << std::endl;
if (attributes & FILE_ATTRIBUTE_ARCHIVE)
std::cout << " - Archive" << std::endl;
}
}
else
{
DWORD error = GetLastError();
std::cerr << "Win32 CopyFile failed with error: " << error << std::endl;
}
}
// 8. File backup with timestamp
bool CreateBackupWithTimestamp(const std::string& filePath)
{
std::cout << "\n=== Creating Backup with Timestamp ===" << std::endl;
try
{
if (!fs::exists(filePath))
{
std::cerr << "Error: Source file does not exist" << std::endl;
return false;
}
// Create backup filename with timestamp
auto now = std::chrono::system_clock::now();
auto time_t = std::chrono::system_clock::to_time_t(now);
auto tm = *std::localtime(&time_t);
std::ostringstream oss;
oss << std::put_time(&tm, "%Y%m%d_%H%M%S");
fs::path sourcePath(filePath);
std::string backupPath = sourcePath.parent_path() /
(sourcePath.stem().string() + "_backup_" + oss.str() +
sourcePath.extension().string());
std::cout << "Creating backup: " << backupPath << std::endl;
if (SimpleFileCopy(filePath, backupPath))
{
std::cout << "Backup created successfully" << std::endl;
return true;
}
else
{
std::cerr << "Failed to create backup" << std::endl;
return false;
}
}
catch (const std::exception& e)
{
std::cerr << "Error creating backup: " << e.what() << std::endl;
return false;
}
}
// Cleanup function
void CleanupTestFiles()
{
std::cout << "\n=== Cleaning Up Test Files ===" << std::endl;
std::vector<std::string> filesToRemove = {
"simple.txt", "copy.txt", "move.txt", "win32_test.txt", "win32_copy.txt"
};
std::vector<std::string> dirsToRemove = {
"batch_source", "batch_dest", "recursive_source", "recursive_dest"
};
for (const auto& file : filesToRemove)
{
try
{
if (fs::exists(file))
{
fs::remove(file);
std::cout << "Removed file: " << file << std::endl;
}
}
catch (const std::exception& e)
{
std::cerr << "Error removing " << file << ": " << e.what() << std::endl;
}
}
for (const auto& dir : dirsToRemove)
{
try
{
if (fs::exists(dir))
{
fs::remove_all(dir);
std::cout << "Removed directory: " << dir << std::endl;
}
}
catch (const std::exception& e)
{
std::cerr << "Error removing " << dir << ": " << e.what() << std::endl;
}
}
}
// Progress callback function
void ShowProgress(long long current, long long total)
{
double progress = (double)current / total * 100.0;
std::cout << "\rProgress: " << std::fixed << std::setprecision(1) << progress << "%";
std::cout.flush();
}
int main()
{
std::cout << "=== C++ Windows File Copy/Move Operations ===" << std::endl;
std::cout << "Demonstrating various file copy and move operations\n" << std::endl;
try
{
// Create a test file first
std::string testFile = "simple.txt";
{
std::ofstream outFile(testFile);
outFile << "This is a test file for copy and move operations.\n";
outFile << "It contains multiple lines of text.\n";
outFile << "C++ file operations are efficient and reliable.\n";
outFile.close();
}
// Simple copy
SimpleFileCopy(testFile, "copy.txt");
// Copy with progress
CopyFileWithProgress(testFile, "large_copy.txt", ShowProgress);
// Safe move
SimpleFileCopy(testFile, "move.txt");
SafeFileMove("move.txt", "moved_file.txt");
// Batch operations
BatchFileOperations();
// Directory copy
fs::create_directories("recursive_source/subdir");
{
std::ofstream outFile("recursive_source/file1.txt");
outFile << "File in source directory";
outFile.close();
}
{
std::ofstream outFile("recursive_source/subdir/file2.txt");
outFile << "File in subdirectory";
outFile.close();
}
CopyDirectory("recursive_source", "recursive_dest");
// Windows-specific operations
WindowsFileOperations();
// Backup with timestamp
CreateBackupWithTimestamp(testFile);
std::cout << "\nAll file copy/move operations completed successfully!" << std::endl;
}
catch (const std::exception& e)
{
std::cerr << "Unexpected error: " << e.what() << std::endl;
return 1;
}
// Clean up
CleanupTestFiles();
return 0;
}
💻 Travessia de Diretórios e Listagem de Arquivos cpp
🟡 intermediate
⭐⭐⭐
Operações completas de diretórios incluindo travessia, busca de arquivos e análise estatística
⏱️ 30 min
🏷️ cpp, directory, filesystem, windows
Prerequisites:
C++17 filesystem, STL containers, Regular expressions
#include <iostream>
#include <filesystem>
#include <vector>
#include <string>
#include <algorithm>
#include <iomanip>
#include <chrono>
#include <regex>
#include <windows.h>
#include <lmcons.h>
namespace fs = std::filesystem;
// File information structure
struct FileInfo {
std::string name;
std::string path;
long long size;
std::string extension;
std::chrono::system_clock::time_point lastModified;
bool isDirectory;
std::string formatSize() const {
const char* units[] = {"B", "KB", "MB", "GB", "TB"};
double size = static_cast<double>(this->size);
int unitIndex = 0;
while (size >= 1024.0 && unitIndex < 4) {
size /= 1024.0;
unitIndex++;
}
std::ostringstream oss;
oss << std::fixed << std::setprecision(2) << size << " " << units[unitIndex];
return oss.str();
}
};
// 1. Basic directory listing
void ListDirectoryContents(const std::string& directoryPath)
{
std::cout << "=== Basic Directory Listing ===" << std::endl;
std::cout << "Directory: " << directoryPath << std::endl;
try {
if (!fs::exists(directoryPath)) {
std::cerr << "Error: Directory does not exist" << std::endl;
return;
}
if (!fs::is_directory(directoryPath)) {
std::cerr << "Error: Path is not a directory" << std::endl;
return;
}
std::vector<FileInfo> files;
std::vector<FileInfo> directories;
for (const auto& entry : fs::directory_iterator(directoryPath)) {
FileInfo info;
info.name = entry.path().filename().string();
info.path = entry.path().string();
info.isDirectory = entry.is_directory();
if (entry.is_regular_file()) {
info.size = entry.file_size();
info.extension = entry.path().extension().string();
info.lastModified = entry.last_write_time();
files.push_back(info);
} else if (entry.is_directory()) {
info.size = 0;
info.extension = "";
info.lastModified = entry.last_write_time();
directories.push_back(info);
}
}
// Sort alphabetically
std::sort(directories.begin(), directories.end(),
[](const FileInfo& a, const FileInfo& b) { return a.name < b.name; });
std::sort(files.begin(), files.end(),
[](const FileInfo& a, const FileInfo& b) { return a.name < b.name; });
// Display directories
std::cout << "\nDirectories (" << directories.size() << "):" << std::endl;
for (const auto& dir : directories) {
std::cout << " 📁 " << dir.name << "/" << std::endl;
}
// Display files
std::cout << "\nFiles (" << files.size() << "):" << std::endl;
for (const auto& file : files) {
std::cout << " 📄 " << std::left << std::setw(30) << file.name
<< std::setw(12) << file.formatSize()
<< " " << file.extension << std::endl;
}
} catch (const std::exception& e) {
std::cerr << "Error listing directory: " << e.what() << std::endl;
}
}
// 2. Recursive directory traversal
void RecursiveDirectoryTraversal(const std::string& rootPath, int maxDepth = 3, int currentDepth = 0)
{
std::cout << "\n=== Recursive Directory Traversal ===" << std::endl;
std::cout << "Root: " << rootPath << " (Max depth: " << maxDepth << ")" << std::endl;
try {
if (currentDepth >= maxDepth) {
std::cout << " (Max depth reached)" << std::endl;
return;
}
std::string indent(currentDepth * 2, ' ');
if (!fs::exists(rootPath) || !fs::is_directory(rootPath)) {
std::cerr << indent << "Error: Invalid directory path" << std::endl;
return;
}
std::cout << indent << "📁 " << fs::path(rootPath).filename().string() << "/" << std::endl;
for (const auto& entry : fs::directory_iterator(rootPath)) {
if (entry.is_directory()) {
// Recursively traverse subdirectory
RecursiveDirectoryTraversal(entry.path().string(), maxDepth, currentDepth + 1);
} else if (entry.is_regular_file()) {
std::cout << indent << " 📄 " << entry.path().filename().string()
<< " (" << entry.file_size() << " bytes)" << std::endl;
}
}
} catch (const std::exception& e) {
std::cerr << "Error during recursive traversal: " << e.what() << std::endl;
}
}
// 3. Calculate directory size
long long CalculateDirectorySize(const std::string& directoryPath)
{
std::cout << "\n=== Calculating Directory Size ===" << std::endl;
long long totalSize = 0;
int fileCount = 0;
int dirCount = 0;
try {
for (const auto& entry : fs::recursive_directory_iterator(directoryPath)) {
if (entry.is_regular_file()) {
totalSize += entry.file_size();
fileCount++;
} else if (entry.is_directory()) {
dirCount++;
}
}
std::cout << "Directory: " << directoryPath << std::endl;
std::cout << "Total size: " << totalSize << " bytes ("
<< formatBytes(totalSize) << ")" << std::endl;
std::cout << "Files: " << fileCount << std::endl;
std::cout << "Subdirectories: " << dirCount << std::endl;
} catch (const std::exception& e) {
std::cerr << "Error calculating directory size: " << e.what() << std::endl;
}
return totalSize;
}
// 4. Search files by pattern
std::vector<FileInfo> SearchFilesByPattern(const std::string& directoryPath, const std::string& pattern)
{
std::cout << "\n=== Search Files by Pattern ===" << std::endl;
std::cout << "Directory: " << directoryPath << std::endl;
std::cout << "Pattern: " << pattern << std::endl;
std::vector<FileInfo> results;
std::regex regexPattern(pattern, std::regex_constants::icase);
try {
for (const auto& entry : fs::recursive_directory_iterator(directoryPath)) {
if (entry.is_regular_file()) {
std::string filename = entry.path().filename().string();
if (std::regex_search(filename, regexPattern)) {
FileInfo info;
info.name = filename;
info.path = entry.path().string();
info.size = entry.file_size();
info.extension = entry.path().extension().string();
info.lastModified = entry.last_write_time();
info.isDirectory = false;
results.push_back(info);
}
}
}
// Sort by size (largest first)
std::sort(results.begin(), results.end(),
[](const FileInfo& a, const FileInfo& b) { return a.size > b.size; });
std::cout << "Found " << results.size() << " matching files:" << std::endl;
for (const auto& file : results) {
std::cout << " " << file.name << " (" << file.formatSize() << ")" << std::endl;
}
} catch (const std::exception& e) {
std::cerr << "Error searching files: " << e.what() << std::endl;
}
return results;
}
// 5. Find recently modified files
std::vector<FileInfo> FindRecentlyModifiedFiles(const std::string& directoryPath, int hoursAgo)
{
std::cout << "\n=== Find Recently Modified Files ===" << std::endl;
std::cout << "Directory: " << directoryPath << std::endl;
std::cout << "Time window: Last " << hoursAgo << " hours" << std::endl;
std::vector<FileInfo> recentFiles;
auto cutoffTime = std::chrono::system_clock::now() - std::chrono::hours(hoursAgo);
try {
for (const auto& entry : fs::recursive_directory_iterator(directoryPath)) {
if (entry.is_regular_file()) {
auto fileTime = std::chrono::clock_cast<std::chrono::system_clock>(entry.last_write_time());
if (fileTime > cutoffTime) {
FileInfo info;
info.name = entry.path().filename().string();
info.path = entry.path().string();
info.size = entry.file_size();
info.extension = entry.path().extension().string();
info.lastModified = entry.last_write_time();
info.isDirectory = false;
recentFiles.push_back(info);
}
}
}
// Sort by modification time (newest first)
std::sort(recentFiles.begin(), recentFiles.end(),
[](const FileInfo& a, const FileInfo& b) { return a.lastModified > b.lastModified; });
std::cout << "Found " << recentFiles.size() << " recently modified files:" << std::endl;
for (const auto& file : recentFiles) {
auto time_t = std::chrono::system_clock::to_time_t(file.lastModified);
auto tm = *std::localtime(&time_t);
std::cout << " " << file.name << " - " << std::put_time(&tm, "%Y-%m-%d %H:%M:%S")
<< " (" << file.formatSize() << ")" << std::endl;
}
} catch (const std::exception& e) {
std::cerr << "Error finding recently modified files: " << e.what() << std::endl;
}
return recentFiles;
}
// 6. Find duplicate files by size and content
void FindDuplicateFiles(const std::string& directoryPath)
{
std::cout << "\n=== Find Duplicate Files ===" << std::endl;
std::cout << "Directory: " << directoryPath << std::endl;
std::map<long long, std::vector<FileInfo>> filesBySize;
try {
// Group files by size
for (const auto& entry : fs::recursive_directory_iterator(directoryPath)) {
if (entry.is_regular_file()) {
FileInfo info;
info.name = entry.path().filename().string();
info.path = entry.path().string();
info.size = entry.file_size();
info.extension = entry.path().extension().string();
info.isDirectory = false;
filesBySize[info.size].push_back(info);
}
}
// Find potential duplicates (files with same size)
int potentialDuplicateGroups = 0;
int confirmedDuplicates = 0;
for (const auto& [size, files] : filesBySize) {
if (files.size() > 1) {
potentialDuplicateGroups++;
std::cout << "\nFiles with same size (" << files.size() << " files, "
<< formatBytes(size) << "):" << std::endl;
for (const auto& file : files) {
std::cout << " " << file.path << std::endl;
}
// For demonstration, we'll just count them as duplicates
// In a real implementation, you'd compare file hashes
if (files.size() > 1) {
confirmedDuplicates += files.size() - 1;
}
}
}
std::cout << "\nSummary:" << std::endl;
std::cout << "Potential duplicate groups: " << potentialDuplicateGroups << std::endl;
std::cout << "Files that could be removed: " << confirmedDuplicates << std::endl;
} catch (const std::exception& e) {
std::cerr << "Error finding duplicate files: " << e.what() << std::endl;
}
}
// 7. Directory statistics analysis
void AnalyzeDirectoryStatistics(const std::string& directoryPath)
{
std::cout << "\n=== Directory Statistics Analysis ===" << std::endl;
std::cout << "Analyzing: " << directoryPath << std::endl;
try {
std::map<std::string, int> extensionCounts;
std::map<std::string, long long> extensionSizes;
std::vector<long long> fileSizes;
int totalFiles = 0;
int totalDirectories = 0;
long long totalSize = 0;
// Collect statistics
for (const auto& entry : fs::recursive_directory_iterator(directoryPath)) {
if (entry.is_regular_file()) {
totalFiles++;
long long fileSize = entry.file_size();
totalSize += fileSize;
fileSizes.push_back(fileSize);
std::string ext = entry.path().extension().string();
if (ext.empty()) ext = "[no extension]";
extensionCounts[ext]++;
extensionSizes[ext] += fileSize;
} else if (entry.is_directory()) {
totalDirectories++;
}
}
// Calculate statistics
std::sort(fileSizes.begin(), fileSizes.end());
long long medianSize = 0;
if (!fileSizes.empty()) {
size_t midIndex = fileSizes.size() / 2;
medianSize = fileSizes[midIndex];
}
// Display results
std::cout << "\nOverall Statistics:" << std::endl;
std::cout << " Total files: " << totalFiles << std::endl;
std::cout << " Total directories: " << totalDirectories << std::endl;
std::cout << " Total size: " << formatBytes(totalSize) << std::endl;
if (!fileSizes.empty()) {
std::cout << " Smallest file: " << formatBytes(fileSizes[0]) << std::endl;
std::cout << " Largest file: " << formatBytes(fileSizes.back()) << std::endl;
std::cout << " Median file size: " << formatBytes(medianSize) << std::endl;
if (totalFiles > 0) {
std::cout << " Average file size: " << formatBytes(totalSize / totalFiles) << std::endl;
}
}
// Display file type statistics
std::cout << "\nFile Types:" << std::endl;
// Sort by size (largest first)
std::vector<std::pair<std::string, long long>> sortedExtensions(
extensionSizes.begin(), extensionSizes.end());
std::sort(sortedExtensions.begin(), sortedExtensions.end(),
[](const auto& a, const auto& b) { return a.second > b.second; });
for (const auto& [ext, size] : sortedExtensions) {
int count = extensionCounts[ext];
double percentage = totalFiles > 0 ? (double)count / totalFiles * 100.0 : 0.0;
std::cout << " " << std::setw(15) << std::left << ext << ": "
<< std::setw(6) << count << " files, "
<< std::setw(12) << formatBytes(size) << " "
<< "(" << std::fixed << std::setprecision(1) << percentage << "%)" << std::endl;
}
} catch (const std::exception& e) {
std::cerr << "Error analyzing directory: " << e.what() << std::endl;
}
}
// 8. Search files by content pattern (simple text search)
void SearchFilesByContent(const std::string& directoryPath, const std::string& searchTerm)
{
std::cout << "\n=== Search Files by Content ===" << std::endl;
std::cout << "Directory: " << directoryPath << std::endl;
std::cout << "Search term: '" << searchTerm << "'" << std::endl;
int filesSearched = 0;
int filesWithMatches = 0;
int totalMatches = 0;
try {
std::vector<std::string> textExtensions = {".txt", ".log", ".cpp", ".h", ".html", ".css", ".js", ".xml", ".json"};
for (const auto& entry : fs::recursive_directory_iterator(directoryPath)) {
if (entry.is_regular_file()) {
std::string ext = entry.path().extension().string();
// Check if it's likely a text file
if (std::find(textExtensions.begin(), textExtensions.end(), ext) != textExtensions.end() ||
ext.empty()) {
filesSearched++;
// Search in file (simple line-by-line search)
std::ifstream file(entry.path());
if (file.is_open()) {
std::string line;
int lineNum = 0;
bool fileHasMatch = false;
while (std::getline(file, line)) {
lineNum++;
if (line.find(searchTerm) != std::string::npos) {
if (!fileHasMatch) {
std::cout << "\n📄 " << entry.path().filename().string() << std::endl;
fileHasMatch = true;
filesWithMatches++;
}
std::cout << " Line " << lineNum << ": " << line << std::endl;
totalMatches++;
}
}
file.close();
}
}
}
}
std::cout << "\nSearch Results:" << std::endl;
std::cout << " Files searched: " << filesSearched << std::endl;
std::cout << " Files with matches: " << filesWithMatches << std::endl;
std::cout << " Total matches: " << totalMatches << std::endl;
} catch (const std::exception& e) {
std::cerr << "Error searching file contents: " << e.what() << std::endl;
}
}
// Helper function to format bytes
std::string formatBytes(long long bytes) {
const char* units[] = {"B", "KB", "MB", "GB", "TB"};
double size = static_cast<double>(bytes);
int unitIndex = 0;
while (size >= 1024.0 && unitIndex < 4) {
size /= 1024.0;
unitIndex++;
}
std::ostringstream oss;
oss << std::fixed << std::setprecision(2) << size << " " << units[unitIndex];
return oss.str();
}
// Create test directory structure for demonstration
void CreateTestDirectoryStructure()
{
std::cout << "Creating test directory structure..." << std::endl;
// Create directories
fs::create_directories("test_root/docs");
fs::create_directories("test_root/images");
fs::create_directories("test_root/code");
fs::create_directories("test_root/code/subdir");
// Create test files
std::ofstream("test_root/readme.txt") << "This is a README file\n";
std::ofstream("test_root/docs/manual.txt") << "User manual content\n";
std::ofstream("test_root/docs/guide.txt") << "User guide content\n";
std::ofstream("test_root/image1.png") << "Fake image content\n";
std::ofstream("test_root/images/photo.jpg") << "Fake photo content\n";
std::ofstream("test_root/main.cpp") << "#include <iostream>\nint main() { return 0; }\n";
std::ofstream("test_root/code/helper.h") << "#pragma once\n";
std::ofstream("test_root/code/subdir/utility.cpp") << "// Utility functions\n";
std::ofstream("test_root/config.json") << "{\"version\": \"1.0\"}";
std::ofstream("test_root/style.css") << "body { margin: 0; }\n";
std::ofstream("test_root/script.js") << "console.log('Hello');\n";
// Create some larger files
for (int i = 0; i < 100; i++) {
std::ofstream file("test_root/large_file_" + std::to_string(i) + ".txt");
file << "This is large file " << i << "\n";
for (int j = 0; j < 100; j++) {
file << "Line " << j << " with some content\n";
}
}
std::cout << "Test directory structure created." << std::endl;
}
// Cleanup test directory
void CleanupTestDirectory()
{
try {
if (fs::exists("test_root")) {
fs::remove_all("test_root");
std::cout << "\nTest directory cleaned up." << std::endl;
}
} catch (const std::exception& e) {
std::cerr << "Error cleaning up test directory: " << e.what() << std::endl;
}
}
int main()
{
std::cout << "=== C++ Directory Traversal and File Listing ===" << std::endl;
std::cout << "Demonstrating various directory operations\n" << std::endl;
// Create test structure
CreateTestDirectoryStructure();
try {
// Perform various directory operations
ListDirectoryContents("test_root");
RecursiveDirectoryTraversal("test_root", 2);
CalculateDirectorySize("test_root");
SearchFilesByPattern("test_root", R"(.*.txt)");
SearchFilesByPattern("test_root", R"(.*.cpp)");
FindRecentlyModifiedFiles("test_root", 1);
FindDuplicateFiles("test_root");
AnalyzeDirectoryStatistics("test_root");
SearchFilesByContent("test_root", "include");
std::cout << "\nAll directory operations completed successfully!" << std::endl;
} catch (const std::exception& e) {
std::cerr << "Unexpected error: " << e.what() << std::endl;
return 1;
}
// Clean up
CleanupTestDirectory();
return 0;
}