C# read line from file with StreamReader with DownloadFileAsync - c#

I am having a problem reading file with StreamReader and while line != null add to textBox1
Code:
using(StreamReader reader = new StreamReader("lastupdate.txt"))
{
string line;
while((line = reader.ReadLine()) != null)
{
textBox1.Text = line;
}
reader.Close();
}
It's not working and I don't know why. I tried to use using StreamReader, I download the file from the URL and I can see in the folder that the file is downloaded. The lastupdate.txt is 1KB in size.
This is my current working code with MessageBox. If I remove the MessageBox, the code doesn't work. It needs some kind of wait or I don't know:
WebClient client = new WebClient();
client.DownloadFileAsync(new Uri(Settings.Default.patchCheck), "lastupdate.txt"); // ok
if(File.Exists("lastupdate.txt"))
{
MessageBox.Show("Lastupdate.txt exist");
using(StreamReader reader = new StreamReader("lastupdate.txt"))
{
string line;
while((line = reader.ReadLine()) != null)
{
textBox1.Text = line;
MessageBox.Show(line.ToString());
}
reader.Close();
}
File.Delete("lastupdate.txt");
}

Try :
StringBuilder sb = new StringBuilder();
using (StreamReader sr = new StreamReader("lastupdate.txt"))
{
while (sr.Peek() >= 0)
{
sb.Append(sr.ReadLine());
}
}
textbox.Text = sb.Tostring();

If you want the text in the text box it would be much more effective to read all of it and then put it into the text box:
var lines = File.ReadAllLines("lastupdate.txt");
textBox1.Lines = lines; //assuming multi-line text box
or:
textBox1.Text = File.ReadAllText("lastupdate.txt");
Edit:
After latest update - you are downloading the file asynchronously - it might not even be there, only partially there or in a state in-between when your code executes.
If you just want the text string in the file don't download it, use DownloadString instead:
string text = "";
using (WebClient wc = new WebClient())
{
text = wc.DownloadString(new Uri(Settings.Default.patchCheck));
}
textBox1.Text = text;

Try this :
using(StreamReader reader = new StreamReader(Path))
{
string line = reader.ReadLine();
while(line != null)
{
textBox1.Text += line;
line = reader.ReadLine()
}
reader.Close();
}

Web Client has a rather bizarre DownloadFileAsync method. The return type is void, so it is not awaitable. Also, that means we do not even get a Task, so ContinueWith is not possible. That leaves us with using the DownloadFileCompleted event.
const string FileName = "lastupdate.txt";
private void DownloadLastUpdate() {
var client = new WebClient();
client.DownloadFileCompleted += ( s, e ) => {
this.UpdateTextBox( e.Error );
client.Dispose();
};
client.DownloadFileAsync( new Uri( Settings.Default.patchCheck ), FileName );
}
I went with an optional exception parameter to relay any exception messages. Feel free to refactor as desired. File.ReadLines yields text line by line, so large files should not use very much memory.
private void UpdateTextBox( Exception exception = null ) {
textBox1.Text = string.Empty;
if ( exception != null ) {
textBox1.Text = exception.Message;
return;
}
if ( !File.Exists( FileName ) ) {
textBox1.Text = string.Format( "File '{0}' does not exist.", FileName );
return;
}
var lines = File.ReadLines( FileName );
textBox1.Text = string.Join( Environment.NewLine, lines );
}

the answer given above is correct, but in your piece of code, just change 1 line:
textBox1.Text += line;

Related

File cannot be accessed because it is being used by another process

