I have an application that reads information from a text file and then categorizes them and puts them onto a Database. For one category, I need to check the line that comes right after the current line and look for a certain keyword?
How do i get to read this line? This should happen when the streamreader has the current line already open....
I'm using c# on VS2010.
Edit:
All of the code below is in a while (!sReader.EndOfStream) loop
string line = sReader.ReadLine(); //Note: this is used way above and lots of things are done before we come to this loop
for (int i = 0; i < filter_length; i++)
{
if (searchpattern_queries[i].IsMatch(line) == true)
{
logmessagtype = selected_queries[i];
//*Here i need to add a if condition to check if the type is "RESTARTS" and i need to get the next line to do more classification. I need to get that line only to classify the current one. So, I'd want it to be open independently *
hit = 1;
if (logmessagtype == "AL-UNDEF")
{
string alid = AlarmID_Search(line);
string query = "SELECT Severity from Alarms WHERE ALID like '" +alid +"'";
OleDbCommand cmdo = new OleDbCommand(query, conn);
OleDbDataReader reader;
reader = cmdo.ExecuteReader();
while (reader.Read())
{
if (reader.GetString(0).ToString() == null)
{ }
else
{
string severity = reader.GetString(0).ToString();
if (severity == "1")
//Keeps going on.....
Also, the .log files that are opened might go upto 50 Mb types... ! Which is why i dont really prefer reading all lines and keeping track!
Here is an idiom to process the current line you while having the next line already available:
public void ProcessFile(string filename)
{
string line = null;
string nextLine = null;
using (StreamReader reader = new StreamReader(filename))
{
line = reader.ReadLine();
nextLine = reader.ReadLine();
while (line != null)
{
// Process line (possibly using nextLine).
line = nextLine;
nextLine = reader.ReadLine();
}
}
}
This is basically a queue with a maximum of two items in it, or "one line read-ahead".
Edit: Simplified.
Simply use
string[] lines = File.ReadAllLines(filename);
and process the file with a for (int i = 0; i < lines.Length; i ++) loop.
For a big file, simply cache the 'previous line' or do an out-of-band ReadLine().
Can you not just call reader.ReadLine() again? Or is the problem that you then need to use the line in the next iteration of the loop?
If it's a reasonably small file, have you considered reading the whole file using File.ReadAllLines()? That would probably make it simpler, although obviously a little less clean in other ways, and more memory-hungry for large files.
EDIT: Here's some code as an alternative:
using (TextReader reader = File.OpenText(filename))
{
string line = null; // Need to read to start with
while (true)
{
if (line == null)
{
line = reader.ReadLine();
// Check for end of file...
if (line == null)
{
break;
}
}
if (line.Contains("Magic category"))
{
string lastLine = line;
line = reader.ReadLine(); // Won't read again next iteration
}
else
{
// Process line as normal...
line = null; // Need to read again next time
}
}
}
You could save the position of the stream then after calling ReadLine, seek back to that position. However this is pretty inefficient.
I would store the result of ReadLine into a "buffer", and when possible use that buffer as a source. When it is empty, use ReadLine.
I am not really a file IO expert... but why not do something like this:
Before you start reading lines declare two variables.
string currentLine = string.Empty
string previousLine = string.Empty
Then while you are reading...
previousLine = currentLine;
currentLine = reader.ReadLine();
Related
I have two text files, Source.txt and Target.txt. The source will never be modified and contain N lines of text. So, I want to delete a specific line of text in Target.txt, and replace by an specific line of text from Source.txt, I know what number of line I need, actually is the line number 2, both files.
I haven something like this:
string line = string.Empty;
int line_number = 1;
int line_to_edit = 2;
using StreamReader reader = new StreamReader(#"C:\target.xml");
using StreamWriter writer = new StreamWriter(#"C:\target.xml");
while ((line = reader.ReadLine()) != null)
{
if (line_number == line_to_edit)
writer.WriteLine(line);
line_number++;
}
But when I open the Writer, the target file get erased, it writes the lines, but, when opened, the target file only contains the copied lines, the rest get lost.
What can I do?
the easiest way is :
static void lineChanger(string newText, string fileName, int line_to_edit)
{
string[] arrLine = File.ReadAllLines(fileName);
arrLine[line_to_edit - 1] = newText;
File.WriteAllLines(fileName, arrLine);
}
usage :
lineChanger("new content for this line" , "sample.text" , 34);
You can't rewrite a line without rewriting the entire file (unless the lines happen to be the same length). If your files are small then reading the entire target file into memory and then writing it out again might make sense. You can do that like this:
using System;
using System.IO;
class Program
{
static void Main(string[] args)
{
int line_to_edit = 2; // Warning: 1-based indexing!
string sourceFile = "source.txt";
string destinationFile = "target.txt";
// Read the appropriate line from the file.
string lineToWrite = null;
using (StreamReader reader = new StreamReader(sourceFile))
{
for (int i = 1; i <= line_to_edit; ++i)
lineToWrite = reader.ReadLine();
}
if (lineToWrite == null)
throw new InvalidDataException("Line does not exist in " + sourceFile);
// Read the old file.
string[] lines = File.ReadAllLines(destinationFile);
// Write the new file over the old file.
using (StreamWriter writer = new StreamWriter(destinationFile))
{
for (int currentLine = 1; currentLine <= lines.Length; ++currentLine)
{
if (currentLine == line_to_edit)
{
writer.WriteLine(lineToWrite);
}
else
{
writer.WriteLine(lines[currentLine - 1]);
}
}
}
}
}
If your files are large it would be better to create a new file so that you can read streaming from one file while you write to the other. This means that you don't need to have the whole file in memory at once. You can do that like this:
using System;
using System.IO;
class Program
{
static void Main(string[] args)
{
int line_to_edit = 2;
string sourceFile = "source.txt";
string destinationFile = "target.txt";
string tempFile = "target2.txt";
// Read the appropriate line from the file.
string lineToWrite = null;
using (StreamReader reader = new StreamReader(sourceFile))
{
for (int i = 1; i <= line_to_edit; ++i)
lineToWrite = reader.ReadLine();
}
if (lineToWrite == null)
throw new InvalidDataException("Line does not exist in " + sourceFile);
// Read from the target file and write to a new file.
int line_number = 1;
string line = null;
using (StreamReader reader = new StreamReader(destinationFile))
using (StreamWriter writer = new StreamWriter(tempFile))
{
while ((line = reader.ReadLine()) != null)
{
if (line_number == line_to_edit)
{
writer.WriteLine(lineToWrite);
}
else
{
writer.WriteLine(line);
}
line_number++;
}
}
// TODO: Delete the old file and replace it with the new file here.
}
}
You can afterwards move the file once you are sure that the write operation has succeeded (no excecption was thrown and the writer is closed).
Note that in both cases it is a bit confusing that you are using 1-based indexing for your line numbers. It might make more sense in your code to use 0-based indexing. You can have 1-based index in your user interface to your program if you wish, but convert it to a 0-indexed before sending it further.
Also, a disadvantage of directly overwriting the old file with the new file is that if it fails halfway through then you might permanently lose whatever data wasn't written. By writing to a third file first you only delete the original data after you are sure that you have another (corrected) copy of it, so you can recover the data if the computer crashes halfway through.
A final remark: I noticed that your files had an xml extension. You might want to consider if it makes more sense for you to use an XML parser to modify the contents of the files instead of replacing specific lines.
When you create a StreamWriter it always create a file from scratch, you will have to create a third file and copy from target and replace what you need, and then replace the old one.
But as I can see what you need is XML manipulation, you might want to use XmlDocument and modify your file using Xpath.
You need to Open the output file for write access rather than using a new StreamReader, which always overwrites the output file.
StreamWriter stm = null;
fi = new FileInfo(#"C:\target.xml");
if (fi.Exists)
stm = fi.OpenWrite();
Of course, you will still have to seek to the correct line in the output file, which will be hard since you can't read from it, so unless you already KNOW the byte offset to seek to, you probably really want read/write access.
FileStream stm = fi.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
with this stream, you can read until you get to the point where you want to make changes, then write. Keep in mind that you are writing bytes, not lines, so to overwrite a line you will need to write the same number of characters as the line you want to change.
I guess the below should work (instead of the writer part from your example). I'm unfortunately with no build environment so It's from memory but I hope it helps
using (var fs = File.Open(filePath, FileMode.Open, FileAccess.ReadWrite)))
{
var destinationReader = StreamReader(fs);
var writer = StreamWriter(fs);
while ((line = reader.ReadLine()) != null)
{
if (line_number == line_to_edit)
{
writer.WriteLine(lineToWrite);
}
else
{
destinationReader .ReadLine();
}
line_number++;
}
}
The solution works fine. But I need to change single-line text when the same text is in multiple places. For this, need to define a trackText to start finding after that text and finally change oldText with newText.
private int FindLineNumber(string fileName, string trackText, string oldText, string newText)
{
int lineNumber = 0;
string[] textLine = System.IO.File.ReadAllLines(fileName);
for (int i = 0; i< textLine.Length;i++)
{
if (textLine[i].Contains(trackText)) //start finding matching text after.
traced = true;
if (traced)
if (textLine[i].Contains(oldText)) // Match text
{
textLine[i] = newText; // replace text with new one.
traced = false;
System.IO.File.WriteAllLines(fileName, textLine);
lineNumber = i;
break; //go out from loop
}
}
return lineNumber
}
I have a CSV file that I need to read all values from. But only from the last row which is newest. But I can't figure it out how to do it.
Im using streamreader now but that loops through the whole CSV file which can be very big.
I need to read two diffrent csv files(headers are the same but on diffrent location).
But how can I edit this code to only read from the last row? I have searched around but could not find anything that are the same as mine.
So this is how I been doing right now:
using (var reader = new StreamReader(path))
{
var headerLine = reader.ReadLine();
var headerValues = headerLine.Split(',');
var serialNumber = headerValues[66];
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(',');
if (values[0] != "Index")
{
var analyseReport = new AnalyseReport();
analyseReport.SerialNumber = serialNumber;
foreach (var item in headerValues)
{
var headerName = item.Trim();
var index = Array.IndexOf(headerValues, item);
switch (headerName)
{
case "Index":
analyseReport.Index = Convert.ToInt32(values[index].Trim());
break;
case "Time":
analyseReport.TimeStamp = Convert.ToDateTime(values[index].Trim());
break;
case "Reading No":
analyseReport.ReadingNo = Convert.ToInt32(values[index].Trim());
break;
case "Duration":
analyseReport.Duration = values[index].Trim();
break;
case "Type":
analyseReport.Type = values[index].Trim();
break;
case "Units":
analyseReport.Units = values[index].Trim();
break;
default:
break;
}
}
analyseReportList.Add(analyseReport);
}
}
return analyseReportList;
}
If you don't have fixed length lines, but can determine an upper limit of the length of your lines, you could use a heuristic to make reading the last line way more efficient.
Basically what to do is to move the current position of the file stream to n bytes from the end and then read until you've reached the last line.
private string ReadLastLine(string fileName, int maximumLineLength)
{
string lastLine = string.Empty;
using(Stream s = File.OpenRead(path))
{
s.Seek(-maximumLineLength, SeekOrigin.End);
using(StreamReader sr = new StreamReader(s))
{
string line;
while((line = sr.ReadLine()) != null)
{
lastLine = line;
}
}
}
return lastLine;
}
For a 1.8 MB CSV it's about 100-200 times faster than the File.ReadLines method. Anyway, at the cost of a way more complicated code.
Remarks: While you could use this method to optimize reading the last line, if it is really the bottleneck, please use the way clearer and cleaner version of Tim Schmelter, if at any rate possible. Please remember the second rule of optimization: "Don't do it, yet."
Futhermore, to determine the maximum length of your lines, you have to be careful and consider the character encoding. Rather over- than under-estimate the line length.
You could use File.ReadLines(path).Last():
string headerLine = File.ReadLines(path).First();
string lastLine = File.ReadLines(path).Last();
// ... (no loop)
These are LINQ methods so you need to add using System.Linq;.
I have two text files, Source.txt and Target.txt. The source will never be modified and contain N lines of text. So, I want to delete a specific line of text in Target.txt, and replace by an specific line of text from Source.txt, I know what number of line I need, actually is the line number 2, both files.
I haven something like this:
string line = string.Empty;
int line_number = 1;
int line_to_edit = 2;
using StreamReader reader = new StreamReader(#"C:\target.xml");
using StreamWriter writer = new StreamWriter(#"C:\target.xml");
while ((line = reader.ReadLine()) != null)
{
if (line_number == line_to_edit)
writer.WriteLine(line);
line_number++;
}
But when I open the Writer, the target file get erased, it writes the lines, but, when opened, the target file only contains the copied lines, the rest get lost.
What can I do?
the easiest way is :
static void lineChanger(string newText, string fileName, int line_to_edit)
{
string[] arrLine = File.ReadAllLines(fileName);
arrLine[line_to_edit - 1] = newText;
File.WriteAllLines(fileName, arrLine);
}
usage :
lineChanger("new content for this line" , "sample.text" , 34);
You can't rewrite a line without rewriting the entire file (unless the lines happen to be the same length). If your files are small then reading the entire target file into memory and then writing it out again might make sense. You can do that like this:
using System;
using System.IO;
class Program
{
static void Main(string[] args)
{
int line_to_edit = 2; // Warning: 1-based indexing!
string sourceFile = "source.txt";
string destinationFile = "target.txt";
// Read the appropriate line from the file.
string lineToWrite = null;
using (StreamReader reader = new StreamReader(sourceFile))
{
for (int i = 1; i <= line_to_edit; ++i)
lineToWrite = reader.ReadLine();
}
if (lineToWrite == null)
throw new InvalidDataException("Line does not exist in " + sourceFile);
// Read the old file.
string[] lines = File.ReadAllLines(destinationFile);
// Write the new file over the old file.
using (StreamWriter writer = new StreamWriter(destinationFile))
{
for (int currentLine = 1; currentLine <= lines.Length; ++currentLine)
{
if (currentLine == line_to_edit)
{
writer.WriteLine(lineToWrite);
}
else
{
writer.WriteLine(lines[currentLine - 1]);
}
}
}
}
}
If your files are large it would be better to create a new file so that you can read streaming from one file while you write to the other. This means that you don't need to have the whole file in memory at once. You can do that like this:
using System;
using System.IO;
class Program
{
static void Main(string[] args)
{
int line_to_edit = 2;
string sourceFile = "source.txt";
string destinationFile = "target.txt";
string tempFile = "target2.txt";
// Read the appropriate line from the file.
string lineToWrite = null;
using (StreamReader reader = new StreamReader(sourceFile))
{
for (int i = 1; i <= line_to_edit; ++i)
lineToWrite = reader.ReadLine();
}
if (lineToWrite == null)
throw new InvalidDataException("Line does not exist in " + sourceFile);
// Read from the target file and write to a new file.
int line_number = 1;
string line = null;
using (StreamReader reader = new StreamReader(destinationFile))
using (StreamWriter writer = new StreamWriter(tempFile))
{
while ((line = reader.ReadLine()) != null)
{
if (line_number == line_to_edit)
{
writer.WriteLine(lineToWrite);
}
else
{
writer.WriteLine(line);
}
line_number++;
}
}
// TODO: Delete the old file and replace it with the new file here.
}
}
You can afterwards move the file once you are sure that the write operation has succeeded (no excecption was thrown and the writer is closed).
Note that in both cases it is a bit confusing that you are using 1-based indexing for your line numbers. It might make more sense in your code to use 0-based indexing. You can have 1-based index in your user interface to your program if you wish, but convert it to a 0-indexed before sending it further.
Also, a disadvantage of directly overwriting the old file with the new file is that if it fails halfway through then you might permanently lose whatever data wasn't written. By writing to a third file first you only delete the original data after you are sure that you have another (corrected) copy of it, so you can recover the data if the computer crashes halfway through.
A final remark: I noticed that your files had an xml extension. You might want to consider if it makes more sense for you to use an XML parser to modify the contents of the files instead of replacing specific lines.
When you create a StreamWriter it always create a file from scratch, you will have to create a third file and copy from target and replace what you need, and then replace the old one.
But as I can see what you need is XML manipulation, you might want to use XmlDocument and modify your file using Xpath.
You need to Open the output file for write access rather than using a new StreamReader, which always overwrites the output file.
StreamWriter stm = null;
fi = new FileInfo(#"C:\target.xml");
if (fi.Exists)
stm = fi.OpenWrite();
Of course, you will still have to seek to the correct line in the output file, which will be hard since you can't read from it, so unless you already KNOW the byte offset to seek to, you probably really want read/write access.
FileStream stm = fi.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
with this stream, you can read until you get to the point where you want to make changes, then write. Keep in mind that you are writing bytes, not lines, so to overwrite a line you will need to write the same number of characters as the line you want to change.
I guess the below should work (instead of the writer part from your example). I'm unfortunately with no build environment so It's from memory but I hope it helps
using (var fs = File.Open(filePath, FileMode.Open, FileAccess.ReadWrite)))
{
var destinationReader = StreamReader(fs);
var writer = StreamWriter(fs);
while ((line = reader.ReadLine()) != null)
{
if (line_number == line_to_edit)
{
writer.WriteLine(lineToWrite);
}
else
{
destinationReader .ReadLine();
}
line_number++;
}
}
The solution works fine. But I need to change single-line text when the same text is in multiple places. For this, need to define a trackText to start finding after that text and finally change oldText with newText.
private int FindLineNumber(string fileName, string trackText, string oldText, string newText)
{
int lineNumber = 0;
string[] textLine = System.IO.File.ReadAllLines(fileName);
for (int i = 0; i< textLine.Length;i++)
{
if (textLine[i].Contains(trackText)) //start finding matching text after.
traced = true;
if (traced)
if (textLine[i].Contains(oldText)) // Match text
{
textLine[i] = newText; // replace text with new one.
traced = false;
System.IO.File.WriteAllLines(fileName, textLine);
lineNumber = i;
break; //go out from loop
}
}
return lineNumber
}
I am in a fight with overwriting of a text file with some of changes using a console application. Here I am reading the file line by line. Can any one help me.
StreamReader sr = new StreamReader(#"C:\abc.txt");
string line;
line = sr.ReadLine();
while (line != null)
{
if (line.StartsWith("<"))
{
if (line.IndexOf('{') == 29)
{
string s = line;
int start = s.IndexOf("{");
int end = s.IndexOf("}");
string result = s.Substring(start+1, end - start - 1);
Guid g= Guid.NewGuid();
line = line.Replace(result, g.ToString());
File.WriteAllLines(#"C:\abc.txt", line );
}
}
Console.WriteLine(line);
line = sr.ReadLine();
}
//close the file
sr.Close();
Console.ReadLine();
Here I am getting the error file is already open by another process.
Please help me, anyone. Main task is to overwrite the same texfile with modifications
You need a single stream,
open it for both reading and writing.
FileStream fileStream = new FileStream(
#"c:\words.txt", FileMode.OpenOrCreate,
FileAccess.ReadWrite, FileShare.None);
now you can use fileStream.Read() and fileStream.Write() methods
please see this link for extended discussion
How to both read and write a file in C#
The problem is that you're trying to write to a file that is used by the StreamReader. You have to close it or - better - use the using-statement which disposes/closes it even on error.
using(StreamReader sr = new StreamReader(#"C:\abc.txt"))
{
// ...
}
File.WriteAllLines(...);
File.WriteAllLines also writes all lines to the file not only the currrent line, so it's pointless to do it in the loop.
Can i suggest you a different method to read the lines of a text-file? You can use File.ReadAllLines which reads all lines into a string[] or File.ReadLines which works similar to a StreamReader by reading all lines lazily.
Here's a version doing the same but using a ( more readable?) LINQ query:
var lines = File.ReadLines(#"C:\abc.txt")
.Where(l => l.StartsWith("<") && l.IndexOf('{') == 29)
.Select(l =>
{
int start = l.IndexOf("{");
int end = l.IndexOf("}", start);
string result = l.Substring(start + 1, end - start - 1);
Guid g = Guid.NewGuid();
return l.Replace(result, g.ToString());
}).ToList();
File.WriteAllLines(#"C:\abc.txt", lines);
Problem is that you have opened the file and reading from same file at the same time you are writing in that file. But what you should do is,
Read the changes from the file
Close the file
Write the contents back to file
So your code should be like
List<string> myAppendedList = new List<string>();
using (StreamReader sr = new StreamReader(#"C:\abc.txt"))
{
string line;
line = sr.ReadLine();
while (line != null)
{
if (line.StartsWith("<"))
{
if (line.IndexOf('{') == 29)
{
string s = line;
int start = s.IndexOf("{");
int end = s.IndexOf("}");
string result = s.Substring(start + 1, end - start - 1);
Guid g = Guid.NewGuid();
line = line.Replace(result, g.ToString());
myAppendedList.Add(line);
}
}
Console.WriteLine(line);
line = sr.ReadLine();
}
}
if(myAppendedList.Count > 0 )
File.WriteAllLines(#"C:\abc.txt", myAppendedList);
I have a log file that is not more than 10KB (File size can go up to 2 MB max) and I want to find if atleast one group of these strings occurs in the files. These strings will be on different lines like,
ACTION:.......
INPUT:...........
RESULT:..........
I need to know atleast if one group of above exists in the file. And I have do this about 100 times for a test (each time log is different, so I have reload and read the log), so I am looking for fastest and bets way to do this.
I looked up in the forums for finding the fastest way, but I dont think my file is too big for those silutions.
Thansk for looking.
I would read it line by line and check the conditions. Once you have seen a group you can quit. This way you don't need to read the whole file into memory. Like this:
public bool ContainsGroup(string file)
{
using (var reader = new StreamReader(file))
{
var hasAction = false;
var hasInput = false;
var hasResult = false;
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
if (!hasAction)
{
if (line.StartsWith("ACTION:"))
hasAction = true;
}
else if (!hasInput)
{
if (line.StartsWith("INPUT:"))
hasInput = true;
}
else if (!hasResult)
{
if (line.StartsWith("RESULT:"))
hasResult = true;
}
if (hasAction && hasInput && hasResult)
return true;
}
return false;
}
}
This code checks if there is a line starting with ACTION then one with INPUT and then one with RESULT. If the order of those is not important then you can omit the if () else if () checks. In case the line does not start with the strings replace StartsWith with Contains.
Here's one possible way to do it:
StreamReader sr;
string fileContents;
string[] logFiles = Directory.GetFiles(#"C:\Logs");
foreach (string file in logFiles)
{
using (StreamReader sr = new StreamReader(file))
{
fileContents = sr.ReadAllText();
if (fileContents.Contains("ACTION:") || fileContents.Contains("INPUT:") || fileContents.Contains("RESULT:"))
{
// Do what you need to here
}
}
}
You may need to do some variation based on your exact implementation needs - for example, what if the word spans two lines, does the line need to start with the word, etc.
Added
Alternate line-by-line check:
StreamReader sr;
string[] lines;
string[] logFiles = Directory.GetFiles(#"C:\Logs");
foreach (string file in logFiles)
{
using (StreamReader sr = new StreamReader(file)
{
lines = sr.ReadAllLines();
foreach (string line in lines)
{
if (line.Contains("ACTION:") || line.Contains("INPUT:") || line.Contains("RESULT:"))
{
// Do what you need to here
}
}
}
}
Take a look at How to Read Text From a File. You might also want to take a look at the String.Contains() method.
Basically you will loop through all the files. For each file read line-by-line and see if any of the lines contains 1 of your special "Sections".
You don't have much of a choice with text files when it comes to efficiency. The easiest way would definitely be to loop through each line of data. When you grab a line in a string, split it on the spaces. Then match those words to your words until you find a match. Then do whatever you need.
I don't know how to do it in c# but in vb it would be something like...
Dim yourString as string
Dim words as string()
Do While objReader.Peek() <> -1
yourString = objReader.ReadLine()
words = yourString.split(" ")
For Each word in words()
If Myword = word Then
do stuff
End If
Next
Loop
Hope that helps
This code sample searches for strings in a large text file. The words are contained in a HashSet. It writes the found lines in a temp file.
if (File.Exists(#"temp.txt")) File.Delete(#"temp.txt");
String line;
String oldLine = "";
using (var fs = File.OpenRead(largeFileName))
using (var sr = new StreamReader(fs, Encoding.UTF8, true))
{
HashSet<String> hash = new HashSet<String>();
hash.Add("house");
using (var sw = new StreamWriter(#"temp.txt"))
{
while ((line = sr.ReadLine()) != null)
{
foreach (String str in hash)
{
if (oldLine.Contains(str))
{
sw.WriteLine(oldLine);
// write the next line as well (optional)
sw.WriteLine(line + "\r\n");
}
}
oldLine = line;
}
}
}