Working with files is a practical, everyday skill for any C# developer, whether you’re saving logs, reading configuration data, or building small utilities.
This collection of 30 C# file handling exercises covers the System.IO namespace in depth, from writing and reading text files to appending logs and checking file existence safely.
Each exercise includes a Practice Problem, Purpose, Hint, and a full Solution with Explanation, so you understand how to work with files without unexpected crashes.
Also, See: C# Exercises with 22 topic-wise sets and 620+ practice questions.
What You’ll Practice
- Writing Files:
File.WriteAllText()andFile.AppendAllText(). - Reading Files:
File.ReadAllText()andFile.ReadAllLines(). - Safety Checks:
File.Exists()and handling missing files gracefully. - Practical Use: Building simple logs, diaries, and file-based utilities.
+ Table Of Contents (30 Exercises)
Table of contents
- Exercise 1: Create a Blank File
- Exercise 2: Write Text to File
- Exercise 3: Read Entire File
- Exercise 4: Append Text
- Exercise 5: Delete a File
- Exercise 6: Read File Line-by-Line
- Exercise 7: Copy a File
- Exercise 8: Move/Rename a File
- Exercise 9: Count Lines in a File
- Exercise 10: Write Array of Strings
- Exercise 11: Find Specific Word
- Exercise 12: CSV Data Parser
- Exercise 13: Count Characters and Words
- Exercise 14: Directory File Lister
- Exercise 15: Filter Lines
- Exercise 16: Binary Writer/Reader
- Exercise 17: Uppercase Converter
- Exercise 18: Find the Largest File
- Exercise 19: File Properties Viewer
- Exercise 20: Remove Empty Lines
- Exercise 21: Create Subdirectories
- Exercise 22: Reverse File Content
- Exercise 23: Search Files by Extension
- Exercise 24: Exception Safe Reader
- Exercise 25: Merge Two Files
- Exercise 29: Secure Object Serialization Engine
- Exercise 30: Memory-Mapped File Processor
Exercise 1: Create a Blank File
Practice Problem: Write a program to check if a specific file exists, and if not, create a blank text file.
Purpose: This exercise helps you practice using File.Exists to check for a file’s presence before creating it, and File.Create to generate an empty file safely without overwriting existing data.
Given Input: filePath = "notes.txt" (assumed not to exist yet)
Expected Output: File created: notes.txt
▼ Hint
- Use
File.Exists(path)to check whether the file is already there. - Only call the creation method if that check returns false.
- Use
File.Create(path)to make a new, empty file at the given path. - Close or dispose of the returned stream immediately, since you don’t need to write to it yet.
▼ Solution & Explanation
Explanation:
File.Exists(filePath): Checks the file system for a file at the given path without opening or modifying it.if (!File.Exists(filePath)): Only proceeds with creation when the file is genuinely missing, preventing an existing file from being wiped out.using (File.Create(filePath)) { }: Creates the file and immediately closes the stream, since the empty block leaves the file with no content.- Running it again: A second run finds the file already there and prints the “already exists” message instead of recreating it.
Exercise 2: Write Text to File
Practice Problem: Take a name and an age, and write this information into a user.txt file.
Purpose: This exercise helps you practice writing formatted text to a new file using File.WriteAllText, which creates the file if needed or overwrites it if it already exists.
Given Input: name = "Alex", age = 28
Expected Output: user.txt is created containing Name: Alex, Age: 28, and the console prints Saved to user.txt.
▼ Hint
- Combine the name and age into a single formatted string before writing anything.
- Use
File.WriteAllText(path, content)to write that string to a file in one call. - Remember that
WriteAllTextreplaces the file’s entire content if it already exists. - Read the file back afterward if you want to verify exactly what was written.
▼ Solution & Explanation
Explanation:
string content = "Name: " + name + ", Age: " + age: Builds the full line of text before writing it, so the file receives one complete string.File.WriteAllText("user.txt", content): Createsuser.txtif it doesn’t exist, or overwrites it completely if it does.- Single method call: Handles opening the file, writing the text, and closing the file automatically, without needing a
usingblock. - Fixed sample values:
nameandageare hardcoded here so the example produces the same output every time; in an interactive console app these would typically come fromConsole.ReadLine()instead.
Exercise 3: Read Entire File
Practice Problem: Read and display the entire content of an existing text file to the console using File.ReadAllText.
Purpose: This exercise helps you practice reading a file’s full contents into a single string in one call, suitable for small to medium sized files.
Given Input: A file notes.txt containing Hello from the file!
Expected Output: Hello from the file!
▼ Hint
- Use
File.ReadAllText(path)to load the entire file into a single string. - Store the returned string in a variable before printing it.
- Print that variable to the console using
Console.WriteLine. - Consider checking
File.Existsfirst if the file might not be there.
▼ Solution & Explanation
Explanation:
File.ReadAllText("notes.txt"): Opens the file, reads every character into memory, and closes the file automatically, returning the result as a single string.string content: Stores the file’s contents so it can be used or printed as many times as needed.Console.WriteLine(content): Prints the entire file to the console in one statement.- Suitability:
ReadAllTextworks well for small files, but very large files are usually better handled line-by-line to avoid loading everything into memory at once.
Exercise 4: Append Text
Practice Problem: Open an existing text file and append a timestamped log entry (e.g., “Log entry at [Current Time]”) to the end of it.
Purpose: This exercise helps you practice using File.AppendAllText to add new content to the end of a file without overwriting what’s already there.
Given Input: An existing file log.txt with previous entries, plus the current system timestamp for the new entry.
Expected Output: Log entry appended
▼ Hint
- Build the log line as a string that includes a timestamp value.
- Use
File.AppendAllText(path, text)to add that line to the end of the file. - Include a newline character at the end of the string, since
AppendAllTextdoesn’t add one automatically. - Run the program more than once to see multiple log entries accumulate in the same file.
▼ Solution & Explanation
Explanation:
DateTime.Now: Captures the current date and time, giving each log entry a unique timestamp.Environment.NewLine: Appended manually to the end of the entry, sinceAppendAllTextwrites exactly the string it’s given without adding a line break.File.AppendAllText("log.txt", logEntry): Adds the new entry after the file’s existing content instead of replacing it.- Repeated runs: Each execution adds one more line to
log.txt, building up a running history of entries over time.
Exercise 5: Delete a File
Practice Problem: Write a program that safely checks for the presence of a file and deletes it, handling the scenario where the file does not exist.
Purpose: This exercise helps you practice guarding a delete operation with an existence check, keeping the two possible outcomes explicit instead of assuming the file is always there.
Given Input: filePath = "temp.txt", which may or may not exist.
Expected Output: File deleted: temp.txt if the file existed, or File not found: temp.txt otherwise.
▼ Hint
- Check
File.Exists(path)before attempting the delete. - Call
File.Delete(path)only inside that condition. - Print a message confirming the deletion when the file was found.
- Print a different message when the file wasn’t there to begin with.
▼ Solution & Explanation
Explanation:
File.Exists(filePath): Confirms the file is actually there before any deletion is attempted.File.Delete(filePath): Removes the file from disk, but only runs inside the branch where the existence check succeeded.- Guarding the delete: Checking first keeps the intent of the code explicit and makes the two outcomes easy to branch on cleanly.
- Two distinct messages: The program reports a different outcome depending on whether the file was actually present, rather than assuming success.
Exercise 6: Read File Line-by-Line
Practice Problem: Read a text file line-by-line using a loop and display each line prefixed with its line number.
Purpose: This exercise helps you practice reading a file into an array of lines with File.ReadAllLines, and processing each line individually rather than as one large string.
Given Input: A file poem.txt containing three lines: “Roses are red”, “Violets are blue”, “Sugar is sweet”.
Expected Output:
1: Roses are red 2: Violets are blue 3: Sugar is sweet
▼ Hint
- Use
File.ReadAllLines(path)to load the file as an array of strings, one per line. - Loop through that array using a
forloop so you have access to the index. - Add 1 to the index when printing, since line numbers usually start at 1 rather than 0.
- Print each line together with its number using string concatenation.
▼ Solution & Explanation
Explanation:
File.ReadAllLines("poem.txt"): Reads the entire file and splits it into an array of strings, one element per line.for (int i = 0; i < lines.Length; i++): Loops through every line using its index, which is needed to build the line number.(i + 1): Converts the zero-based array index into a one-based line number that matches how lines are usually counted.lines[i]: Accesses the actual text of the current line to print alongside its number.
Exercise 7: Copy a File
Practice Problem: Copy a specific file from a source directory to a backup directory, overwriting the destination file if it already exists.
Purpose: This exercise helps you practice using File.Copy with its overwrite parameter, avoiding an exception when the destination file already exists from a previous run.
Given Input: sourcePath = "source/report.txt", destinationPath = "backup/report.txt"
Expected Output: File copied to backup/report.txt
▼ Hint
- Use
File.Copy(sourcePath, destinationPath, overwrite)with three arguments. - Pass
trueas the overwrite argument so a previous copy at the destination gets replaced instead of throwing an exception. - Make sure the destination directory already exists before copying, since
File.Copydoes not create folders. - Print a confirmation message once the copy completes successfully.
▼ Solution & Explanation
Explanation:
File.Copy(sourcePath, destinationPath, true): Copies the file’s contents to the new location, with the third argument allowing it to overwrite an existing file at that destination.- Passing
truefor overwrite: Without it, callingFile.Copyon a destination that already exists throws anIOException. - Directory assumption:
File.Copyexpects the destination folder to already exist; it does not create intermediate directories automatically. - Confirmation message: Printed only after the copy operation completes without throwing an exception.
Exercise 8: Move/Rename a File
Practice Problem: Take an existing file and move it to a different directory or rename it within the same folder.
Purpose: This exercise helps you practice using File.Move to relocate or rename a file in a single operation, understanding that .NET treats renaming as simply moving a file to a new path within the same folder.
Given Input: sourcePath = "draft.txt", destinationPath = "archive/draft_final.txt"
Expected Output: File moved to archive/draft_final.txt
▼ Hint
- Use
File.Move(sourcePath, destinationPath)to relocate the file. - Make sure the destination folder already exists, since
File.Movedoes not create directories. - Remember that renaming a file is just a special case of moving it to a new path in the same folder.
- Check that the destination path doesn’t already point to an existing file, since
File.Movethrows if it does.
▼ Solution & Explanation
Explanation:
File.Move(sourcePath, destinationPath): Relocates the file from its original path to the new one, removing it from the source location entirely.- Renaming as a special case: Giving a destination path in the same folder but with a different file name effectively renames the file.
- Destination folder requirement: The
archivefolder must already exist, sinceFile.Move, likeFile.Copy, does not create missing directories. - Existing destination file: If a file already exists at
destinationPath,File.Movethrows an exception instead of overwriting it.
Exercise 9: Count Lines in a File
Practice Problem: Read a text file and return the total count of lines it contains.
Purpose: This exercise helps you practice counting the elements in an array produced by File.ReadAllLines, a quick way to measure a file’s length in lines without processing its content further.
Given Input: A file poem.txt containing 3 lines.
Expected Output: Total lines: 3
▼ Hint
- Use
File.ReadAllLines(path)to split the file into an array of individual lines. - Use the array’s
Lengthproperty to get the total number of lines directly. - Print the count using a descriptive message.
- Consider that an empty file still returns an array, just with a length of zero.
▼ Solution & Explanation
Explanation:
File.ReadAllLines("poem.txt"): Reads the file and splits it into an array, with each element representing one line.lines.Length: Gives the exact count of lines without needing to loop through the array manually.- Simplicity: This approach relies entirely on the array’s built-in property instead of writing a counting loop.
- Empty file behavior: An empty file still produces a valid array, just one with a length of zero rather than throwing an exception.
Exercise 10: Write Array of Strings
Practice Problem: Create an array of strings representing a shopping list and write each element as a new line in a file using File.WriteAllLines.
Purpose: This exercise helps you practice writing multiple lines to a file in one call using File.WriteAllLines, which handles the line breaks between elements automatically.
Given Input: items = ["Milk", "Eggs", "Bread"]
Expected Output: shopping_list.txt is created with three lines (Milk, Eggs, Bread), and the console prints Shopping list saved.
▼ Hint
- Store the shopping list items in a string array.
- Use
File.WriteAllLines(path, array)to write every element as its own line in one call. - Remember that
WriteAllLinesautomatically adds a line break after each element, so you don’t have to add one yourself. - Print a confirmation message once the file has been written.
▼ Solution & Explanation
Explanation:
string[] items = { "Milk", "Eggs", "Bread" }: Defines the shopping list as an array, with each element representing one item.File.WriteAllLines("shopping_list.txt", items): Writes every element of the array to the file, automatically placing each one on its own line.- Compared to
WriteAllText:WriteAllLinesis built specifically for arrays or collections of strings, so it removes the need to manually join elements with line break characters. - Overwrite behavior: Like
WriteAllText, this method replaces the file entirely if it already exists, rather than appending to it.
Exercise 11: Find Specific Word
Practice Problem: Read a text file and search for a specific word. Output the line number(s) where the word is found.
Purpose: This exercise helps you practice combining File.ReadAllLines with a per-line search condition, using the loop index to report matching line numbers.
Given Input: A file story.txt with four lines, searching for the word "fox".
Expected Output:
Found on line 1 Found on line 3
▼ Hint
- Read the file into an array of lines using
File.ReadAllLines. - Loop through the array with a
forloop to access both the line text and its index. - Check whether each line contains the target word using
string.Contains. - Print the line number (index + 1) whenever a match is found.
▼ Solution & Explanation
Explanation:
string wordToFind = "fox": Defines the target word once so the search stays consistent across the whole file.lines[i].Contains(wordToFind): Checks whether the current line includes the target word anywhere within it.for (int i = 0; i < lines.Length; i++): Iterates over every line while keeping track of its position in the array.(i + 1): Converts the zero-based index into a human-readable line number before printing it.
Exercise 12: CSV Data Parser
Practice Problem: Read a comma-separated values (.csv) file containing employee names and salaries, parse the data, and print it in a formatted table.
Purpose: This exercise helps you practice splitting each line of a CSV file on its delimiter and aligning the resulting values into readable columns.
Given Input: employees.csv containing three rows: Alice,55000, Bob,62000, Charlie,48000.
Expected Output:
Alice 55000 Bob 62000 Charlie 48000
▼ Hint
- Read all lines of the CSV file using
File.ReadAllLines. - Split each line on the comma character using
string.Split. - Use string formatting, such as
PadRight, to align the name and salary into columns. - Print one formatted row per line of the file.
▼ Solution & Explanation
Explanation:
line.Split(','): Breaks each row into an array of two elements, since the file uses a comma as the delimiter between name and salary.parts[0]andparts[1]: Extract the name and salary values from the split array by their fixed position.name.PadRight(12): Pads the name with spaces up to a fixed width, so every salary lines up in the same column regardless of name length.foreach (string line in lines): Processes one row of the CSV at a time, keeping the parsing logic simple and readable.
Exercise 13: Count Characters and Words
Practice Problem: Write a program to count the total number of characters (excluding spaces) and total words in a text file.
Purpose: This exercise helps you practice combining two string manipulation methods, Replace and Split, to derive two different measurements from the same piece of text.
Given Input: A file sample.txt containing "The quick brown fox".
Expected Output:
Characters (excluding spaces): 16 Words: 4
▼ Hint
- Read the file’s entire content into a single string using
File.ReadAllText. - Remove spaces from that string using
Replacebefore counting characters. - Split the original content on whitespace using
Splitto get an array of words. - Print both counts using the
Lengthproperty of the resulting string and array.
▼ Solution & Explanation
Explanation:
content.Replace(" ", ""): Removes every space from the text before measuring its length, so spaces don’t count toward the character total.content.Split(' ', StringSplitOptions.RemoveEmptyEntries): Splits the text into words on spaces, discarding any empty entries caused by extra whitespace..Lengthon the resulting string and array: Gives the character count and word count respectively, without any manual counting loop.- Single read:
File.ReadAllTextloads the file once, and both measurements are derived from that same string.
Exercise 14: Directory File Lister
Practice Problem: List all files inside a given directory path along with their file sizes in kilobytes (KB).
Purpose: This exercise helps you practice using Directory.GetFiles to enumerate files in a folder, then FileInfo to inspect each file’s size.
Given Input: directoryPath = "documents", containing report.txt (2048 bytes) and notes.txt (512 bytes).
Expected Output:
report.txt - 2 KB notes.txt - 0.5 KB
▼ Hint
- Use
Directory.GetFiles(path)to get an array of full file paths inside the folder. - Wrap each path in a new
FileInfoobject to access its metadata. - Divide the file’s
Lengthproperty (in bytes) by 1024 to convert it to kilobytes. - Print each file’s name, using
FileInfo.Name, alongside its calculated size.
▼ Solution & Explanation
Explanation:
Directory.GetFiles(directoryPath): Returns the full path of every file directly inside the given folder, not including subfolders.new FileInfo(filePath): Wraps a single file path in an object that exposes metadata like size, name, and timestamps.info.Length / 1024.0: Converts the file’s size from bytes into kilobytes, using a double to preserve fractional values for small files.info.Name: Extracts just the file name from the full path, rather than printing the entire path each time.
Exercise 15: Filter Lines
Practice Problem: Read a text file and write only the lines containing the word “Error” into a new file named errors.log.
Purpose: This exercise helps you practice filtering an array of lines with a condition before writing the filtered result to a separate file.
Given Input: A file app.log containing four lines, two of which include the word “Error”.
Expected Output: errors.log is created containing only the two matching lines, and the console prints Filtered lines saved to errors.log.
▼ Hint
- Read the source file into an array of lines using
File.ReadAllLines. - Use LINQ’s
Wheremethod to select only the lines containing “Error”. - Convert the filtered result into an array before writing it out.
- Write the filtered lines to
errors.logusingFile.WriteAllLines.
▼ Solution & Explanation
Explanation:
lines.Where(line => line.Contains("Error")): Filters the array down to only the lines that contain the word “Error”, using a LINQ query instead of a manual loop..ToArray(): Converts the filtered LINQ result back into a string array, sinceFile.WriteAllLinesexpects an array or collection of strings.File.WriteAllLines("errors.log", errorLines): Writes just the matching lines to a brand new file, leaving the originalapp.loguntouched.- Separation of concerns: Reading, filtering, and writing are each handled by a single, focused line of code.
Exercise 16: Binary Writer/Reader
Practice Problem: Write primitive data types (an int, a double, and a string) to a binary file using BinaryWriter, then read them back accurately using BinaryReader.
Purpose: This exercise helps you practice writing and reading primitive values in their raw binary form, which is more compact than text and requires reading values back in the exact order they were written.
Given Input: age = 30, price = 19.99, name = "Widget"
Expected Output:
30 19.99 Widget
▼ Hint
- Open a
BinaryWriterwrapped around aFileStreamto write the data. - Call
Writefor each value in a specific order: int, then double, then string. - Open a
BinaryReaderwrapped around aFileStreamto read the data back. - Call
ReadInt32,ReadDouble, andReadStringin that exact same order to retrieve the values correctly.
▼ Solution & Explanation
Explanation:
BinaryWriterwrapped aroundFile.Open("data.bin", FileMode.Create): Opens a file specifically for writing raw binary data rather than text.writer.Write(age),writer.Write(price),writer.Write(name): Writes each value in its native binary representation, one after another, in a fixed sequence.reader.ReadInt32(),reader.ReadDouble(),reader.ReadString(): Reads the values back in the exact same order they were written, since binary data has no built-in labels identifying each value.- Order sensitivity: Reading the values in a different order, or with the wrong method, would produce garbage or throw an exception, since binary data relies entirely on a known, agreed-upon layout.
Exercise 17: Uppercase Converter
Practice Problem: Read a text file, convert all its characters to uppercase, and save the result into a new file.
Purpose: This exercise helps you practice combining a file read, a string transformation, and a file write into a single, small pipeline.
Given Input: A file original.txt containing "Hello World".
Expected Output: uppercase.txt is created containing "HELLO WORLD", and the console prints Converted file saved.
▼ Hint
- Read the entire source file into a string using
File.ReadAllText. - Call
ToUpper()on that string to produce a fully uppercase version. - Write the transformed string to a new file using
File.WriteAllText. - Keep the original file untouched by writing to a different file name.
▼ Solution & Explanation
Explanation:
File.ReadAllText("original.txt"): Loads the source file’s content into a single string for processing.content.ToUpper(): Produces a new string with every character converted to uppercase, leaving the original string unchanged.File.WriteAllText("uppercase.txt", upperContent): Saves the transformed text to a separate file, rather than overwriting the original.- Three-step pipeline: Read, transform, then write is a pattern that applies to many other text-processing tasks beyond just uppercase conversion.
Exercise 18: Find the Largest File
Practice Problem: Scan a specified directory and output the name and path of the largest file in that folder.
Purpose: This exercise helps you practice using FileInfo alongside LINQ’s OrderByDescending to find the single largest item in a collection of files.
Given Input: directoryPath = "documents", containing report.txt (2048 bytes), notes.txt (512 bytes), and presentation.pptx (10240 bytes).
Expected Output: Largest file: presentation.pptx (10240 bytes)
▼ Hint
- Use
Directory.GetFiles(path)to get every file path inside the folder. - Convert each path into a
FileInfoobject so itsLengthproperty can be compared. - Use LINQ’s
OrderByDescendingto sort the files by size, largest first. - Take the first result from that sorted sequence and print its
NameandLengthtogether.
▼ Solution & Explanation
Explanation:
files.Select(path => new FileInfo(path)): Converts each file path string into aFileInfoobject so its size and other metadata become accessible.OrderByDescending(info => info.Length): Sorts theFileInfoobjects from largest to smallest based on their byte size..First(): Takes the top result from that sorted sequence, which is the single largest file in the folder.largest.Nameandlargest.Length: Read directly from the chosenFileInfoobject to build the final output message.
Exercise 19: File Properties Viewer
Practice Problem: Display the metadata of a specific file, including its creation time, last access time, and attributes (e.g., Hidden, Read-Only).
Purpose: This exercise helps you practice reading a file’s metadata through FileInfo, which exposes details beyond just its content, such as timestamps and file system attributes.
Given Input: filePath = "report.txt"
Expected Output (values will vary based on the actual file):
Created: 1/5/2026 9:15:00 AM Last Accessed: 7/13/2026 8:00:00 AM Attributes: Archive
▼ Hint
- Create a
FileInfoobject for the target file path. - Read its
CreationTimeandLastAccessTimeproperties directly. - Read its
Attributesproperty, which returns a combined set of flags such as Hidden or ReadOnly. - Print each piece of metadata with a clear label describing what it represents.
▼ Solution & Explanation
Explanation:
new FileInfo(filePath): Creates an object representing the file’s metadata without reading its actual content.info.CreationTimeandinfo.LastAccessTime: Expose the file’s timestamps directly asDateTimevalues, ready to print or format further.info.Attributes: Returns aFileAttributesvalue, which can combine multiple flags such as Hidden, ReadOnly, or Archive into a single result.- No content is read: This entire program never opens the file’s contents, only the file system record describing it.
Exercise 20: Remove Empty Lines
Practice Problem: Clean up a text file by removing all empty or whitespace-only lines, saving the cleaned content back to the disk.
Purpose: This exercise helps you practice filtering out unwanted lines with a whitespace check before writing the cleaned result back to the same file.
Given Input: A file messy.txt containing several lines, some of which are empty or contain only whitespace.
Expected Output: messy.txt is overwritten so it contains only its non-empty lines, and the console prints Empty lines removed.
▼ Hint
- Read the file into an array of lines using
File.ReadAllLines. - Use
string.IsNullOrWhiteSpaceto identify lines that are empty or contain only whitespace. - Filter out those lines using LINQ’s
Wheremethod. - Write the remaining lines back to the same file using
File.WriteAllLines.
▼ Solution & Explanation
Explanation:
string.IsNullOrWhiteSpace(line): Returns true for lines that are empty, contain only spaces, or are entirely whitespace, catching more cases than a simple empty-string check.lines.Where(line => !string.IsNullOrWhiteSpace(line)): Keeps only the lines that fail that whitespace check, effectively filtering out the unwanted ones.File.WriteAllLines("messy.txt", cleanedLines): Writes the cleaned array back to the same file path, overwriting the original messy content.- Same file overwrite: Since the destination path matches the source path, the original file itself ends up holding only the cleaned lines afterward.
Exercise 21: Create Subdirectories
Practice Problem: Write a program that checks if a folder structure exists (e.g., MyApp/Logs/Archive) and creates all missing subdirectories programmatically.
Purpose: This exercise helps you practice using Directory.CreateDirectory, which creates every missing folder in a path at once, unlike File.Copy or File.Move, which require the destination folder to already exist.
Given Input: path = "MyApp/Logs/Archive"
Expected Output: Directory structure ready: MyApp/Logs/Archive
▼ Hint
- Use
Directory.Exists(path)to check whether the full nested path is already there. - Use
Directory.CreateDirectory(path)to create it if it’s missing. Directory.CreateDirectorycan create every missing folder in the chain in a single call, not just the final one.- Print a confirmation message once the check and creation are complete.
▼ Solution & Explanation
Explanation:
Directory.Exists(path): Checks whether the full nested folder structure already exists before attempting to create anything.Directory.CreateDirectory(path): Creates every missing folder along the path in one call, soMyApp,Logs, andArchiveare all created together if none of them exist yet.- No error on partial existence: If
MyAppalready exists butLogsandArchivedon’t,CreateDirectoryonly creates the missing parts without throwing an exception. - Idempotent behavior: Running the program again when the structure already exists does nothing harmful, since the initial check skips the creation step.
Exercise 22: Reverse File Content
Practice Problem: Read a text file line by line, reverse the order of the lines (the last line becomes the first), and save it to a new file.
Purpose: This exercise helps you practice using Array.Reverse to invert the order of elements read from a file before writing them back out.
Given Input: A file original.txt containing the lines “First”, “Second”, “Third”.
Expected Output: reversed.txt is created containing:
Third Second First
▼ Hint
- Read all lines of the source file into an array using
File.ReadAllLines. - Use
Array.Reverseto reverse the order of elements in that array in place. - Write the reversed array to a new file using
File.WriteAllLines. - Keep the original file untouched by saving the result to a different file name.
▼ Solution & Explanation
Explanation:
File.ReadAllLines("original.txt"): Loads every line of the source file into an array in its original order.Array.Reverse(lines): Reverses the array in place, so the last line becomes the first element and vice versa.File.WriteAllLines("reversed.txt", lines): Writes the now-reversed array to a separate file, one element per line.- In-place modification:
Array.Reversechanges the existing array directly rather than returning a new one, which is why the samelinesvariable is reused for writing.
Exercise 23: Search Files by Extension
Practice Problem: Given a directory path and a file extension (e.g., .pdf, .png), list all matching files in that folder.
Purpose: This exercise helps you practice using Directory.GetFiles with a search pattern to filter files by extension directly, instead of retrieving every file and filtering manually.
Given Input: directoryPath = "documents", extension = "*.pdf"
Expected Output:
report.pdf invoice.pdf
▼ Hint
- Pass a search pattern like
"*.pdf"as the second argument toDirectory.GetFiles. - The pattern uses a wildcard (
*) to match any file name, followed by the specific extension to filter on. - Loop through the returned array and print each matching file’s name.
- Use
Path.GetFileNameif you only want the file name rather than its full path.
▼ Solution & Explanation
Explanation:
Directory.GetFiles(directoryPath, extension): Filters the returned files directly at the file system level, so only files matching the pattern are included in the result."*.pdf": The wildcard*matches any file name, while.pdfrestricts the results to files with that specific extension.Path.GetFileName(filePath): Extracts just the file name from each full path, keeping the output clean and readable.- Fixed sample values:
directoryPathandextensionare hardcoded here to keep the example deterministic; in an interactive console app they would typically come fromConsole.ReadLine().
Exercise 24: Exception Safe Reader
Practice Problem: Implement a program that reads a file using structured exception handling (try-catch-finally) to gracefully catch FileNotFoundException and UnauthorizedAccessException.
Purpose: This exercise helps you practice structuring a file operation with multiple specific catch blocks, handling different failure scenarios with tailored messages instead of one generic catch-all.
Given Input: filePath = "missing.txt", a file that doesn’t exist.
Expected Output:
File not found: missing.txt Read attempt finished
▼ Hint
- Wrap the file read inside a
tryblock. - Add a
catchblock specifically forFileNotFoundException, since it represents a missing file. - Add a second
catchblock forUnauthorizedAccessException, since it represents a permissions problem. - Add a
finallyblock that always runs, regardless of whether an exception occurred.
▼ Solution & Explanation
Explanation:
try { File.ReadAllText(filePath); }: Attempts the read operation, which may throw if the file is missing or inaccessible.catch (FileNotFoundException): Handles the specific case where the file simply doesn’t exist at the given path.catch (UnauthorizedAccessException): Handles a separate case where the file exists but the program lacks permission to read it.finally { ... }: Runs after either thetryblock succeeds or one of thecatchblocks handles an exception, useful for cleanup or status messages that must always execute.
Exercise 25: Merge Two Files
Practice Problem: Read contents from two separate text files and merge them alternate line by alternate line into a third file.
Purpose: This exercise helps you practice looping through two arrays of lines simultaneously using a shared index, interleaving their content into a single combined result.
Given Input: fileA.txt containing “A1”, “A2”; fileB.txt containing “B1”, “B2”.
Expected Output: merged.txt is created containing:
A1 B1 A2 B2
▼ Hint
- Read both files into separate arrays using
File.ReadAllLines. - Loop using an index that goes up to the length of the longer array.
- Inside the loop, add the line from the first array if that index exists, then the line from the second array if it exists.
- Write the combined list of lines to the new file using
File.WriteAllLines.
▼ Solution & Explanation
Explanation:
int maxLength = Math.Max(fileA.Length, fileB.Length): Ensures the loop covers every line from whichever file is longer, so no content gets left out.if (i < fileA.Length)andif (i < fileB.Length): Guard each addition individually, so a shorter file simply contributes fewer lines without causing an index out of range error.merged.Add(...): Builds the interleaved sequence one line at a time, alternating between the two source files at each index.File.WriteAllLines("merged.txt", merged): Writes the final combined list to a new file, sinceList<string>works with the same overloadFile.WriteAllLinesaccepts for arrays.
Exercise 29: Secure Object Serialization Engine
Practice Problem: Design a system that takes a complex user-defined Company object with a list of Employees, serializes it to a JSON file, and encrypts the file on disk using AES encryption. Write a corresponding decryption and deserialization method to load it back safely.
Purpose: This exercise helps you practice combining object serialization with symmetric encryption, so structured data can be persisted to disk in a format that isn’t readable without the correct key.
Given Input: A Company object named “Acme Corp” with two employees, Alice and Bob.
Expected Output: company.dat is written to disk as encrypted bytes; after decrypting and deserializing it, the console prints Company: Acme Corp, Employees: 2.
▼ Hint
- Define simple
CompanyandEmployeeclasses with plain public properties so a JSON serializer can read and write them. - Serialize the object graph into a JSON string using
System.Text.Json. - Use the
Aesclass to encrypt the serialized bytes with a key and an initialization vector (IV) before writing them to disk. - Write a matching decryption method that reverses the process: decrypt the bytes, then deserialize the resulting JSON back into a
Companyobject.
▼ Solution & Explanation
Explanation:
JsonSerializer.Serialize(company): Converts the entire object graph, including the nested list of employees, into a single JSON string.Aes.Create()with a fixedKeyandIV: Sets up a symmetric encryption algorithm using the same key and initialization vector for both encrypting and decrypting, which must match exactly on both sides.CryptoStreamwrapping aFileStream: Encrypts data as it’s written to disk, or decrypts it as it’s read back, without needing a separate buffer for the raw encrypted bytes.LoadDecryptedreversing the process: Decrypts the file’s bytes back into JSON text, then deserializes that text into a newCompanyobject, restoring the original structure of data. In a real application, the key would come from a secure source rather than being hardcoded in the source file.
Exercise 30: Memory-Mapped File Processor
Practice Problem: Given a log file too large to fit into RAM, use MemoryMappedFiles to map the file into virtual memory space, parse through the bytes directly to find specific patterns, and count occurrences without loading the whole file into application memory.
Purpose: This exercise helps you practice using memory-mapped files to process data far larger than available RAM, working directly with a mapped view’s bytes instead of reading the entire file into a string or byte array.
Given Input: filePath = "huge_log.txt", searching for the byte pattern representing the word “ERROR”.
Expected Output (illustrative; the actual count depends on the file’s contents): Occurrences found: 42
▼ Hint
- Open the target file using
MemoryMappedFile.CreateFromFile, which maps the file into virtual memory rather than loading it into a managed byte array. - Create a view stream over the mapped file to read through its bytes in smaller chunks.
- Read the file through the view in fixed-size chunks, checking each chunk for the byte pattern you’re searching for.
- Keep a running count of matches found across all chunks and print the total once the entire file has been scanned.
▼ Solution & Explanation
Explanation:
MemoryMappedFile.CreateFromFile(filePath, FileMode.Open): Maps the file’s contents into the process’s virtual address space, letting the operating system manage which parts are actually loaded into physical memory at any moment.mappedFile.CreateViewStream(): Provides a stream-like way to read through the mapped file sequentially, chunk by chunk, without needing to hold the entire file in a managed array.- Nested byte comparison loop: Checks every possible starting position within each chunk for an exact match against the target pattern’s bytes.
- Running
occurrencescount: Accumulates across every chunk processed, so the final total reflects matches found throughout the entire file even though no single chunk ever contains all of it. A production version would also retain a small overlap of trailing bytes between chunks, since this simple approach can miss a pattern split across a chunk boundary.

Leave a Reply