Reading and Writing Files in Windows

This sample demonstrates fundamental file input and output operations on the Windows platform, covering various methods and best practices for handling file data.

Platform

Windows

Category

File I/O

Technologies

C++, Win32 API, C# (.NET)

Author

Microsoft Developer Network (MSDN)

Introduction

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.

Core Concepts

Win32 API Example (C++)

This section showcases basic file operations using the Win32 API. It's essential for understanding the underlying mechanisms.

Writing to a File

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; }

Reading from a File

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; }

.NET Framework Example (C#)

The .NET Framework offers a more abstract and often simpler way to handle file operations.

Writing to a File with `StreamWriter`

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}"); } } }

Reading from a File with `StreamReader`

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}"); } } }

Additional Resources