Text File writer and reader not working on my WPF - c#

My WPF app crashes whenever I try to click on the write button of my app. The write button is supposed to write a string into a text file and read the string back. I have the string appear on the content section of the write button.
Here is where I think the problem lies.
private void Write_Click(object sender, RoutedEventArgs e)
{
TextWriter writer = new StreamWriter(filelocation);
writer.WriteLine("Welcome to my universe");
TextReader reader = new StreamReader(filelocation);
Write.Content= reader.ReadToEnd();
}
The WPF app crashes with no warnings when I try to build and test it. I have tried removing the other sections of the code, and I have determined that the other parts work fine. How do I stop the WPF app from crashing?

The problem is that you are using the build of the app instead of the debugger to test your code. If you run your code as it is now, you will get an error saying the file you are tying to access is already being used by another process. To fix this you must close the writer before you start the reader with writer.Close();This should fix the issue:
private void Write_Click(object sender, RoutedEventArgs e)
{
TextWriter writer = new StreamWriter(filelocation);
writer.WriteLine("Welcome to my universe");
writer.Close();
TextReader reader = new StreamReader(filelocation);
Write.Content= reader.ReadToEnd();
}

Related

How to monitor a logfile that seems to be open all the time (much like notepad++ does)?

I'm trying to build a small program to monitor my pfirewall.log, but I can't seem to open it.
I found quite many (simple) answers, that all kinda say
// use FilesystemWatcher
// open FileStream
// read from last position to end
// output new lines
The problem here is: The file seems to always be opened by another process already. I guess that's the windows process writing to the file, since it's getting written to all the time, as Notepad++ shows me.
Which means, Notepad++ can for some reason do what I can not: Read the file despite it being opened already.
I initialize my monitor in the constructor:
public FirewallLogMonitor(string path)
{
if (!File.Exists(path))
throw new FileNotFoundException("Logfile not found");
this.file = path;
this.lastPosition = 0;
this.monitor = new FileSystemWatcher(Path.GetDirectoryName(path), Path.GetFileName(path));
this.monitor.NotifyFilter = NotifyFilters.Size;
}
And try to read the file on monitor.Changed event:
private void LogFileChanged(object sender, FileSystemEventArgs e)
{
using (FileStream stream = new FileStream(e.FullPath, FileMode.Open, FileAccess.Read, FileShare.Read))
using (StreamReader reader = new StreamReader(stream))
{
stream.Seek(this.lastPosition, SeekOrigin.Begin);
var newLines = reader.ReadToEnd();
this.lastPosition = stream.Length;
var filteredLines = filterLines(newLines);
if (filteredLines.Count > 0)
NewLinesAvailable(this, filteredLines);
}
}
It always throws the IOException on new FileStream(...) to tell me the file is already in use.
Since Notepad++ does it, there has to be a way I can do it too, right?
**Edit: ** A button does this:
public void StartLogging()
{
this.IsRunning = true;
this.monitor.Changed += LogFileChanged;
this.monitor.EnableRaisingEvents = true;
}
**Edit2: ** This is not a duplicate of FileMode and FileAccess and IOException: The process cannot access the file 'filename' because it is being used by another process, since that one assumes I have control over the writing process. Will try the other suggestions, and report back with results.
If i understand your question you can use the notepad++ itself with a plugin to monitor you need to go to:
plugins -> Document Moniter -> Start to monitor
if you dont have this plugin you can download it here:
http://sourceforge.net/projects/npp-plugins/files/DocMonitor/

Clear Contents of A Text File C# (WinRT)

