reading and querying a txt/log file using c# - c#

i have created a log file example.txt that records events as
Button1 Click event happen ID=xyz DT:3/1/2015 9:27:32 AM
Button2 Click event happen ID=xyz DT:3/1/2015 9:28:32 AM
Button1 Click event happen ID=xyz DT:3/1/2015 9:29:32 AM
Button2 Click event happen ID=xyz DT:3/1/2015 9:30:32 AM
i can read those file but i will get everything written in the log file.\
i have used the following code
try
{
using(FileStream fileStream = new FileStream("c://temp1/example_logfile.txt",FileMode.Open,FileAccess.Read,FileShare.ReadWrite))
{
using(StreamReader streamReader = new StreamReader(fileStream))
{
this.txt.Text = streamReader.ReadToEnd();
}
}
}
I want to read just the Button1 click event. how do you do that?

Use File.ReadLines and a bit of LINQ to get only the lines you're interested in:
var results = File.ReadLines(filePath).Where(x => x.StartsWith("Button1 Click"));
Now you've got a collection of strings representing the matching lines. If you want to display them in a single TextBox, you can flatten the list back out to a single string:
this.txt.Text = String.Join(", ", results);
Or modify the LINQ statement to get, say, the first match only: (assuming at least one match)
this.txt.Text = File.ReadLines(filePath).First(x => x.StartsWith("Button1 Click"));

What about a solution with StreamReader.ReadLine() combined with String.Contains()
String line;
while (!streamReader.EndOfStream) // <= Check for end of file
{
line = streamReader.ReadLine(); // <=Get a single line
if (line.Contains("Button1")) // <= Check for condition ; line contains 'Button1'
{
this.txt.Text += line + "\n"; // <== Append text with a newline
}
}

Related

Appending to new line will not go to new line

