Questions
-
What is the name of the class we use to read from files?
-
FileReader -
StreamOpener -
ReadFile -
StreamReader -
FileStream
-
-
What is of crucial importance?
- Always call the
Openmethod before reading from or writing into a file. - Always assume the user has
C:\as their main drive. - Always call the
Closemethod after being done reading from or writing into a file. - Never read from or write into a file inside a
try-catchblock.
- Always call the
-
The
StreamReaderclass contains a method called…- …
.Open - …
.Close. - …
.ReadLine - …
.WriteLine - …
.NextLine
- …
-
If a file is located at
~/upload/teaching/2026/spring/quiz8.md, then…- … its extension is
md. - … it is safe to assume that it can be accessed by all users.
- … it will have the same path if transferred to a computer using Windows.
- … it is located in a folder called
spring.
- … its extension is
Problems
-
Assume that
filePathcontains the path to a text file. Briefly explain what the following program would do, and how it could be made safer to execute.StreamWriter sw = new StreamWriter(filePath); sw.WriteLine("Hello World!!");Solution
This program would
- Create a file located at
filePath, - Store in the file “Hello World!!”, followed by a new line.
This program is unsafe because:
- It does not close the file properly,
- It can throw exceptions if e.g.,
filePathcannot be accessed by the program, - It possibly overwrites the file located at
filePath.
To solve those, it should be edited to:
- Close the file using
sw.Close(), - Be wrapped inside a
try…catchblock, - Either test first if the file exists, or use the
StreamWriterconstructor that appends to the file if it already exists.
- Create a file located at
Assume that filePath contains the path to a text file that is not
empty. Write a program that counts its number of lines.
Solution
int count = 0;
string line;
try
{
StreamReader sr = new StreamReader(filePath);
line = sr.ReadLine();
while (line != null)
{
count++;
line = sr.ReadLine();
}
sr.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}Write a program that create a text file called HelloWorld.txt in
its bin/Debug folder and store “Hello” followed by a name entered
by the user in it.
Solution
string uName;
Console.WriteLine("Please, enter your name.");
uName = Console.ReadLine();
try
{
string filePath = Path.Combine(
AppDomain.CurrentDomain.BaseDirectory,
"HelloWorld.txt"
);
// This string contains the path for the file we create.
StreamWriter sw = new StreamWriter(filePath);
// We create the file
sw.WriteLine("Hello " + uName);
sw.Close();
Console.WriteLine("Check out " + filePath + "!");
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e.Message);
}Write a program that ask the user for a filename, makes sure the
filename ends with “.txt” and does not begin with a ”.” (otherwise,
the file would be hidden on unix systems), does not match a file
with the same name in the bin/Debug folder of your program, then
create it in the bin/Debug folder of your program and write in it
all the number from 1 to 1,000,000 (both included). Out of
curiosity, what is the file size?
Solution
string fName,
filePath;
do
{
Console.WriteLine("Enter a file name.");
fName = Console.ReadLine();
filePath = Path.Combine(
AppDomain.CurrentDomain.BaseDirectory,
fName
);
} while (
!fName.EndsWith(".txt")
|| fName.StartsWith(".")
|| File.Exists(filePath)
);
try
{
StreamWriter sw = new StreamWriter(filePath);
for (int i = 1; i <= 1000000; i++)
sw.WriteLine(i);
sw.Close();
Console.WriteLine("Check out " + filePath + "!");
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e.Message);
}(Download this code) The resulting file is about 6.6 MB on Unix system, 7.52 MB on Windows system.
Execute the following program, then write a program that find the
greatest number in the RandomNumber.txt file.
string filePath = Path.Combine(
AppDomain.CurrentDomain.BaseDirectory,
"RandomNumbers.txt"
);
Random gen = new Random();
try
{
StreamWriter sw = new StreamWriter(filePath);
for (int i = 1; i <= 100; i++)
sw.WriteLine(gen.Next(1000));
sw.Close();
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e.Message);
}
Solution
string line;
int number;
int maxSoFar;
try
{
StreamReader sr = new StreamReader(filePath);
line = sr.ReadLine();
if (int.TryParse(line, out number))
{
maxSoFar = number;
}
else
{
throw new ArgumentException(
"File contains string that is not a number."
);
}
while (line != null)
{
if (int.TryParse(line, out number))
{
if (maxSoFar < number)
{
maxSoFar = number;
}
}
else
{
throw new ArgumentException(
"File contains string that is not a number."
);
}
line = sr.ReadLine();
}
Console.WriteLine(
"The maximum number in the file is "
+ maxSoFar
+ "."
);
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e.Message);
}Suppose that at filePath is located a file where each line is
either
- a decimal (e.g., 12.4, -14, 0.34),
- the word “STOP”,
- some other string (“Test”, “The sky is blue”, “Ignore this line”, “My file contains”), that may contain the characters “STOP”.
Write a program that displays the average of the decimals in the file knowing that
- your program should ignore the values after a line containing “STOP” and only “STOP” if it is present,
- all the other strings should simply be ignored.
For example, for the following three files, “4.0”, “10.0” and “7.5” should be displayed, as (12.48 - 2.48 + 2) / 3 = 4 (13 been ignored), (15 + 5) / 2 = 10, and (11 + 4) / 2 = 7.5 (12 being ignored).
┌────────────────┐
│12.48 │
│This is a test │
│-2.48 │
│2 │
│STOP │
│13 │
└────────────────┘
┌────────────────┐
│My file contains│
│STOP but │
│averages │
│15 │
│ and │
│5 │
└────────────────┘
┌────────────────┐
│This 12 will be │
│ignored │
│but not │
│11 │
│ nor │
│4 │
└────────────────┘
Solution
double number;
double sum = 0;
int counter = 0;
double average;
try
{
// Opening file
StreamReader sr = new StreamReader(filePathP);
// Reading first line
string line = sr.ReadLine();
// Looping through the file until we
// reach the end, or read the word
// "STOP" on its own line.
while (line != null && line != "STOP")
{
// We test if the line contains a double.
if (double.TryParse(line, out number))
{
sum += number;
counter++;
}
// We read the next line.
line = sr.ReadLine();
}
sr.Close();
}
catch { }
// if to prevent division by 0.
if (counter != 0)
{
average = sum / counter;
}
else
{
average = -1;
}Suppose that at filePath is located a file containing text. Write
a program that, for each line, displays the content of that line if
it does not start with a % character, and that furthermore
displays as a dollar amount the content of that line if it is (only)
a decimal.
For example, the following file on the left would be rendered as shown on the right.
FILE OUTPUT SCREEN
┌────────────────┐ ┌────────────────┐
│Receipt test │ │Receipt test │
│% Ignore me │ │$12.48 │
│12.48 │ │$2.00 │
│2 │ │** Total ** │
│** Total ** │ │$14.48 │
│14.48 │ │ │
│% 00.00 │ │ │
└────────────────┘ └────────────────┘
Solution
try
{
StreamReader sw = new StreamReader(filePath);
string cLine = sw.ReadLine();
decimal amount;
while (cLine != null)
{
if (cLine[0] != '%')
{
if (decimal.TryParse(cLine, out amount))
{
Console.WriteLine($"{amount:C}");
}
else
{
Console.WriteLine(cLine);
}
}
cLine = sw.ReadLine();
}
}
catch
{
Console.WriteLine("An error was thrown.");
}Write a program that asks the user to enter a sentence, and store it in a file where the maximum width is 40: if the string entered is more than 40 characters long, then it should span over multiple lines of no more than 40 characters each. For example, if the user enters
In publishing and graphic design, Lorem ipsum is a placeholder text commonly used to demonstrate the visual form of a document or a typeface without relying on meaningful content. Lorem ipsum may be used as a placeholder before the final copy is available.then the text file should contain
In publishing and graphic design, Lorem
ipsum is a placeholder text commonly use
d to demonstrate the visual form of a do
cument or a typeface without relying on
meaningful content. Lorem ipsum may be u
sed as a placeholder before the final co
py is available.
Solution
string filePath = Path.Combine(
AppDomain.CurrentDomain.BaseDirectory,
"TextTruncate.txt"
);
Console.WriteLine("Enter a string.");
string uString = Console.ReadLine();
const int MAXWIDTH = 40;
try
{
StreamWriter sw = new StreamWriter(filePath);
while (uString.Length > MAXWIDTH)
{
sw.WriteLine(uString.Substring(0, MAXWIDTH));
uString = uString.Substring(MAXWIDTH);
}
sw.WriteLine(uString);
sw.Close();
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e.Message);
}Write a program that counts the number of words in itself! Ideally, empty lines should not count toward the word count.
Hint: Program.cs is normally located at
Path.Combine(
new DirectoryInfo(Directory.GetCurrentDirectory()).Parent.Parent.ToString(),
"Program.cs"
)
Solution
using System;
using System.IO;
class Program
{
static void Main()
{
string filePath = Path.Combine(
new DirectoryInfo(
Directory.GetCurrentDirectory()
).ToString(),
"Program.cs"
);
/*
* On older versions, you may need to use the following instead,
* as the program is executed in /bin/Debug, we need to go
* two folders up, where Program.cs is located: note the ".Parent"
* bits in the code that follows.
*/
/*
string filePath = Path.Combine(
new DirectoryInfo(
Directory.GetCurrentDirectory()
).Parent.Parent.ToString(),
"Program.cs"
);
*/
if (!File.Exists(filePath))
{
Console.WriteLine(
"There seems to be an issue. Impossible to locate Program.cs"
);
}
else
{
Console.WriteLine("Program.cs located, processing.");
string line;
string[] words;
int wCount = 0;
try
{
StreamReader sr = new StreamReader(filePath);
line = sr.ReadLine();
while (line != null)
{
words = line.Split(
new string[] { " " },
StringSplitOptions.RemoveEmptyEntries
);
wCount += words.Length;
line = sr.ReadLine();
}
sr.Close();
Console.WriteLine(
"Your program contains " + wCount + " words!"
);
// Should display "Your program contains 121 words!"
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e.Message);
}
}
}
}Write a program that
- Asks the user to enter a path,
- Checks if there is a file at this path:
- If there is a file, display its content at the screen.
- If there is no file, ask the user to enter text. When the user enters exactly “!DONE!”, on a single line, without the quotes, write the text entered before !DONE! into a file located at the given path.
Your program should be able to handle graciously possible issues (such as an invalid path).
Below are two examples of execution, taking place one after the other.
Example execution #1
Enter a path
/͟h͟o͟m͟e͟/͟u͟s͟e͟r͟/͟C͟S͟C͟I͟_͟1͟3͟0͟2͟/͟f͟i͟n͟a͟l͟/͟t͟e͟s͟t͟.͟t͟x͟t͟
Now creating a file at /home/user/CSCI_1302/final/test.txt.
Enter your text, one line at a time. When done, type "!DONE!" (without the quotes), then enter.
T͟h͟i͟s͟ ͟i͟s͟ ͟a͟ ͟t͟e͟s͟t͟
s͟p͟a͟n͟n͟i͟n͟g͟ ͟o͟v͟e͟r͟
t͟h͟r͟e͟e͟ ͟l͟i͟n͟e͟s͟.͟
!͟D͟O͟N͟E͟!͟
File correctly written.Example execution #2
Enter a path
/͟h͟o͟m͟e͟/͟u͟s͟e͟r͟/͟C͟S͟C͟I͟_͟1͟3͟0͟2͟/͟f͟i͟n͟a͟l͟/͟t͟e͟s͟t͟.͟t͟x͟t͟
Now displaying file at /home/user/CSCI_1302/final/test.txt.
This is a test
spanning over
three lines.
Done displaying file.
Solution
using System;
using System.IO;
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter a path");
string path = Console.ReadLine();
if (File.Exists(path))
{
Console.WriteLine(
"Now displaying file at " + path + "."
);
try
{
StreamReader sr = new StreamReader(path);
string cLine = sr.ReadLine();
while (cLine != null)
{
Console.WriteLine(cLine);
cLine = sr.ReadLine();
}
sr.Close();
Console.WriteLine("Done displaying file.");
}
catch
{
Console.WriteLine(
"There was an error opening your file."
);
}
}
else
{
Console.WriteLine(
"Now creating a file at "
+ path
+ ".\n Enter your text, one line at a time. When done, type \"!DONE!\" (without the quotes), then enter."
);
try
{
StreamWriter sw = new StreamWriter(path);
string uInput = Console.ReadLine();
while (uInput != "!DONE!")
{
sw.WriteLine(uInput);
uInput = Console.ReadLine();
}
sw.Close();
Console.WriteLine("File correctly written.");
}
catch
{
Console.WriteLine(
"There was an error creating your file."
);
}
}
}
}