I have to store the contents of a control between sessions. This is what I do:
private void Window_Closing(object sender, CancelEventArgs e)
{
IsolatedStorageFile f = IsolatedStorageFile.GetUserStoreForAssembly();
using(IsolatedStorageFileStream stream = new IsolatedStorageFileStream("somefilename", FileMode.Create, f))
using(StreamWriter writer = new StreamWriter(stream))
{
foreach(string path in searchFoldersListView.Items)
{
writer.WriteLine(path);
}
}
}
This is attached to the Closing event of the window. When debugging, the control goes through all the items, but when I run the program again, the control is empty. It turns out that when I navigate to the file, it's empty. When I change the code to save to a regular file by putting a File.AppendAllText() in the foreach loop, that file is saved just fine. Why is that?
EDIT: reading event handler:
private void Window_Initialized(object sender, EventArgs e)
{
IsolatedStorageFile f = IsolatedStorageFile.GetUserStoreForAssembly();
using(IsolatedStorageFileStream stream = new IsolatedStorageFileStream("somefilename", FileMode.OpenOrCreate, f))
using(StreamReader reader = new StreamReader(stream))
{
string line = reader.ReadLine();
while(line != null)
{
searchFoldersListView.Items.Add(line);
}
}
}
There is a bug in your method that reads from the file. You only read the first line which is probably null. Try the following:
using(StreamReader reader = new StreamReader(stream))
{
string line = reader.ReadLine();
while(line != null)
{
searchFoldersListView.Items.Add(line);
line = reader.ReadLine();
}
}
Related
I've searched multiple solutions and coudnt find the one specificly adressing my issue:
What i want to accomplish is to save a state of checkbox to specific line of file.
I have used identical code for saving patch of file from openFileDialog.
if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
var lines = File.ReadAllLines("patcher.conf");
lines[0] = openFileDialog1.FileName;
File.WriteAllLines("patcher.conf", lines);
}
code above saves file patch in 1st (0 indexed) line of text file, and it works!
But for some reason when i try to do exacly the same thing in :
private void checkexe_CheckedChanged(object sender, EventArgs e)
{
string line;
System.IO.StreamReader file =
new System.IO.StreamReader("patcher.conf");
while ((line = file.ReadLine()) != null)
{
var lines = File.ReadAllLines("patcher.conf");
lines[1] = checkexe.Checked.ToString();
File.WriteAllLines("patcher.conf", lines);
}
file.Close();
}
and save information about state of checkbox in 2nd (1 indexed line of file) the error says :
process cannot access the file because it is being used by another process.
What i do wrong?
Your method for writing the file is flawed. You are opening the file and reading all lines, but for every line, you are then reading all lines again and saving the file in the same loop. This would be the cause of your process cannot access the file because it is being used by another process error.
private void checkexe_CheckedChanged(object sender, EventArgs e)
{
string line;
System.IO.StreamReader file = new System.IO.StreamReader("patcher.conf");
while ((line = file.ReadLine()) != null)
{
var lines = File.ReadAllLines("patcher.conf");
lines[1] = checkexe.Checked.ToString();
File.WriteAllLines("patcher.conf", lines);
}
file.Close();
}
Instead, try below: (untested, but should get you in the right direction)
private void checkexe_CheckedChanged(object sender, EventArgs e)
{
var lines = File.ReadAllLines("patcher.conf");
for(var i = 0; i < lines.Length; i++)
{
if (i == 1)
lines[i] = checkexe.Checked.ToString();
}
File.WriteAllLines("patcher.conf", lines);
}
On the file stream, you have use readwrite
System.IO.FileStream fs = new System.IO.FileStream(txtFilePath.Text, System.IO.FileMode.Open, System.IO.FileAccess.Read,System.IO.FileShare.ReadWrite);
System.IO.StreamReader sr = new System.IO.StreamReader(fs);
I've got this code at the start of the form that reads a file that already exists and sets value of 4 textBoxes accordingly to what it's written inside. How do I proceed if the file hasn't yet been created? Any help would be very appreciated.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
FileStream file = new FileStream("cenaEnergentov.txt", FileMode.Open, FileAccess.Read);
StreamReader sr = new StreamReader(file);
sr.ReadLine();
var textLines = File.ReadAllLines("cenaEnergentov.txt");
foreach (var line in textLines)
{
string[] dataArray = line.Split(';');
textBox1.Text = (dataArray[0]);
textBox2.Text = (dataArray[1]);
textBox3.Text = (dataArray[2]);
textBox4.Text = (dataArray[3]);
}
}
If the uper is a false I'd like to proceed with normal script down below that starts with:
public void trackBar1_Scroll(object sender, EventArgs e)
{
......
Use a simple if statement
// I edit this line according to your comment
if(File.Exists(String.Concat("cenaEnergentov".ToUpper(), ".txt"))
{
// do your job
}
else
{
// call appropriate method
trackBar1_Scroll(this,EventArgs.Empty); // for example
}
Try this before you open the file:
var filename = "filename.txt";
if (!File.Exists(filename))
{
File.Create(filename);
}
This won't account for the fact that you're assigning values without checking to see if they exist first. Implementing that is relatively trivial as well.
It also appears that the FileStream and StreamReader are redundant. Just use File.ReadAllLines instead.
The previous solutions will work OK... however they don't really answer the big question:
How do I know when to continue?
The best way would be to use a FileSystemWatcher:
var watcher = new FileSystemWatcher(path, ".txt");
watcher.Created += (sender, e) =>
{
if (e.ChangeType == WatcherChangeTypes.Created)
initForm();
};
Where initForm() is:
void initForm()
{
if(File.Exists(path))
{
// Update form
}
else
{
var watcher = new FileSystemWatcher(path, ".txt");
watcher.Created += (sender, e) =>
{
if (e.ChangeType == WatcherChangeTypes.Created)
initForm();
};
}
}
try this
if(File.Exists("yourFile.txt"))
{
//do what you do
}
else
{
// call appropriate method
}
I have a text file with about 5,000 lines and I want to copy its contents to another file, but only the first 38 characters of each line.
I currently have this code:
private void button1_Click(object sender, EventArgs e)
{
string line, line2;
System.IO.StreamReader file = new System.IO.StreamReader(#"c:\test.txt");
while ((line = file.ReadLine()) != null)
{
line2 = line.Substring(0, 38);
using (System.IO.StreamWriter files = new System.IO.StreamWriter(#"C:\test2.txt"))
{
files.WriteLine(line2);
}
}
file.Close();
}
It only copies the last line. :(
because you rewrite your new file in your loop. You should create your new string in the loop (use a stringBuilder for this will be more efficient), but write the new file out of the loop :
string line;
var sb = new StringBuilder();
System.IO.StreamReader file = new System.IO.StreamReader(#"c:\test.txt");
while ((line = file.ReadLine()) != null)
sb.AppendLine(line.Substring(0, Math.Min(38, line.Length)));
file.Close();
using (System.IO.StreamWriter files = new System.IO.StreamWriter(#"C:\test2.txt"))
{
files.WriteLine(sb.ToString());
}
or to do it shorter
var result = File.ReadAllLines(#"c:\test.txt")
.Select(m => m.Substring(0, Math.Min(38, m.Length)));
File.WriteAllLines(#"C:\test2.txt", result);
You need to move the creation of 'file2' before the while loop.
You should also create 'file' in a using:. You won't need to call close for either one then.
private void button1_Click(object sender, EventArgs e)
{
string line;
using (System.IO.StreamReader file = new System.IO.StreamReader(#"c:\test.txt"))
using (System.IO.StreamWriter file2 = new System.IO.StreamWriter(#"C:\test2.txt"))
while ((line = file.ReadLine()) != null)
{
string line2 = line.Substring(0, 38);
file2.WriteLine(line2);
}
}
Your file's .WriteLine overwrites the entire file every time you call it. Therefore, put the entire code in your using block, or add true to the StreamWriter's arguments to tell it to append to the file instead of overwriting.
Option 1:
private void button1_Click(object sender, EventArgs e)
{
string line, line2;
using (System.IO.StreamWriter files = new System.IO.StreamWriter(#"C:\test2.txt"))
{
System.IO.StreamReader file = new System.IO.StreamReader(#"c:\test.txt");
while ((line = file.ReadLine()) != null)
{
line2 = line.Substring(0, 38);
files.WriteLine(line2);
}
file.Close();
}
}
Option 2:
private void button1_Click(object sender, EventArgs e)
{
string line, line2;
System.IO.StreamReader file = new System.IO.StreamReader(#"c:\test.txt");
while ((line = file.ReadLine()) != null)
{
line2 = line.Substring(0, 38);
using (System.IO.StreamWriter files = new System.IO.StreamWriter(#"C:\test2.txt",true))
{
files.WriteLine(line2);
}
}
file.Close();
}
And finally, if you choose to use a StringBuilder, you can use System.IO.File.WriteAllText(#"C:\test2.txt", stringHere); instead of the entire using and StreamWriter block
I am using this code to import text file to my ListBox
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "Text Files|*.txt";
openFileDialog1.Title = "Select a Text file";
openFileDialog1.FileName = "";
DialogResult result = openFileDialog1.ShowDialog();
if (result == DialogResult.OK)
{
string file = openFileDialog1.FileName;
string[] text = System.IO.File.ReadAllLines(file);
foreach (string line in text)
{
listBox2.Items.Add(line);
}
listBox2.Items.Add("");
}
It works fine for small text files, with 10 lines or so, but when I try to import bigger list, (4-5 megabytes) the program isn't responding and it's crashing.
Any help?
Use the BufferedStream class in C# to improve performance.
http://msdn.microsoft.com/en-us/library/system.io.bufferedstream.aspx
By using this:
string[] text = System.IO.File.ReadAllLines(file);
listBox1.Items.AddRange(text);
instead of this:
string[] text = System.IO.File.ReadAllLines(file);
foreach (string line in text)
{
listBox2.Items.Add(line);
}
you will speed up the execution at least 10-15 times because you are not invalidating listBox on every Item insert.
I have measured with few thousand lines.
The bottleneck could also be ReadAllLines if your text has too many lines. Even though I can't figure out why you would be inserting so many lines, will user be able to find the line he/she needs?
EDIT OK then I suggest you to use BackgroundWorker, here is the code:
First you initialize BackGroundWorker:
BackgroundWorker bgw;
public Form1()
{
InitializeComponent();
bgw = new BackgroundWorker();
bgw.DoWork += new DoWorkEventHandler(bgw_DoWork);
bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted);
}
Then you call it in your method:
private void button1_Click(object sender, EventArgs e)
{
if (!bgw.IsBusy)
{
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "Text Files|*.txt";
openFileDialog1.Title = "Select a Text file";
openFileDialog1.FileName = "";
DialogResult result = openFileDialog1.ShowDialog();
if (result == DialogResult.OK)
{
string file = openFileDialog1.FileName;
listView1.BeginUpdate();
bgw.RunWorkerAsync(file);
}
}
else
MessageBox.Show("File reading at the moment, try later!");
}
void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
listView1.EndUpdate();
}
void bgw_DoWork(object sender, DoWorkEventArgs e)
{
string fileName = (string)e.Argument;
TextReader t = new StreamReader(fileName);
string line = string.Empty;
while ((line = t.ReadLine()) != null)
{
string nLine = line;
this.Invoke((MethodInvoker)delegate { listBox1.Items.Add(nLine); });
}
}
It will add each line when it reads it, you will have responsive UI, and lines won't affect the listBox before it finishes loading.
It maybe simply not completing its job, and you should have to wait for more. Try with this solution:
http://www.bytechaser.com/en/articles/f3a3niqyb7/display-large-lists-in-listview-control-quickly.aspx
could use a stream to store the data:
class Test
{
public static void Main()
{
string path = #"c:\temp\MyTest.txt";
//Create the file.
using (FileStream fs = File.Create(path))
{
AddText(fs, "This is some text");
AddText(fs, "This is some more text,");
AddText(fs, "\r\nand this is on a new line");
AddText(fs, "\r\n\r\nThe following is a subset of characters:\r\n");
for (int i=1;i < 120;i++)
{
AddText(fs, Convert.ToChar(i).ToString());
}
}
//Open the stream and read it back.
using (FileStream fs = File.OpenRead(path))
{
byte[] b = new byte[1024];
UTF8Encoding temp = new UTF8Encoding(true);
while (fs.Read(b,0,b.Length) > 0)
{
Console.WriteLine(temp.GetString(b));
}
}
}
private static void AddText(FileStream fs, string value)
{
byte[] info = new UTF8Encoding(true).GetBytes(value);
fs.Write(info, 0, info.Length);
}
}
then you event handler
privateasyncvoid Button_Click(object sender, RoutedEventArgs e)
{
UnicodeEncoding uniencoding = new UnicodeEncoding();
string filename = #"c:\Users\exampleuser\Documents\userinputlog.txt";
byte[] result = uniencoding.GetBytes(UserInput.Text);
using (FileStream SourceStream = File.Open(filename, FileMode.OpenOrCreate))
{
SourceStream.Seek(0, SeekOrigin.End);
await SourceStream.WriteAsync(result, 0, result.Length);
}
}
Your application becomes unresponsive because it's waiting for the ReadAllLines method to complete and blocks the UI thread. You may want to read files on a separate thread to avoid blocking the UI. I cannot guarantee that the code below will work without errors but it should give you an idea on how to tackle the problem.
First of all, you'll need a method to append an item to the ListBox:
private void AddListBoxItem(string item)
{
if(!InvokeRequired)
{
listBox2.Items.Add(item);
}
else
{
var callback = new Action<string>(AddListBoxItem);
Invoke(callback, new object[]{item});
}
}
The method above checks if it is executed on UI thread and if yes, it simply adds an item to the listBox2.Items collection; if not, it creates a delegate from itself and invokes that delegate on UI thread.
Next, you'll need to move the code that reads the file to another thread and call AddListBoxItem method. For the sake of readability, let's put that into a separate method:
private void AddFileContentsToList(string fileName)
{
using(var reader = new System.IO.StreamReader(fileName))
{
while(!reader.EndOfStream)
{
var line = reader.ReadLine();
AddListBoxItem(line);
}
}
}
And now we will call the method on a separate thread:
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "Text Files|*.txt";
openFileDialog1.Title = "Select a Text file";
openFileDialog1.FileName = "";
DialogResult result = openFileDialog1.ShowDialog();
if (result == DialogResult.OK)
{
var thread = new Thread(AddFileContentsToList);
thread.Start();
}
Hope this helps!
the text file like this:
id,name,username,password
1,x,js,111
2,y,mm,222
i can read from file and put it on datagridview and this is the code
private void buttonTadd_Click(object sender, EventArgs e)
{
FileStream fs = new FileStream(#"C:\Users\HP\Documents\Visual Studio 2008\Projects\BankServer\TellerFile.txt", FileMode.Append);
StreamWriter sw = new StreamWriter(fs);
sw.WriteLine(textBoxTNumber.Text +","+ textBoxTName.Text +","+ textBoxTUserName.Text +","+ textBoxTPassword.Text);
sw.Close();
dataGridViewTellers.Rows.Clear();
StreamReader sr = new StreamReader(#"C:\Users\HP\Documents\Visual Studio 2008\Projects\BankServer\TellerFile.txt");
string line;
while ((line = sr.ReadLine()) != null)
{
dataGridViewTellers.Rows.Add(line.Split(','));
}
sr.Close();
}
you can use regex pattern matching to read it
File.WriteAllText("Path", Regex.Replace(File.ReadAllText("Path"), "[Pattern]", "Replacement"));
this link may also be helpful