This sample demonstrates fundamental file input and output operations on the Windows platform, covering various methods and best practices for handling file data.
Windows
File I/O
C++, Win32 API, C# (.NET)
Microsoft Developer Network (MSDN)
Efficiently managing files is a cornerstone of many applications. This sample provides code snippets and explanations to help you master reading from and writing to files using both low-level Win32 API functions and higher-level .NET framework classes.
This section showcases basic file operations using the Win32 API. It's essential for understanding the underlying mechanisms.
The following C++ code snippet demonstrates how to create a file, write some text to it, and close the handle.
#include <windows.h>
#include <iostream>
int main() {
HANDLE hFile = CreateFile(
L"example.txt", // File name
GENERIC_WRITE, // Desired access
0, // Share mode
NULL, // Security attributes
CREATE_ALWAYS, // Creation disposition
FILE_ATTRIBUTE_NORMAL, // Flags and attributes
NULL); // Template file
if (hFile == INVALID_HANDLE_VALUE) {
std::cerr << "Error creating file: " << GetLastError() << std::endl;
return 1;
}
const char* dataToWrite = "Hello, Windows File I/O!\r\n";
DWORD bytesWritten;
if (!WriteFile(
hFile, // File handle
dataToWrite, // Buffer
strlen(dataToWrite), // Number of bytes to write
&bytesWritten, // Number of bytes written
NULL)) { // Overlapped structure
std::cerr << "Error writing to file: " << GetLastError() << std::endl;
CloseHandle(hFile);
return 1;
}
CloseHandle(hFile);
std::cout << "Successfully wrote to example.txt" << std::endl;
return 0;
}
This example demonstrates reading data back from the file created above.
#include <windows.h>
#include <iostream>
#include <vector>
int main() {
HANDLE hFile = CreateFile(
L"example.txt", // File name
GENERIC_READ, // Desired access
FILE_SHARE_READ, // Share mode
NULL, // Security attributes
OPEN_EXISTING, // Creation disposition
FILE_ATTRIBUTE_NORMAL, // Flags and attributes
NULL); // Template file
if (hFile == INVALID_HANDLE_VALUE) {
std::cerr << "Error opening file: " << GetLastError() << std::endl;
return 1;
}
char buffer[256];
DWORD bytesRead;
std::vector<char> fileContent;
while (ReadFile(hFile, buffer, sizeof(buffer) - 1, &bytesRead, NULL) && bytesRead > 0) {
buffer[bytesRead] = '\0'; // Null-terminate the read chunk
fileContent.insert(fileContent.end(), buffer, buffer + bytesRead);
}
if (GetLastError() != ERROR_SUCCESS && GetLastError() != ERROR_HANDLE_EOF) {
std::cerr << "Error reading from file: " << GetLastError() << std::endl;
}
CloseHandle(hFile);
fileContent.push_back('\0'); // Null-terminate the entire content
std::cout << "File content:\n" << fileContent.data() << std::endl;
return 0;
}
The .NET Framework offers a more abstract and often simpler way to handle file operations.
using System;
using System.IO;
public class FileWriteExample {
public static void Main(string[] args) {
string filePath = "example_dotnet.txt";
try {
using (StreamWriter sw = new StreamWriter(filePath)) {
sw.WriteLine("Hello from .NET!");
sw.WriteLine("This is line two.");
}
Console.WriteLine($"Successfully wrote to {filePath}");
} catch (Exception ex) {
Console.WriteLine($"Error writing to file: {ex.Message}");
}
}
}
using System;
using System.IO;
public class FileReadExample {
public static void Main(string[] args) {
string filePath = "example_dotnet.txt";
try {
using (StreamReader sr = new StreamReader(filePath)) {
string line;
while ((line = sr.ReadLine()) != null) {
Console.WriteLine(line);
}
}
} catch (FileNotFoundException) {
Console.WriteLine($"Error: The file '{filePath}' was not found.");
} catch (Exception ex) {
Console.WriteLine($"Error reading from file: {ex.Message}");
}
}
}