I'm kind of new to coding and I've been trying to replace a word in a text file but when I execute the program it gives me the "File is used by another process error"
private void btnSave1_Click(object sender, EventArgs e)
{
string DOB = dateTimePicker1.Value.ToString();
string Fname = txtBFirstName.ToString();
string Lname = txtBLastName.ToString();
string IDnum = txtBIDnum.ToString();
string Address = txtBAddress.ToString();
string nationality = txtBNationality.ToString();
//string gender = cmbGender.SelectedItem.ToString();
// string marrStatus = cmbMaritialStatus.SelectedItem.ToString();
StreamReader read = null;
//write to file
try
{
// var lines = File.ReadAllLines("CV.txt");
string line;
read = new StreamReader("CurriculumVitae.txt");
while ((line = read.ReadLine()) != null)
{
string text = File.ReadAllText("CurriculumVitae.txt");
text = text.Replace("Empty", DOB);
File.WriteAllText("CurriculumVitae.txt",
File.ReadAllText("CurriculumVitae.txt")
.Replace("empty",DOB));
}
}
catch (Exception exc)
{
MessageBox.Show(exc.Message);
}
finally
{
read.Close();
}
//Open Next Form
Education objNextForm = new Education();
objNextForm.Visible = true;
}
Problem from these 3 lines
read = new StreamReader("CurriculumVitae.txt");
string text = File.ReadAllText("CurriculumVitae.txt");
File.WriteAllText("CurriculumVitae.txt"
,File.ReadAllText("CurriculumVitae.txt").Replace("empty",DOB));
Both StreamReader and File.ReadAllText will lock a file. And whenever they try to lock same file it will error
You should try to do thing once. Don't try to open file many times. And don't open same file before it closed
You can just take out this part around your code, as you're not using the StreamReader you created:
while ((line = read.ReadLine()) != null)
{
...
}
And change
File.WriteAllText("CurriculumVitae.txt",
File.ReadAllText("CurriculumVitae.txt");
To
File.WriteAllText("CurriculumVitae.txt", text);
You will want to update your StreamReader to open the file in "shared" mode so that it doesn't lock the file.
See this question for details on how to do that.
First, don't use a StreamReader when you use File.ReadAllText as it's not needed, the other error comes from this line:
File.WriteAllText("CurriculumVitae.txt", File.ReadAllText("CurriculumVitae.txt").Replace("empty", DOB));
You are opening the same file twice, try something like this:
string content = File.ReadAllText("CurriculumVitae.txt").Replace("empty", DOB);
File.WriteAllText("CurriculumVitae.txt", content);
Use either StreamReader or ReadAllText but not both at the same time...
Also I would really suggest to do "usings" wherever possible becuase this helps a lot closing objects (but is not your prime problem here)
// It will free resources on its own.
//
using (StreamReader reader = new StreamReader("file.txt"))
{
line = reader.ReadLine();
}
Console.WriteLine(line);
}

C# IO Stream not working like expected

I have this piece of code here:
private void button1_Click(object sender, EventArgs e)
{
StreamReader sr = new StreamReader("TextFile1.txt");
while ((line = sr.ReadLine()) != null)
{
if (line == textBox1.Text)
{
line = sr.ReadLine();
if (line == textBox2.Text)
{
MessageBox.Show("Logged in! Welcome " + textBox1.Text);
new Form2().Show();
this.Hide();
LoginSucces = true;
}
}
}
sr.Close();
if (LoginSucces == false) MessageBox.Show("Login Failed :(");
}
And it reads from this text:
AverageJavaGuy
Password
Chezzy
Password
The problem is that it doesnt work!
When I type in:
textBox1 = Chezzy.
textBox2 = Password.
it doesnt work...
it only works for AverageJavaGuy.
Does anyone know how to fix this?
Dictionary<string, string> userPass_dict = new Dictionary<string, string>(); // add this at class level
using (StreamReader sr = new StreamReader("TextFile1.txt"))
{
string line = "";
string line2 = "";
while (!sr.EndOfStream)
{
line = sr.ReadLine();
line2 = sr.ReadLine();
userPass_dict.Add(line, line2);
}
}
So it works for the first login/password, but not the second ?
Have you checked your textfile ?
Isn't the problem related to the dot beside "Chezzy" (in you post!) ?
Try to add "Console.WriteLine" or use debugger to fix your code and see what happens it the loop.
Also, I think the inner " sr.ReadLine();" in the loop may cause unexpected "shifting" according to the textfile content, use it carefully...
move line = sr.ReadLine(); to the outside the if statement

