7.5. Lab: Files
7.5.1. Example: Sum Numbers in File
StreamReader
.EndOfStream
.Close()
negation
ReadLine
.Trim()
int.Parse()
You have summed the numbers from 1 to n
. In that case you generated
the next number i
automatically using i++
. We could also write a
method to read numbers from a file containing one number per line
(plus possible white space):
static int CalcSum(string filename)
{
int sum = 0;
var reader = new StreamReader(filename);
while (!reader.EndOfStream) {
string sVal = reader.ReadLine().Trim(); // Trim(()
sum += int.Parse(sVal);
}
reader.Close();
return sum;
}
Below is a more elaborate, complete example with some data quality control, that also exits gracefully if you give a bad file name. If you give a good file name, it skips lines that contain only whitespace.
Note
Note that this example uses the
UI
class. You can simply copy the fileui.cs
to the project folder like before.
using System;
using System.IO;
namespace IntroCSCS
{
class SumFile // sum a file integers, one per line
{
static void Main()
{
string filename = UI.PromptLine(
"Enter the name of a file of integers: ");
if (File.Exists(filename)) {
Console.WriteLine("The sum is {0}", CalcSum(filename));
}
else {
Console.WriteLine("Bad file name {0}", filename);
}
}
/// Open, read and close the named file and
/// return the sum of an int from
/// each line that is not just white space.
static int CalcSum(string filename)
{
int sum = 0;
var reader = new StreamReader(filename);
while (!reader.EndOfStream) {
string sVal = reader.ReadLine().Trim();
if (sVal.Length > 0) {
sum += int.Parse(sVal);
}
}
reader.Close();
return sum;
}
}
}
A useful method used in Main
for avoiding filename typo errors
is File.Exists
in the System.IO
namespace
bool File.Exists(string filenamePath)
It is true if the named files exists in the operating system’s file structure. For files in the current folder, you can just use the plain file name.
7.5.2. Safe Sum File
From sum_file/sum_file.cs, copy the method CalcSum and the logic in the Main to your project Program.cs of the chapter to make sure it works. Afterwards, write a new method with the header below. Use it in
Main
, in place of theif
statement that checks (only once) for a legal file:// Prompt the user to enter a file name to open for reading. // Repeat until the name of an existing file is given. // Open and return the file. public static StreamReader PromptFile(string prompt)
A user who completely forgot the file name could be stuck in an infinite loop! Elaborate the method and program, so that an empty line entered means “give up”, and
null
(no object) should be returned. The main program needs to test for this and quit gracefully in that case.
7.5.3. Copy to Upper Case
Here is a simple fragment from example file copy_upper/copy_upper.cs. It copies a file line by line to a new file in upper case:
var reader = new StreamReader("text.txt");
var writer = new StreamWriter("upper_text.txt");
while (!reader.EndOfStream) {
string line = reader.ReadLine();
writer.WriteLine(line.ToUpper());
}
reader.Close();
writer.Close();
This is another case where the ReadToEnd
method could have eliminated the loop:
string contents = reader.ReadToEnd();
writer.Write(contents.ToUpper());