I am currently working on a project using the Windows Runtime and I have run into a roadblock, this was something that was always very easy to do and I feel very frustrated for not getting this right.
I have been sitting for hours and I just cannot seem to get it right. I get the "Access is denied error", also in some variations of my code when I did click on the button, nothing happened. I feel like the answer is staring me right in the face. Here is the code:
private async void btnDtlsSaveChanges(object sender, TappedRoutedEventArgs e)
{
StorageFile del = await Package.Current.InstalledLocation
.GetFileAsync("UserDetails.txt");
await del.DeleteAsync();
StorageFile file = await Package.Current.InstalledLocation.CreateFileAsync
("UserDetails.txt", CreationCollisionOption.OpenIfExists);
using (StreamWriter writer =
new StreamWriter(await file.OpenStreamForWriteAsync()))
{
await writer.WriteLineAsync("Hello World");
}
}
I also tried using ReplaceExisting instead of OpenIfExists:
StorageFile file = await Package.Current.InstalledLocation.CreateFileAsync
("UserDetails.txt", CreationCollisionOption.ReplaceExisting);
using (StreamWriter writer = new StreamWriter(await file.OpenStreamForWriteAsync()))
{
await writer.WriteLineAsync("Hello World");
}
I have tried in several ways, all leading down the same track, and I have looked at every related question on stack overflow, nothing is getting me there.
Any help would be greatly appreciated, thanks in advance.
EDIT: (Solved) Me in my stupidity and the learning of a new technology did not actually realise that there is a difference between the LocalStorage and the actual installed location, thanks to Rob Caplan for guiding me in the right direction.
You get access denied because apps don't have write access to Package.Current.InstalledLocation.
For write access you need to use your application data folders such as Windows.Storage.ApplicationData.Current.LocalFolder
If you want to ship your app with an initial data file and then update the app with user data at runtime you can copy it from InstalledLocation to LocalFolder on first run.
See App data (Windows Runtime apps) and Accessing app data with the Windows Runtime (Windows Runtime apps)
I don't know why you are using await, but the following code should be able to clear the file content for you
using (StreamWriter sw = new StreamWriter("UserDetails.txt", false))
{
sw.WriteLine("Hello world");
}
I used a button for it to test
After Clicking the button the file will be empty.
You need to use using FileMode.Create, It will create a new file or overwrite it.
private void button1_Click(object sender, EventArgs e)
{
using (FileStream NewFileStream = new FileStream(#"C:\Users\Crea\Documents\TCP.txt", FileMode.Create))
{ }
//using (StreamWriter sw = new StreamWriter(#"C:\Users\Crea\Documents\TCP.txt", true))
// {
// sw.WriteLine("Hello");
// }
}

Read updated text file every x seconds

I am working on making a program that is going to read xy coordinates in a text file from a drawing application. I am thinking that the sets of coordinates will start getting detected from the start to the end of the drawn line. For each line drawn there is gonna be a new set of xy coordinates. Then I want to make a program that is
Going to look for updated sets of xy coordinates every x seconds
If the text file is updated I want the new contents of the text file to be written in the console
If the file is not yet updated I don't want it to do anything
Also I am wondering if the best thing is to
Have a single text file that get its contents changed with the new set of xy coordinates?
Or to have a single text file that get the new set of xy coordinates addes to the previous sets of coordinates?
Or have a new text file to be created for every new set of xy coordinates?
I am really new to programming and would really appreciate if I got some kind of help. I have been programming in C# in Visual Studio. I am pretty sure I need to use FileSystemWatcher, I just don't know how to use it....
So far I have only done this:
class Test
{
public static void Main()
{
while (true)
{
try
{
using (StreamReader sr = new StreamReader("TestFile.txt"))
{
String line = sr.ReadToEnd();
Console.WriteLine(line);
}
}
catch (Exception e)
{
Console.WriteLine("This file doesn't excist:");
Console.WriteLine(e.Message);
}
Thread.Sleep(2000);
}
}
}
Initialize a watcher as follows:
FileSystemWatcher watcher = new FileSystemWatcher(_folder_name_)
{
NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.Size
};
watcher.Changed += watcher_Changed;
watcher.EnableRaisingEvents = true;
Event handler:
void watcher_Changed(object sender, FileSystemEventArgs e)
{
if (e.Name == "TestFile.txt")
using (StreamReader sr = new StreamReader(e.FullPath))
{
String line = sr.ReadToEnd();
Console.WriteLine(line);
}
}
Alternative way is to use a System.Threading.Timer.
If a text is appended to the file incrementally, I recommend you to use database, sockets etc instead of file.
Thank you so much for the quick answer and the help! :)
Just before I saw your answer I was working on another way of doing it. The text file will be read and written to the console when the text file exists. When it's read it will be deleted and are waiting for another text file to appear (another set of xy-coordinates). I am not going to have the program to write "Waiting for new file..." in the end, it's just to see that things are working the way I've been thinking. Also I think the Web application need to receive some kind of a message that the text file is read and is now ready to receive a new text file.
Any thoughts if this is an OK way of doing it too?
class Testing
{
public static void Main()
{
string fileName = "TestFile.txt";
while (true)
{
if(File.Exists(fileName))
{
using (StreamReader sr = new StreamReader(fileName))
{
String line = sr.ReadToEnd();
Console.WriteLine(line);
}
}
else
{
Console.WriteLine("Waiting for new file...");
}
File.Delete(fileName);
Thread.Sleep(5000);
}
}
}
Since I'm new, I'm just asking to be sure. I don't know what is going to work out the best when it comes to every part of the system working together. At least I have two ways to work with now! :D

"Cannot access file" when writing to file

I have been working on a clone of notepad and I have run into a problem.
When I try to write the text in the textbox into a file which I create I get the exception:
The process cannot access the file 'C:\Users\opeyemi\Documents\b.txt'
because it is being used by another process.
Below is the code I have written. I would really appreciate any advise on what I should do next.
private void Button_Click_1(object sender, RoutedEventArgs e)
{
SaveFileDialog TextFile = new SaveFileDialog();
TextFile.ShowDialog();
// this is the path of the file i wish to save
string path = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),TextFile.FileName+".txt");
if (!System.IO.File.Exists(path))
{
System.IO.File.Create(path);
// i am trying to write the content of my textbox to the file i created
System.IO.StreamWriter textWriter = new System.IO.StreamWriter(path);
textWriter.Write(textEditor.Text);
textWriter.Close();
}
}
You must "protect" your StremWriter use (both read and write) in using, like:
using (System.IO.StreamWriter textWriter = new System.IO.StreamWriter(path))
{
textWriter.Write(textEditor.Text);
}
no .Close() necessary.
You don't need the System.IO.File.Create(path);, because the StreamWriter will create the file for you (and the Create() returns a FileStream that you keep open in your code)
Technically you could:
File.WriteAllText(path, textEditor.Text);
this is all-in-one and does everything (open, write, close)
Or if you really want to use the StreamWriter and the File.Create:
using (System.IO.StreamWriter textWriter = new System.IO.StreamWriter(System.IO.File.Create(path)))
{
textWriter.Write(textEditor.Text);
}
(there is a StreamWriter constructor that accepts FileStream)