How to prevent adding an empty line to my file?

Im creating a text file and the last line is ""
private void lastRunDate()
{
String lastLine = readLastDate();
String[] date = lastLine.Split('/');
DateTime dt = new DateTime(Int32.Parse(date[2]), Int32.Parse(date[0]), Int32.Parse(date[1]));
DateTime currentDT = DateTime.Now;
argValue = 1;
if ((dt.Month == currentDT.Month) && (argValue == 0))
{
MessageBox.Show("This application has already been run this month");
this.Close();
}
}
private void AddRecordToFile()
{
DateTime now = DateTime.Now;
prepareToEmail();
string path = filepath;
bool dirtyData = true;
// This text is added only once to the file.
if (!File.Exists(path))
{
// Create a file to write to.
using (StreamWriter sw = File.CreateText(path))
{
sw.Write(now.ToShortDateString());
}
dirtyData = false;
}
if (dirtyData)
{
// This text is always added, making the file longer over time
// if it is not deleted.
using (StreamWriter sw = File.AppendText(path))
{
sw.Write(now.ToShortDateString());
}
}
}
private String readLastDate()
{
using (StreamReader sr = new StreamReader(filepath))
{
// Initialize to null so we are not stuck in loop forever in case there is nothing in the file to read
String line = null;
do
{
line = sr.ReadLine();
// Is this the end of the file?
if (line == null)
{
// Yes, so bail out of loop
return "01/01/1900"; // I had to put something
}
// Is the line empty?
if (line == String.Empty)
{
// Yes, so skip it
continue;
}
// Here you process the non-empty line
return line;
} while (true);
}
}
is what I am using to create the file (or append it)
now is a DateTime object
I used your (Karl) code to create a method called "readLastDate()"
I get the 1st date instead.
I'm probably being way to pragmatic and simple, but skip all the stream stuff and use File class directly like this...
string newLine = "";
if (!isFirstLine)
newLine = Environment.NewLine;
File.AppendAllText(
filePath,
string.Format("{0}{1}", newLine, DateTime.Now.ToString()));
You could use a sw.Write and PRE-pend a linefeed. Unfortunately that will give you an empty line at the start of the file.
Have you tried using the command .Trimend ('\n')?
http://msdn.microsoft.com/en-us/library/system.string.trimend.aspx
Do this:
sw.Write(now.ToShortDateString());
Here is the MSDN documentation for StreamWriter.WriteLine.
Here is the MSDN documentation for StreamWriter.Write.
UPDATE:
Keep using the WriteLine, but change the way you read your values in from the file:
using (StreamReader sr = new StreamReader(path))
{
// Initialize to null so we are not stuck in loop forever in case there is nothing in the file to read
String line = null;
do
{
line = sr.ReadLine();
// Is this the end of the file?
if (line == null)
{
// Yes, so bail out of loop
return;
}
// Is the line empty?
if (line == String.Empty)
{
// Yes, so skip it
continue;
}
// Here you process the non-empty line
} while (true);
}
Adding a record should be a simple matter of calling File.AppendAllText, as pointed out in another answer. Although I would recommend:
File.AppendAllText(filePath, DateTime.Now.ToString() + Environment.NewLine);
To read the last date from the file is also very easy:
string lastGoodLine = "01/01/1900";
using (StringReader sr = new StringReader(filePath))
{
while (!sr.EndOfStream)
{
string line = sr.ReadLine();
if (!string.IsNullOrEmpty(line))
lastGoodLine = line;
}
}
return lastGoodLine;

Changing a part of text line in a file on mouse doubleclick by comparing it with a value

