C# – File Handling, Streams & I/O Operations
1. How do you read and write files in C#?
C# provides classes in the System.IO namespace to create, read, write, append, and delete files.
The File class is commonly used for simple file operations.
Example
using System.IO;
// Write to a file
File.WriteAllText("employee.txt", "Hello Syed");
// Read from a file
string content = File.ReadAllText("employee.txt");
Console.WriteLine(content);
// Append text
File.AppendAllText("employee.txt", "\nWelcome");
// Check file existence
bool exists = File.Exists("employee.txt");
Output:
Hello Syed
Explanation
-
WriteAllText()creates or overwrites a file. -
ReadAllText()reads the complete file content. -
AppendAllText()adds content without deleting existing data. -
Exists()checks whether a file exists.
Key Points
-
System.IOprovides file-handling classes. -
Filecontains static methods. -
File.ReadAllLines()reads all lines into an array. -
File.ReadLines()supports lazy, line-by-line reading. -
Use asynchronous methods for non-blocking I/O.
2. What is the difference between File, FileInfo, StreamReader, and StreamWriter?
All four are used for file operations, but their purposes differ.
Comparison
|
Class |
Purpose |
Method Type |
|---|---|---|
|
|
Simple file operations |
Static |
|
|
File operations and metadata |
Instance |
|
|
Read text from a stream |
Instance |
|
|
Write text to a stream |
Instance |
Example
using System.IO;
// File
File.WriteAllText("test.txt", "Hello");
// FileInfo
FileInfo info = new FileInfo("test.txt");
Console.WriteLine(info.Length);
// StreamReader
using (StreamReader reader = new StreamReader("test.txt"))
{
Console.WriteLine(reader.ReadLine());
}
// StreamWriter
using (StreamWriter writer = new StreamWriter("test.txt", append: true))
{
writer.WriteLine("Welcome");
}
Explanation
-
Fileis convenient for one-time file operations. -
FileInfoprovides properties such asLength,Name, andCreationTime. -
StreamReaderreads text sequentially. -
StreamWriterwrites text sequentially.
Key Points
-
Use
Filefor simple read/write operations. -
Use
FileInfowhen working repeatedly with file metadata. -
Use
StreamReaderfor sequential text reading. -
Use
StreamWriterfor sequential text writing. -
Dispose readers and writers using
using.
3. What is the difference between synchronous and asynchronous file operations?
Synchronous file operations block the calling thread until the operation completes.
Asynchronous file operations allow the calling thread to perform other work while waiting for I/O completion.
Example
Synchronous:
string content = File.ReadAllText("employee.txt");
Console.WriteLine(content);
Asynchronous:
string content =
await File.ReadAllTextAsync("employee.txt");
Console.WriteLine(content);
Flow
Synchronous
-----------
Thread
|
+-- Start File Reading
|
+-- Wait (Blocked)
|
+-- Reading Completed
|
+-- Continue Execution
Asynchronous
------------
Thread
|
+-- Start File Reading
|
+-- Await (Thread Not Blocked)
|
+-- I/O Completes
|
+-- Resume Execution
Comparison
|
Synchronous |
Asynchronous |
|---|---|
|
Blocks calling thread |
Does not block while awaiting I/O |
|
Uses methods like |
Uses methods like |
|
Simple execution flow |
Uses |
|
Suitable for small console utilities |
Useful for scalable Web APIs |
Key Points
-
Async I/O improves scalability when threads would otherwise wait.
-
Async does not necessarily create a new thread.
-
Async is not automatically faster for every individual file operation.
-
Prefer async file operations in ASP.NET Core when handling significant I/O.
4. What is a Stream in C#?
A Stream represents a sequence of bytes that can be read from or written to a source such as a file, memory, or network connection.
Stream is an abstract class in System.IO.
Common Stream Types
|
Stream |
Purpose |
|---|---|
|
|
Reads/writes file bytes |
|
|
Reads/writes bytes in memory |
|
|
Transfers bytes over a network |
|
|
Adds buffering to another stream |
Example
using System.IO;
using System.Text;
using FileStream fs = new FileStream(
"test.txt",
FileMode.Create,
FileAccess.Write
);
byte[] data = Encoding.UTF8.GetBytes("Hello Syed");
fs.Write(data, 0, data.Length);
Explanation
-
FileStreamopens or creates a file. -
Encoding.UTF8.GetBytes()converts text into bytes. -
Write()writes the bytes to the file. -
usingautomatically disposes the stream.
Flow
C# Application
|
v
Stream
|
+-- FileStream -> Disk
|
+-- MemoryStream -> RAM
|
+-- NetworkStream -> Network
Key Points
-
Streams work with bytes.
-
Streams support reading, writing, and sometimes seeking.
-
StreamReaderandStreamWriterhandle text encoding. -
Streams implement
IDisposable. -
Streams are commonly used for file uploads and downloads.
5. What is the difference between FileStream and MemoryStream?
Both inherit from Stream, but they use different storage locations.
Comparison
|
FileStream |
MemoryStream |
|---|---|
|
Reads/writes files |
Reads/writes memory buffers |
|
Uses disk-backed storage |
Uses RAM |
|
Requires file access |
Does not require a physical file |
|
Useful for large file operations |
Useful for temporary in-memory data |
|
Subject to disk I/O |
Avoids disk I/O |
Example
FileStream:
using FileStream fs = new FileStream(
"test.txt",
FileMode.Create
);
byte[] data = { 65, 66, 67 };
fs.Write(data, 0, data.Length);
MemoryStream:
using MemoryStream ms = new MemoryStream();
byte[] data = { 65, 66, 67 };
ms.Write(data, 0, data.Length);
Console.WriteLine(ms.Length);
Output:
3
Explanation
-
FileStreamwrites bytes totest.txt. -
MemoryStreamstores bytes in memory. -
Both use the same
Write()method because they inherit fromStream.
Key Points
-
FileStreamis suitable for disk-based operations. -
MemoryStreamis suitable for temporary data processing. -
MemoryStreamcan consume significant RAM for large data. -
Both support asynchronous operations through the Stream API.
6. How do you process large files without loading them entirely into memory?
For large files, use streaming instead of reading the entire file into memory.
Common approaches include StreamReader, File.ReadLines(), and FileStream.
Example
Suppose employees.txt contains one employee name per line.
using System.IO;
using StreamReader reader =
new StreamReader("employees.txt");
string? line;
while ((line = reader.ReadLine()) != null)
{
Console.WriteLine(line);
}
Explanation
-
StreamReaderreads one line at a time. -
The entire file is not loaded into memory.
-
Each line is processed before reading the next.
-
Memory consumption stays relatively low, assuming individual lines are reasonably sized.
Flow
Large File (2 GB)
|
v
StreamReader
|
+-- Read Line 1 -> Process
|
+-- Read Line 2 -> Process
|
+-- Read Line 3 -> Process
|
+-- Continue Until EOF
Alternative
foreach (string line in File.ReadLines("employees.txt"))
{
Console.WriteLine(line);
}
File.ReadLines() lazily reads lines instead of loading all lines at once.
Key Points
-
Avoid
ReadAllText()for very large files. -
Use
StreamReaderfor sequential text processing. -
Use
File.ReadLines()for simpler line-by-line processing. -
Use
FileStreamwith fixed-size buffers for large binary files. -
In Web APIs, stream large uploads and downloads where practical.
7. How do you handle file access exceptions and resource disposal?
File operations may fail because of missing files, permission issues, locked files, or disk errors.
Use try-catch to handle exceptions and using to release resources.
Example
using System;
using System.IO;
try
{
using StreamReader reader =
new StreamReader("employee.txt");
string content = reader.ReadToEnd();
Console.WriteLine(content);
}
catch (FileNotFoundException)
{
Console.WriteLine("File not found.");
}
catch (UnauthorizedAccessException)
{
Console.WriteLine("Access denied.");
}
catch (IOException ex)
{
Console.WriteLine($"I/O error: {ex.Message}");
}
Explanation
-
The
tryblock performs file reading. -
FileNotFoundExceptionhandles missing files. -
UnauthorizedAccessExceptionhandles permission problems. -
IOExceptionhandles other I/O failures. -
usingensures the reader is disposed even if an exception occurs.
Resource Disposal Flow
Open File
|
v
Read / Write
|
+-- Success ------+
| |
+-- Exception ----+
|
v
Dispose()
|
v
Release Resources
Common File Exceptions
|
Exception |
Reason |
|---|---|
|
|
File does not exist |
|
|
Directory does not exist |
|
|
Insufficient permissions |
|
|
I/O failure or sharing conflict |
|
|
File path exceeds supported limits |
Key Points
-
Use
try-catchfor expected file access failures. -
Catch specific exceptions before general exceptions.
-
Use
usingfor automatic resource disposal. -
Use
await usingwhen asynchronous disposal is appropriate. -
Avoid leaving files or streams open unnecessarily.
-
Log exceptions in production applications.
Quick Interview Revision
|
Question |
Important Answer |
|---|---|
|
File Handling |
Use |
|
|
Static methods vs instance methods and metadata |
|
|
Read text vs write text |
|
Sync vs Async |
Blocking vs non-blocking I/O |
|
Stream |
Abstraction for reading/writing bytes |
|
|
Disk-backed vs memory-backed storage |
|
Large File Processing |
Read line-by-line or in fixed-size chunks |
|
Exception Handling |
Use specific |
|
Resource Disposal |
Use |
Interview Tip for .NET Tech Lead: Be prepared to explain how you would handle a 2 GB CSV file upload in ASP.NET Core Web API. A strong answer should mention streaming, buffered processing, asynchronous I/O, validation, resource disposal, and avoiding unnecessary memory allocation.