Hey guys, having a bit of trouble here.
So I have a load button that loads the file, and a save button the saves the file. I also have a exit button that closes the program. What I need help with is when I close the program, I wont to check whether there are any StreamReader or StreamWriter things that have not been closed.
Heres what I have so far:
At the top, i declear these guys
bool isDirtyBoolean = false;
string moreData = "";
My load button looks like this
private void loadToolStripMenuItem_Click(object sender, EventArgs e)
{
//begin in the project folder
openFileDialog1.InitialDirectory = Directory.GetCurrentDirectory();
//display the file open dialog box
DialogResult responseDialogResult;
responseDialogResult = openFileDialog1.ShowDialog();
if (responseDialogResult != DialogResult.Cancel)
{ //check that user did not click the cancel button
//create a streamreader object for the selected file,
//read the file contents,
//and display each line of the file in the list box
StreamReader nameStreamReader = new StreamReader(openFileDialog1.FileName);
while (nameStreamReader.Peek() != -1)
{
freindsDataListBox.Items.Add(nameStreamReader.ReadLine());
}
nameStreamReader.Close();
isDirtyBoolean = true;
}
}
And my save button looks like this
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
//begin in the project folder
saveFileDialog1.InitialDirectory = Directory.GetCurrentDirectory();
//display the file save dialog
DialogResult responseDialogResult;
responseDialogResult = saveFileDialog1.ShowDialog();
if (responseDialogResult != DialogResult.Cancel)
{ //check that user did not click the cancel button
//create a streamWriter object and
//then write out the list box items to the file
StreamWriter nameStreamWriter = new StreamWriter(saveFileDialog1.FileName);
int count = freindsDataListBox.Items.Count;
for (int i = 0; i < count; i++)
{
nameStreamWriter.WriteLine(freindsDataListBox.Items[i]);
}
nameStreamWriter.Close();
isDirtyBoolean = true;
freindsDataListBox.Items.Clear();
}
}
My exit button looks like this
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
if (isDirtyBoolean == false)
nameStreamReader.Close();
nameStreamWriter.Close();
this.Close();
}
What I tried to do was set up the bool isDirtyBoolean up top, then when the Stream Reader or Writer closes, sets the bool value to true, so when i exit the app, if its still set to false, it closes them anyway.
But this doesnt work because the isDirtyBoolean value is those private void buttons and I cant get to them.
To keep better track of things in general, close your readers and writers in the same method you open them in, rather than letting them live for the duration of the application.
If you use using they will be disposed of (and closed) automatically. Examples:
Reader:
using (StreamReader reader = new StreamReader(openFileDialog1.FileName)) {
// do your stuff...
} // automatic close.
You can do the same with your writer instance.
Or if you're reading and writing at the same time you can open both and auto-close both at the end like so:
using (StreamReader reader = new StreamReader(openFileDialog1.FileName)) {
using (StreamWriter writer = new StreamWriter(path_to_other_file)) {
// now you're reading and writing
// DO YOUR STUFF
} // closes writer.
} // closes reader.
The reason using works as it does is because of the IDisposable interface which is implemented by both the stream reader and writer classes; in fact any class implementing this interface is a candidate for using the using statement on.
And remember to keep an eye out for caveats in the MSDN documentation like so:
StreamWriter.Dispose always closes stream
StreamWriter.Dispose always closes
stream Disposing a StreamWriter closes
the underlying stream when it is
disposed, even if you use a
constructor where you explicitly
provide the stream. Sometimes you want
to keep the stream open, but this
class doesn't currently provide a
mechanism to do that, except to not
call Dispose, but be sure to call
Flush instead.
First of all, you are closing your streams alright - although I would use "using" statement to make sure they are closed even if there is an exception. So no need to close them when form exits.
Also this is bad coding:
if (isDirtyBoolean == false)
nameStreamReader.Close();
nameStreamWriter.Close();
Your if condition only works on the first statement. You need to put curly braces after if.
Use "using" or write your own try/catch/finally blocks and close your streams in the finally.
I'm assuming this is homework so if your assignment requires you to check the streams you are going to have to declare your streams outside of the methods they are currently declared in. When you declare something in a method it only has scope in that method so the code that is currently in your exit button handler shouldn't even compile.
your missing brackets on your if in your exit button handler.
Related
I have a print form which does the printing jobs.
When I close the print form without printing I click Close button
Close button has
private void Close_Click(object sender, EventArgs e)
{
PublicVariables.PrintData = -1;
PublicVariables.PrintStat = false;
ppc.Document = null;
ppc.Dispose();
streamToRead.Close();
this.Hide();
}
But each time I create a text file to print I delete the old.
Delete method :
public static bool DeleteData()
{
bool result=true;
string pattern = "data??.txt";
string appPath = Path.GetDirectoryName(Application.ExecutablePath);
var matches = Directory.GetFiles(appPath, pattern);
foreach (string file in Directory.GetFiles(appPath).Intersect(matches))
{
try
{
File.Delete(file);
result =true;
}
catch (IOException e1)
{
MessageBox.Show(e1.ToString());
return false;
}
}
return result;
}
But if an IOException occurs can't delete any file.
However form load of all threads I have DeleteData() and this deletes without problem the text data.
Is there a way to delete this text file within in the thread where it's created ?
For those who will advise me to make an hidden form which will delete data. I did it I got always an IOexception error. After few IOexception errors all data??.txt files are erased but it happens randomly.
Here below two procedures which create data??.txt
http://www.turcguide.com/stack/procedures.txt
Here is the CreateDataFile(string fName) and GetNewfName(string oldName) procedures link:
http://turcguide.com/stack/createdatafile.txt
The printpreviewcontroler should block this file as when we cancel a printing document on printer it needs time.
After closing and disposing the printpreviewcontroller form, when I try to delete 4-5 attempts later the file is deleted.
My point of view it comes from printpreviewcontroller.
I created simple program for save/open practice. Made a setup and associated my program with my own datatype, called it .xxx (for practice).
I managed to Save and Open code and data from textbox but only from my program. Double click (or enter from windows-desktop) open up my WindowsForm as it is but there is an empty textbox. I want my saved file to be opened on double click in the same condition as when I open it from my program. How to set that up??
Here is the code of simple app (cant post images but it simple - got 1 label and 1 textbox with open and save buttons):
private void ButOpen_Click(object sender, EventArgs e)
{
textBox1.Text = "";
DialogResult result = openFileDialog1.ShowDialog();
if (result == DialogResult.OK)
{
string data = Read(openFileDialog1.FileName);
textBox1.Text = data;
}
else
{//do nothing }
}
private string Read(string file)
{
StreamReader reader = new StreamReader(file);
string data = reader.ReadToEnd();
reader.Close();
return data;
}
private void ButSave_Click(object sender, EventArgs e)
{
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
saveFileDialog1.Filter = "Something|*.xxx";
DialogResult result = saveFileDialog1.ShowDialog();
string file = saveFileDialog1.FileName.ToString();
string data = textBox1.Text;
Save(file, data);
}
private void Save(string file, string data)
{
StreamWriter writer = new StreamWriter(file);
writer.Write(data);
writer.Close();
}
NOTE:
My similar question was marked as duplicate but it is not, and this question which was referenced as duplicate Opening a text file is passed as a command line parameter does not help me.It's not the same thing...
Just wanted to find out how to configure registry so windows understand and load data inside the file, or to file save data somehow so i can open it with double click.
So someone please help. If something is not clear I will give detailed information just ask on what point.
Thanks
MSDN has some information about this:
https://msdn.microsoft.com/en-us/library/bb166549.aspx
Basically you need to create an entry in the registry so that explorer.exe knows to launch your program when that file is activated (e.g. double-clicked).
Explorer will then pass the path to the file as an argument to your program.
This is what i did in the top of Form1:
string line;
StreamWriter w;
StreamReader sr;
Then in the constructor:
if (File.Exists(#"d:\test.txt"))
{
sr = new StreamReader(#"d:\test.txt");
line = sr.ReadToEnd();
textBox3.Text = line;
sr.Close();
sr.Dispose();
}
w = new StreamWriter(#"d:\test.txt");
Then in textBox3 Text Changed event:
private void textBox3_TextChanged(object sender, EventArgs e)
{
if (w == null)
{
w = new StreamWriter(#"d:\ircbotsettings.txt");
w.Write(line);
w.Write(textBox3.Text);
}
}
Then in Form1 Closing event and also in a button click event i added in both places:
w.Close();
w.Dispose();
In the textBox text changed event im trying to open/create the file again for writing first writing the line if any string in it then write the new text from the textBox.
The problem is when im running now the program its going automatic first to the textBox3 text changed event and throw an exception on the line:
w = new StreamWriter(#"d:\ircbotsettings.txt");
The process cannot access the file 'd:\ircbotsettings.txt' because it is being used by another process
What i want to do is:
When typing any text in the textBox in realtime it will save it to the text file.
When i exit the program and run it again read/load from the text file the text and add/put it in the textBox.
So the text file should contain each time only one string and each time when im running the program it should read/load the string back to the textBox.
No need for a StreamWriter or StreamReader, too much clutter and boilerplate.
I would suggest
txtSettings.Text = System.IO.File.ReadAllText(path_to_file);
and on the Leave or Validated event from the textbox
System.IO.File.WriteAllText(path_to_file, txtSettings.Text);
Don't write to a file on each TextChanged event, or it will write to the file on each keystroke which would prove to be a major bottleneck. Either write to the file on Leave or (Form_Closed if it's in a dialog) or use a Timer to periodically save to the file (and keep track of changes with a boolean that you set to true in the TextChanged event).
Ok I know similar questions have been asked, But I am trying to have a Listbox monitor a text file that is changed by another program. I have it setup to select the top line in the file, and execute a command based off that line, then it deletes top line. I just need the listbox to refresh after deletion and read new top line and continue to read until null. I am also having it monitor if the serialPort is OPEN or not. ( I want it to only loop if the serial Port is closed). I am fairly new to C# so any help is appreciated. My current code:
public partial class Form1 : Form
{
List<string> myList = new List<string>();
public Form1()
{
InitializeComponent();
myList = System.IO.File.ReadLines("textfile").ToList();
this.GPSCOM.DataSource = myList;
GPSCOM.SelectionMode = SelectionMode.One;
myList.FirstOrDefault();
GPSCOM.SetSelected(0, true);
if (serialPort.IsOpen)
{
return;
}
else
{
for(;;)
{
switch ((string)GPSCOM.SelectedItem)
{
case "set1":
var lines = System.IO.File.ReadAllLines("textfile");
System.IO.File.WriteAllLines("textfile", lines.Skip(1).ToArray());
return;
case "set2":
var lines1 = System.IO.File.ReadAllLines("textfile");
System.IO.File.WriteAllLines("textfile", lines1.Skip(1).ToArray());
return;
case "set3":
var lines2 = System.IO.File.ReadAllLines("textfile");
System.IO.File.WriteAllLines("textfile", lines2.Skip(1).ToArray());
return;
}
}
}
}
A FileSystemWatcher would be your best bet.
I would like to ask however if it would be inconvenient to make the other program output to its standard output stream and use ProcessStartInfo in System.Diagnosics to redirect the output. If would be a faster and more direct solution as the data could be moved directly between the two programs instead of using the less indirect file storage method. Cut out the middle man as it were.
You would be better off using a FileSystemWatcher and catching the change notification than continuously polling the contents of the file.
I can't find a solution for this problem:
I write a program, which reads all file in a directory and puts them in a listbox.
When a user select a file from a listbox, the program reads the selected file and prints out some info...
The problem is that after the firs selection my program "stop working". He don't crash, but when I try to select another file he do nothing.
I figured out, that the problem is in:
private String porocilo(String s)
{
file = "/path to file/";
TextReader tr = new StreamReader(file); //<- problem here
//...
tr.close();
return someinfo;
}
//..
//Call function:
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
label1.Text = porocilo(listBox1.SelectedItems[0].ToString());
}
After removing that (problem) line the program normally select files, but without this I can't read files and my program don't do anything.
Can someone tell me where I'm wrong?
Br, Wolfy
If the code you posted is really the code you are using (plus the missing semicolon), then the reason you are not seeing anything happening is because your code keeps opening and reading the same file, not the file the user selected. You are setting file to a constant path/filename and read from that, and you are not making use of the s parameter.
It looks like you have a hard-coded path in your porocilo method. That is, new StreamReader is taking as it's argument, file, not s.
So it will only ever open, one file, not the file you selected.
private String porocilo(String s)
{
//file = "/path to/file" // not sure what this is...???
TextReader tr = new StreamReader(s); //<- fix here
//...
tr.close();
return someinfo;
}
In your List box Selected index change method you need to assign the selected value as shown below
//Call function:
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
label1.Text = porocilo(listBox1.SelectedItem.Text);
}
Also check your "porocilo" function it uses the parameter corectly