I have a file-message.txt that contains raw data, my application reads the file, parses it and displays the data accordingly in the listview. The raw data contains a word called REC UNREAD meaning the record is unread. So for the first time when message is read it is UNREAD and I display such messages in bold. After I read it(Using doubleclick event) the word REC UNREAD should be changed to REC READ. This is what I have I tried, not working though
private void lvwMessages_MouseDoubleClick_1(object sender, MouseEventArgs e)
{
try
{
ListViewItem item = lvwMessages.SelectedItems[0];
if(item.Font.Bold)
{
lvwMessages.SelectedItems[0].Font = new Font(lvwMessages.Font, FontStyle.Regular);
string tfile = File.ReadAllText("C:\\message.txt");
string m1 = lvwMessages.SelectedItems[0].SubItems[1].Text;
string m2 = lvwMessages.SelectedItems[0].SubItems[2].Text;
//No idea how to go forward from here
This is a sample line in my text file:
+CMGL: 2,"REC UNREAD","+919030665834","","2012/08/10 17:04:15+22"
sample message
In simple words I should be able to search for the line containing m1 and m2(as in the code) and replace the REC UNREAD with REC READ.
This should solve your problem--
ListViewItem item = lvwMessages.SelectedItems[0];
if(item.Font.Bold)
{
lvwMessages.SelectedItems[0].Font = new Font(lvwMessages.Font, FontStyle.Regular);
string tfile = File.ReadAllText("C:\\message.txt");
string m1 = lvwMessages.SelectedItems[0].SubItems[1].Text;
string m2 = lvwMessages.SelectedItems[0].SubItems[2].Text;
string line = string.Empty;
string nfile= "";
using (StreamReader sr = new StreamReader("C:\\message.txt"))
{
while ((line = sr.ReadLine()) != null)
{
if (line.Contains(m2))
{
string pline = line;
string result = line.Replace("REC UNREAD", "REC READ");
nfile= tfile.Replace(pline, result);
}
}
sr.Close();
}
StreamWriter sw = new StreamWriter("C:\\message.txt");
{
sw.Write(nfile);
}
sw.Close();
}
you can try with this code based on IndexOf and Replace
string line = string.Empty;
using (StreamReader sr = new StreamReader("C:\\message.txt"))
{
while ((line = sr.ReadLine()) != null)
{
if (line.IndexOf(m1) > 0 &&
line.IndexOf(m2) )
{
var result = line.Replace(m2, "READ");
}
}
}

Delete specific line from a text file?

I need to delete an exact line from a text file but I cannot for the life of me workout how to go about doing this.
Any suggestions or examples would be greatly appreciated?
Related Questions
Efficient way to delete a line from a text file (C#)
If the line you want to delete is based on the content of the line:
string line = null;
string line_to_delete = "the line i want to delete";
using (StreamReader reader = new StreamReader("C:\\input")) {
using (StreamWriter writer = new StreamWriter("C:\\output")) {
while ((line = reader.ReadLine()) != null) {
if (String.Compare(line, line_to_delete) == 0)
continue;
writer.WriteLine(line);
}
}
}
Or if it is based on line number:
string line = null;
int line_number = 0;
int line_to_delete = 12;
using (StreamReader reader = new StreamReader("C:\\input")) {
using (StreamWriter writer = new StreamWriter("C:\\output")) {
while ((line = reader.ReadLine()) != null) {
line_number++;
if (line_number == line_to_delete)
continue;
writer.WriteLine(line);
}
}
}
The best way to do this is to open the file in text mode, read each line with ReadLine(), and then write it to a new file with WriteLine(), skipping the one line you want to delete.
There is no generic delete-a-line-from-file function, as far as I know.
One way to do it if the file is not very big is to load all the lines into an array:
string[] lines = File.ReadAllLines("filename.txt");
string[] newLines = RemoveUnnecessaryLine(lines);
File.WriteAllLines("filename.txt", newLines);
Hope this simple and short code will help.
List linesList = File.ReadAllLines("myFile.txt").ToList();
linesList.RemoveAt(0);
File.WriteAllLines("myFile.txt"), linesList.ToArray());
OR use this
public void DeleteLinesFromFile(string strLineToDelete)
{
string strFilePath = "Provide the path of the text file";
string strSearchText = strLineToDelete;
string strOldText;
string n = "";
StreamReader sr = File.OpenText(strFilePath);
while ((strOldText = sr.ReadLine()) != null)
{
if (!strOldText.Contains(strSearchText))
{
n += strOldText + Environment.NewLine;
}
}
sr.Close();
File.WriteAllText(strFilePath, n);
}
You can actually use C# generics for this to make it real easy:
var file = new List<string>(System.IO.File.ReadAllLines("C:\\path"));
file.RemoveAt(12);
File.WriteAllLines("C:\\path", file.ToArray());
This can be done in three steps:
// 1. Read the content of the file
string[] readText = File.ReadAllLines(path);
// 2. Empty the file
File.WriteAllText(path, String.Empty);
// 3. Fill up again, but without the deleted line
using (StreamWriter writer = new StreamWriter(path))
{
foreach (string s in readText)
{
if (!s.Equals(lineToBeRemoved))
{
writer.WriteLine(s);
}
}
}
Read and remember each line
Identify the one you want to get rid
of
Forget that one
Write the rest back over the top of
the file
I cared about the file's original end line characters ("\n" or "\r\n") and wanted to maintain them in the output file (not overwrite them with what ever the current environment's char(s) are like the other answers appear to do). So I wrote my own method to read a line without removing the end line chars then used it in my DeleteLines method (I wanted the option to delete multiple lines, hence the use of a collection of line numbers to delete).
DeleteLines was implemented as a FileInfo extension and ReadLineKeepNewLineChars a StreamReader extension (but obviously you don't have to keep it that way).
public static class FileInfoExtensions
{
public static FileInfo DeleteLines(this FileInfo source, ICollection<int> lineNumbers, string targetFilePath)
{
var lineCount = 1;
using (var streamReader = new StreamReader(source.FullName))
{
using (var streamWriter = new StreamWriter(targetFilePath))
{
string line;
while ((line = streamReader.ReadLineKeepNewLineChars()) != null)
{
if (!lineNumbers.Contains(lineCount))
{
streamWriter.Write(line);
}
lineCount++;
}
}
}
return new FileInfo(targetFilePath);
}
}
public static class StreamReaderExtensions
{
private const char EndOfFile = '\uffff';
/// <summary>
/// Reads a line, similar to ReadLine method, but keeps any
/// new line characters (e.g. "\r\n" or "\n").
/// </summary>
public static string ReadLineKeepNewLineChars(this StreamReader source)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
char ch = (char)source.Read();
if (ch == EndOfFile)
return null;
var sb = new StringBuilder();
while (ch != EndOfFile)
{
sb.Append(ch);
if (ch == '\n')
break;
ch = (char)source.Read();
}
return sb.ToString();
}
}
Are you on a Unix operating system?
You can do this with the "sed" stream editor. Read the man page for "sed"
What?
Use file open, seek position then stream erase line using null.
Gotch it? Simple,stream,no array that eat memory,fast.
This work on vb.. Example search line culture=id where culture are namevalue and id are value and we want to change it to culture=en
Fileopen(1, "text.ini")
dim line as string
dim currentpos as long
while true
line = lineinput(1)
dim namevalue() as string = split(line, "=")
if namevalue(0) = "line name value that i want to edit" then
currentpos = seek(1)
fileclose()
dim fs as filestream("test.ini", filemode.open)
dim sw as streamwriter(fs)
fs.seek(currentpos, seekorigin.begin)
sw.write(null)
sw.write(namevalue + "=" + newvalue)
sw.close()
fs.close()
exit while
end if
msgbox("org ternate jua bisa, no line found")
end while
that's all..use #d

Categories