I am trying to append the text from a text box to a new line in a text file and have run into an issue. Lets say that there are already contents in the text file and looks something like this
something
Something
Something<---- Cursor ends here
And the cursor ends where the arrow is pointing (After the g on the last 'something'. If I try to use
File.AppendAllLines(#"Location", new[]{tb.Text});
Or
File.AppendAllText(#"Location", tb.Text + Environment.NewLine);
They will put the text where the cursor is at, not on a new line under the last item in the text file. It works if the cursor is on a new line to begin with but as soon as it ends at the end of the word everything goes on the same line.
Is there something I'm missing? Would using a streamwriter or some other method fix this issue?
It does what you should expect. Your text doesn't init with a newline so it is appended just after the point where the previous text ends, To solve your problem you could open the file before writing in it and try to read the last byte.
bool addNewLine = true;
using (FileStream fs = new FileStream(#"location", FileMode.Open))
using (BinaryReader rd = new BinaryReader(fs))
{
fs.Position = fs.Length - 1;
int last = rd.Read();
// The last byte is 10 if there is a LineFeed
if (last == 10)
addNewLine = false;
}
string allLines = (addNewLine ? Environment.NewLine + tb.Text : tb.Text);
File.AppendAllLines(#"Location", new[]{allLines});
As you can see this a bit more complex but this avoid to read all the file in memory.
Actually, as pointed out in other answers. This is by design. File.AppendAllLines appends text at the end of the file. It does not add a line break before appending text. For this, you will have to read the file somehow and determine if the last character is a line break. There are multiple ways to do this.
The simplest way is to just read all lines and check if the last line is empty. If not, just prepend a line break to your string before passing it to File.AppendAllLines.
However, if dealing with large files, or if you do not want to open the file multiple times - something like the following method will do this whilst still only opening the file once.
public void AppendAllLinesAtNewLine(string path, IEnumerable<string> content)
{
// No file, just append as usual.
if (!File.Exists(path))
{
File.AppendAllLines(path, content);
return;
}
using (var stream = File.Open(path, FileMode.Open, FileAccess.ReadWrite))
using (var reader = new StreamReader(stream))
using (var writer = new StreamWriter(stream))
{
// Determines if there is a new line at the end of the file. If not, one is appended.
long readPosition = stream.Length == 0 ? 0 : -1;
stream.Seek(readPosition, SeekOrigin.End);
string end = reader.ReadToEnd();
if (end.Length != 0 && !end.Equals("\n", StringComparison.Ordinal))
{
writer.Write(Environment.NewLine);
}
// Simple write all lines.
foreach (var line in content)
{
writer.WriteLine(line);
}
}
}
Note: the long readPosition = s.Length == 0 ? 0 : -1; is for handling empty files.
This is exactly what you are asking to do. It appends the text you have to the existing file. If that file is 'wrong', the writer can't help it.
You could make sure the line end is always written to the file, if the file is entirely under your control. Else, you could read every line, append yours to it, and write the entire file back. This is bad for large files obviously:
File.WriteAllLines( #"Location"
, File.ReadAllLines(#"Location")
.Concat(new string[] { text })
);
If you put the Environment.NewLine in front of the text, it should give you the results you're looking for:
File.AppendAllText(#"Location", Environment.NewLine + tb.Text);
Thank you all for your suggestions, here is what I decided to do
FileStream stream = new FileStream("location", FileMode.Open, FileAccess.Read);
char actual = '\0';
if(stream.Length != 0)
{
stream.Seek(-1, SeekOrigin.End);
var lastChar = (byte)stream.ReadByte();
actual = (char)lastChar;
}
stream.Close();
try {
if(addCompT.Text != "")
{
if (actual == '\n' || actual == '\0')
File.AppendAllText("location", addCompT.Text + Environment.NewLine);
else
File.AppendAllText("location", Environment.NewLine + addCompT.Text + Environment.NewLine);
addCompT.Text = "";
}
}
catch(System.UnauthorizedAccessException)
{
MessageBox.Show("Please Run Program As Administrator!");
}
I appreciate everyone's help!

c# , Winform application -search for specific line and replace it with other line

I have a small winform app with a button, which, when clicked, I want to search a text file (file.txt) for a specific word and replace the entire line on which it was found by something else.
Let's say my text file is:
ohad yes no
box cat dog
etc...
I want to search for ohad and once find it replace the line "ohad yes no" to new line "yes I did it"
so the txt file will be:
yes I did it
box cat dog
etc...
This is my code so far:
string lineX;
StringBuilder sb = new StringBuilder();
using (System.IO.StreamReader file = new System.IO.StreamReader(textBox20.Text))
{
while ((lineX = file.ReadLine()) != null)
{
if (lineX.Contains("SRV"))
{
sb.AppendLine(lineX.ToString());
}
}
}
StreamReader streamReader;
streamReader = File.OpenText(textBox20.Text);
string contents = streamReader.ReadToEnd();
streamReader.Close();
StreamWriter streamWriter = File.CreateText(textBox20.Text);
streamWriter.Write(contents.Replace(sb.ToString(), textBox26.Text + textBox29.Text + textBox30.Text + textBox27.Text + textBox28.Text));
streamWriter.Close();
Thanks you all in advance
Ohad
Try this:
// Read file into a string array (NOTE: You should check if exists first!)
string[] Lines = File.ReadAllLines(textBox20.Text);
for(int i=0;i<Lines.Length;i++) {
if(Lines[i].Contains("SRV")) {
Lines[i] = "New value for line";
// if you only want to replace one line, uncomment the next row:
// break;
}
}
// Write array back to file
File.WriteAllLines(textBox20.Text, Lines);
for a starter, how about following these comments i put together.
var s = #"
ohad yes no
box cat dog
";
//split string into array
//go through each item in array
//check if it contains "ohad"
//if so, replace that line with my text
//convert array to string

How to check if a textbox has a line from a TXT File with C#

It's simple what I'm trying to do; when I click a button, my app should check if textBox1.Text has a line from a text file.
Note: I don't want to check if textbox has all the text file in it, just to see if it has a LINE from it.
I tried this with no success:
private void acceptBtn_Click(object sender, EventArgs e)
{
StreamReader sr = new StreamReader(usersPath);
string usersTXT = sr.ReadLine();
if (user_txt.Text == usersTXT)
{
loginPanel.Visible = false;
}
}
Hope someone can help me. Thanks in Advance - CCB
string usersTXT = sr.ReadLine();
Reads exactly one line. So you are only checking if you match the first line in the file.
You want File.ReadALlLines (which also disposes the stream correctly, which you aren't):
if (File.ReadAllLines(usersPath).Contains(user_txt.Text))
{
}
That reads all the lines, enumerates them all checking if your line is in the collection. The only downside to this approach is that it always reads the entire file. If you want to only read until you find your input, you'll need to roll the read loop yourself. Do make sure to use the StreamReader in a using block if you take that route.
You can also just use File.ReadLines (thanks #Selman22) to get the lazy enumeration version of this. I would go with this route personally.
Implemenation that shows this at: http://referencesource.microsoft.com/#mscorlib/system/io/file.cs,675b2259e8706c26
if (File.ReadAllLines(path).Any(x => x == line))
{
// line found
}
Replace x == line with a case-insensitive check or Contains if you want.
Try using the Contains() function on the string:
private void acceptBtn_Click(object sender, EventArgs e)
{
StreamReader sr = new StreamReader(usersPath);
string usersTXT = sr.ReadLine();
if (user_txt.Text.Contains(usersTXT))
{
loginPanel.Visible = false;
}
}

text file: Reading line by line C#

So, let's say i have a text file with 20 lines, with on each line different text.
i want to be able to have a string that has the first line in it, but when i do NextLine(); i want it to be the next line. I tried this but it doesn't seem to work:
string CurrentLine;
int LastLineNumber;
Void NextLine()
{
System.IO.StreamReader file = new System.IO.StreamReader("c:\\test.txt");
CurrentLine = file.ReadLine(LastLineNumber + 1);
LastLineNumber++;
}
How would i be able to do this?
Thanks in advance.
In general, it would be better if you could design this in a way to leave your file open, and not try to reopen the file each time.
If that is not practical, you'll need to call ReadLine multiple times:
string CurrentLine;
int LastLineNumber;
void NextLine()
{
// using will make sure the file is closed
using(System.IO.StreamReader file = new System.IO.StreamReader("c:\\test.txt"))
{
// Skip lines
for (int i=0;i<LastLineNumber;++i)
file.ReadLine();
// Store your line
CurrentLine = file.ReadLine();
LastLineNumber++;
}
}
Note that this can be simplified via File.ReadLines:
void NextLine()
{
var lines = File.ReadLines("C:\\test.txt");
CurrentLine = lines.Skip(LastLineNumber).First();
LastLineNumber++;
}
One simple call should do it:
var fileLines = System.IO.File.ReadAllLines(fileName);
You will want to validate the file exists and of course you still need to watch for blank lines or invalid values but that should give you the basics. To loop over the file you can use the following:
foreach (var singleLine in fileLines) {
// process "singleLine" here
}
One more note - you won't want to do this with large files since it processes everything in memory.
Well, if you really don't mind re-opening the file each time, you can use:
CurrentLine = File.ReadLines("c:\\test.txt").Skip(LastLineNumber).First();
LastLineNumber++;
However, I'd advise you to just read the whole thing in one go using File.ReadAllLines, or perhaps File.ReadLines(...).ToList().
The ReadLine method already reads the next line in the StreamReader, you don't need the counter, or your custom function for that matter. Just keep reading until you reach your 20 lines or until the file ends.
You can't pass a line number to ReadLine and expect it to find that particular line. If you look at the ReadLine documentation, you'll see it doesn't accept any parameters.
public override string ReadLine()
When working with files, you must treat them as streams of data. Every time you open the file, you start at the very first byte/character of the file.
var reader = new StreamReader("c:\\test.txt"); // Starts at byte/character 0
You have to keep the stream open if you want to read more lines.
using (var reader = new StreamReader("c:\\test.txt"))
{
string line1 = reader.ReadLine();
string line2 = reader.ReadLine();
string line3 = reader.ReadLine();
// etc..
}
If you really want to write a method NextLine, then you need to store the created StreamReader object somewhere and use that every time. Somewhat like this:
public class MyClass : IDisposable
{
StreamReader reader;
public MyClass(string path)
{
this.reader = new StreamReader(path);
}
public string NextLine()
{
return this.reader.ReadLine();
}
public void Dispose()
{
reader.Dispose();
}
}
But I suggest you either loop through the stream:
using (var reader = new StreamReader("c:\\test.txt"))
{
while (some_condition)
{
string line = reader.ReadLine();
// Do something
}
}
Or get all the lines at once using the File class ReadAllLines method:
string[] lines = System.IO.File.ReadAllLines("c:\\test.txt");
for (int i = 0; i < lines.Length; i++)
{
string line = lines[i];
// Do something
}

How to read the next line in a text document?

I want to know how to read the next line of a text document.
If I click the button, it should open the text document and read the first line.
Then, if I click the "next" button it should read the next line.
How can I do this second button? In C and other languages there are some commands for this..
You need a StreamReader object and then you can invoke the ReadLine method. Don't forget to add the "#" symbol before file path name.
StreamReader sr = new StreamReader(#"C:\\YourPath.txt");
Then on your button clicks you can do:
var nextLine = sr.ReadLine();
The result of each line will be stored in the nextLine variable.
You can use StreamReader.ReadLine
if (myStreamReader.Peek() >= 0)
{
string line = myStreamReader.ReadLine();
}
If you don't want to keep the file open, you can start by reading all lines into memory using File.ReadAllLines
string[] allLines = File.ReadAllLines(path);

Categories

Resources