C# richtextbox and reading huge file - c#

I am reading a huge file (hundreds of MB) and displaying it to a richtext box. my program would freeze when I run it. can anybody give me advice? is is because the way I read the file? or is it because there is somekind of limit on richtextbox ? I tried to increase the maxLength properties 2147483647, but it says "property value is not valid is not a valid value for INt32" . My application is 64 bit so why this happens? and how do I make the int32 to be 64 ?
StreamReader sr = new StreamReader(file_name1);
string myLine;
while ((myLine = sr.ReadLine()) != null)
{
richTextBox1.AppendText(myLine+"\n");
count_lines++;
}
sr.Close();
textBox2.Text = count_lines.ToString(); ;

(I'll respond to your comment as an answer, to enhance the readability)
Q: (by John Ryann )
would it be possible to apply pattern for either richTextBox.LoadFile
or File.ReadAllText()? meaning would it be possible to only get lines
which has/which contains a certain string?
A:
StreamReader sr = new StreamReader("#c:\MyBigFile.log");
string line = sr.ReadLine();
while (line != null)
{
if(line.Contains("Error"))
{
richTextBox.Text += line + Environment.NewLine;
}
line = sr.ReadLine();
}
sr.Close();

Related

C# Way to validate test data

I'm running a test where i need to validate data from a linux file. I've defined the path of the file is located (see below). Once i cat the file to read the data contents (irm_dwge_stt_l__xxxx.csv.ovr) how can i validate the data within this file
Also where i have defined the measurementName where can i define what measurements belong within this.
public string validateMeasurement(string measurementName, string domaianName)
{
var processFilePath = "/inputs/ff/ff/actuals/" + measurementName + ".csv.ovr";
var actualItemData = Common.LinuxCommandExecutor.RunLinuxcommand("cat " + processFilePath);
return actualItemData;
}
One way of reading data in C# is to use File.Open.
Running cat and capturing the output is probably not the way to go.
This C# example from https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/file-system/how-to-read-a-text-file-one-line-at-a-time shows you how to read a file line by line.
You can then compare the file line by line to whatever data you are validating against.
Notice, this will probably only works if you are trying to validate a text file.
int counter = 0;
string line;
// Read the file and display it line by line.
System.IO.StreamReader file =
new System.IO.StreamReader(#"c:\test.txt");
while((line = file.ReadLine()) != null)
{
System.Console.WriteLine (line);
counter++;
}
file.Close();
System.Console.WriteLine("There were {0} lines.", counter);
// Suspend the screen.
System.Console.ReadLine();

Difference in number of lines in Editpad Lite and Windows notepad

I have a text file which when opened in Editpad Lite show the number of lines as 2754813 and when it is opened in Windows Notepad showing the number of lines as 2713520. When I read it with a C# programme, it shows the number of lines contained in the text file as 2713520 i.e. the same as in notepad. Wordwrap is turned off in both cases This prevents me from matching the lines with Editpad text file. Would anyone please offer their valuable comment.
int b = 0;
using (StreamWriter Writer = new StreamWriter(path_to_textfile.txt"))
{
using (StreamReader Reader = new StreamReader(lisfile))
{
while ((line = Reader.ReadLine()) != null)
{
Match match = Regex.Match(line, #"");//line break symbol between quotes.
if (match.Success)
{
b++;
if (b == 100000) //I got the count of lines correctly.
{
Writer.WriteLine(line);
}
}
else
{
//Writer.WriteLine(line);
}
}
}
}

How to close file that has been read

So im trying to close a file (transactions.txt) that has been open that i've used to read into a textbox and now I want to save back to the file but the problem debug says that the file is in use so I need to find a way to close it. Can anyone help me with this? Thanks!
SearchID = textBox1.Text;
string ID = SearchID.ToString();
bool idFound = false;
int count = 0;
foreach (var line in File.ReadLines("transactions.txt"))
{
//listView1.Items.Add(line);
if (line.Contains(ID))
{
idFound = true;
}
//Displays Transactions if the variable SearchID is found.
if (idFound && count < 8)
{
textBox2.Text += line + "\r\n";
count++;
}
}
}
private void SaveEditedTransaction()
{
SearchID = textBox1.Text;
string ID = SearchID.ToString();
bool idFound = false;
int count = 0;
foreach (var lines in File.ReadLines("transactions.txt"))
{
//listView1.Items.Add(line);
if (lines.Contains(ID))
{
idFound = true;
}
if (idFound)
{
string edited = File.ReadAllText("transactions.txt");
edited = edited.Replace(lines, textBox2.Text);
File.WriteAllText("Transactions.txt", edited);
}
The problem here is that File.ReadLines keeps the file open while you read it, since you've put the call to write new text to it inside the loop, the file is still open.
Instead I would simply break out of the loop when you find the id, and then put the if-statement that writes to the file outside the loop.
This, however, means that you will also need to maintain which line to replace in.
So actually, instead I would switch to using File.ReadAllLines. This reads the entire file into memory, and closes it, before the loop starts.
Now, pragmatic minds might argue that if you have a lot of text in that text file, File.ReadLines (that you're currently using) will use a lot less memory than File.ReadAllLines (that I am suggesting you should use), but if that's the case then you should switch to a database, which would be much more suited to your purpose anyway. It is, however, a bit of an overkill for a toy project with 5 lines in that file.
Use StreamReader directly with the using statement, for example:
var lines = new List<string>();
using (StreamReader reader = new StreamReader(#"C:\test.txt")) {
var line = reader.ReadLine();
while (line != null) {
lines.Add(line);
line = reader.ReadLine();
}
}
By using the using statement the StreamReader instance will automatically be disposed of after it's done with it.
You can try with this:
File.WriteAllLines(
"transactions.txt",
File.ReadAllLines("transactions.txt")
.Select(x => x.Contains(ID) ? textBox2.Text : x));
It works fine, but if the file is big you have to find other solutions.
You can use the StreamReader class instead of the methods of the File class. In this way you can use, Stream.Close() and Stream.Dispose().

Append Text with StringReader (After reader.ReadLine())

Right now I'm building a game application using c#, which will require loading from text file for the game script. (It's quite a simple visual novel game)
Now when the main form loads, i load the script from the file script.txt
And i declared :
StringReader reader = new StringReader(script);
as a global variable there
Now in the middle of the game where the reader is in the middle of the string script,
I need to append starting from next line of the reader.
Basically what I want to achieve:
Append all texts from "news.txt" to script starting from reader.ReadLine() [i.e. in the middle of the string script]
What will be the most efficient solution to achieve this?
What I know:
StreamReader sr = new StreamReader("news.txt");
string news = sr.ReadToEnd();
//Now how to append 'news' to reader.ReadLine() ??
Edit for more clarification (sorry, this is my first time asking here) :
I will try to explain more about what i'm trying to achieve here.
What i'm having right now :
//global variables
string script;
StringReader reader;
//during form_load
StreamReader sr = new StreamReader("script.txt");
script = sr.ReadToEnd();
reader - new StringReader(script);
//And as the game progresses, I keep on implementing reader.ReadLine()..
//At one point, the program will ask the user, do you want to watch the news?
DialogResult dialogResult = MessageBox("Do you want to watch the news?", , MessageBoxButtons.YesNo
if(dialogResult == DialogResult.Yes)
{
StreamReader newsSr = new StreamReader("news.txt");
string news = newsSr.ReadToEnd();
//now I want to append the contents of 'news' to the string 'script' after reader.ReadLine() - any best way to implement this?
}
One possible way (and i think it's the worst way as well) is by introducing one count variable, to get the starting position of the last reader.ReadLine(),
and execute the desired result using Insert like follows :
script = script.Insert(startIndex, news)
You cannot write into a StringReader.
However, if I understand your latest question I think you want this.
StreamReader sr = new StreamReader("news.txt");
string news = string.Empty;
string line = sr.ReadLine();
while (line != null)
{
news += line;
news += someOtherString;
line = sr.ReadLine();
}
Aside I wouldn't do this with string concatenation. I would do this with a StringBuilder.
Just load the file into memory using File.ReadAllLines().
You can then access this as a string array, without worrying about readers, writers, streams etc.
For example:
// load files as arrays
string[] scriptLinesArray = File.ReadAllLines("script.txt");
string[] newsLinesArray = File.ReadAllLines("news.txt");
// convert arrays to lists
var script = new List<string>(scriptLinesArray);
var news = new List<string>(newsLinesArray );
// append news list to script list
script.AddRange(news);
in the end I was able to resolve this problem.
This is what I used (in case anyone wanna know :))
//I'm using a switch statement, in case reader.ReadLine() == "#(morningnews)"
dialogResult = MessageBox.Show("Do you want to watch the news?", , MessageBoxButtons.YesNo);
if(dialogResult = DialogResult.Yes)
{
StreamReader sr = new StreamReader(directoryName + "\\morningactivities\\morningnews1.txt");
string news = sr.ReadToEnd();
script = script.Replace("#(morningnews)", "#(morningnews)\n" + news);
reader = new StringReader(script);
while (reader.ReadLine() != "#(morningnews)")
continue;
loadNextScript();
}
Thanks for everyone who helped, it gave me the inspiration to actually came up with this.

C#: Using StreamReader to read line from txt file, but Peek() return -1 even there are a lot of lines left

I use Peek() method of StreamReader to check whether there are more lines need to be processed. There are more than 1000 lines in my file, but Peek() suddenly return -1 when it reachs line#750. I checked but seems no differences between line#750 and #751. Even I deleted line#750 and 751, it will still break up at other line.
Below are my codes for your information:
try
{
String ftpserver = ftp + filename;
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpserver));
reqFTP.UsePassive = false;
reqFTP.UseBinary = true;
reqFTP.Proxy = null;
reqFTP.Credentials = new NetworkCredential(username, password);
reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
response = (FtpWebResponse)reqFTP.GetResponse();
stream = response.GetResponseStream();
reader = new StreamReader(stream, ConfigHelper.MyEncoding);
while (reader.Peek() > -1)
{
string x = reader.ReadLine();
if (x != null)
{
//.......
}
}
}
catch (Exception ex)
{
}
finally
{
if (reader != null)
reader.Close();
if (response != null)
response.Close();
}
I tried while ((x = reader.ReadLine()) != null), but an exception of "Cannot access a disposed object" was thrown out.
Finally I figured it out by using:
while (stream.CanRead && (x = reader.ReadLine()) != null)
While it doesn't explain what's going on, I'd personally avoid using Peek. I'd use:
string line;
while ((line = reader.ReadLine()) != null)
{
// Use the line
}
That way you're only reading in one place. It somehow feels more sane than checking whether or not you can read, and then reading.
You can also write a method to create an IEnumerable<string> from a TextReader (or from a Func<TextReader>, or a filename) which can make all of this more pleasant. If you're just reading a file and you're using .NET 4, then File.ReadLines is already built-in.
EDIT: Here's one reason you may be getting -1, from the docs of StreamReader.Peek:
An integer representing the next character to be read, or -1 if there are no characters to be read or if the stream does not support seeking.
Does your stream support seeking?
I'm not sure why Peek Method returns -1 in your case, but the usual way to read lines with the StreamReader Class to the end of the file is to repeatedly call the ReadLine Method until null is returned:
string line;
while ((line = reader.ReadLine()) != null)
{
Console.WriteLine(line);
}
Do you need to use peek? Are you skipping certain lines? If you want to read all lines use this.
while(!sr.EndOfStream)
{
//Do stuff
}
As stated in MSDN, Peek Method not only returns -1 when you reach the end of the stream, but also in case of internal errors:
The Peek method returns an integer value in order to determine whether the end of the file, or another error has occurred. This allows a user to first check if the returned value is -1 before casting it to a Char type.
Maybe check for wrong data conversions in your SQL command, I think this method should work too!
I ran into a similar problem when trying to interact with an application that required authentication. Peek() would return -1 when encountering funky characters (unicode characters?) and ReadLine() was also unreliable and would eventually lockup my application since it seems the process' Standard stream was not closed.
Using the Read() method was the only way I could assure I got ALL lines and characters. Additionally, using the Process' ErrorDataReceived or OutputDataReceived event handlers also proved UNRELIABLE (missing lines). Below is how I solved my problem and insured all lines, and characters, were received:
process.Start();
var stdOutput = process.StandardOutput;
StringBuilder fullMessage = new StringBuilder();
while (true)
{
var character = (char)stdOutput.Read();
fullMessage.Append(character);
//Print Out All Characters
Console.Write(character);
if (fullMessage.ToString().EndsWith("Enter Password: "))
{
//Submit Password To Application
using(StreamWriter writer = process.StandardInput){
writer.Write("somepassword");
writer.Flush();
}
break;
}
}

Categories