Write data from Textbox into text file in ASP.net with C#

I have a textbox where a user can input their email, what I want to do is make it so that when they click a submit button. That email will be saved into a text file ( on my server ) called emails.txt
I managed to get this working using System.IO and then using the File.WriteAll method. However I want to make it so that it will add the email to the list ( on a new line ) rather then just overwriting whats already in there.
I've seen people mention using Append, but I can't quite grasp how to get it working.
This is my current code (that overwrites instead of appending).
public partial class _Default : Page
{
private string path = null;
protected void Page_Load(object sender, EventArgs e)
{
path = Server.MapPath("~/emails.txt");
}
protected void emailButton_Click(object sender, EventArgs e)
{
File.WriteAllText(path, emailTextBox.Text.Trim());
confirmEmailLabel.Text = "Thank you for subscribing";
}
}
You can use StreamWriter to get working with text file. The WriteLine method in true mode append your email in new line each time....
using (StreamWriter writer = new StreamWriter("email.txt", true)) //// true to append data to the file
{
writer.WriteLine("your_data");
}
From the official MSDN documentation:
using (StreamWriter w = File.AppendText("log.txt"))
{
MyWriteFunction("Test1", w);
MyWriteFunction("Test2", w);
}
Use StreamWriter in Append mode. Write your data with WriteLine(data).
using (StreamWriter writer = new StreamWriter("emails.txt", true))
{
writer.WriteLine(email);
}
Seems like a very easy question with a very easy answer: Open existing file, append a single line
If you post the current code, we can modify that to append instead of overwrite.

Categories