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)
Related
I'm wondering if there is a best practice when it comes to working with .tmp file for writing data. I like to make an .tmp that will be use in the filestream and then when I close the writer, I like to rename the file. Is there a way to rename file extension?
FileStream stream2 = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite);
StreamWriter streamWriter2 = new StreamWriter(stream2);
streamWriter2.WriteLine(textToAdd);
streamWriter2.Close();
string changed = Path.ChangeExtension(fileName, .txt);
File.Move(path, changed);
Here's how I would do this:
// Build a FileInfo object for your temp destination, this gives us
// access to a handful of useful file manipulation methods
var yourFile = new FileInfo(#"C:\temp\testfile.tmp");
// open a StreamWriter to write text to the file
using (StreamWriter sw = yourFile.CreateText())
{
// Write your text
sw.WriteLine("Test");
// There's no need to call Close() when you're using usings
}
// "Rename" the file -- this is the fastest way in C#
yourFile.MoveTo(#"C:\temp\testfile.txt");
You can use Path.GetFilenameWithoutExtension to remove the extension and then just add the one you want.
I have seen several post for this problem .I have implemented all suggestion like using flush() , close() method on streamwriter and connection Object,use GC.Collect() to force cleanup,, use using{} to autodispose
I am Doing Simple Get Operation from DB and write to text file ..here is my Code
public void WriteToFile(string ProductName)
{
//Already Got Data from DB and stored in "ProductName"
//saving in File
if (!File.Exists(path11))
{
File.Create(path11);
StreamWriter tw = new StreamWriter(path11);
tw.WriteLine(ProductName+"#"+DateTime.Now.ToString());
tw.Flush();
tw.Close();
}
else if (File.Exists(path11))
{
StreamWriter tw = new StreamWriter(path11, true);
tw.WriteLine(ProductName + "#" + DateTime.Now.ToString());
tw.Flush();
tw.Close();
}
GC.Collect();
}
Another suggestion I Got is to lock the object ..But I cannot implement it ..
Any suggestion would be Helpful
File.Create creates the file and returns an open stream. You don't really need all that logic. Just use new StreamWriter(path11, true) which will create the file if it doesn't exist and append to it if it does. Also using is helpful:
public void WriteToFile(string ProductName)
{
//Get Data from DB and stored in "ProductName"
using (var tw = new StreamWriter(path11, true))
{
tw.WriteLine(ProductName+"#"+DateTime.Now.ToString());
}
}
FileCreate returns a stream which you should use to instantiate StreamWriter:
var file = File.Create(path11);
StreamWriter tw = new StreamWriter(file);
And you should use using blocks to make sure your stream and file is closed when you're finished writing.
I am making simple tool for manipulating images in a database. I want to show the output result in a txt file and because the outcome may be different each time, I want the file to be rewritten with the fresh data every time the data is executed.
Also I want (if possible) to use some default location where the txt file will be created even though I have an App.Config file and that's also an option.
The problem I am having is with this code:
string Resultfile =
System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) +
"\\PictureStatus.txt";
FileStream strm = new FileStream(Resultfile , FileMode.Create);
TextWriter tw = new StreamWriter(strm);
This populates the PictureStatus.txt only once and then I get the same text over and over again. I noticed that if I use some random destination the file is updated. Not sure if it's just random behavior or have something to do with using MyDocuments, but what I need is a way to be sure that I'll rewrite the file with the new data each time, and if possible, use some default destination that will work for other people.
You can try something like this
public partial Form2 : Form
{
public string path = Environment.CurrentDirectory + "/" + "Name.txt";
public Form2()
{
InitializeComponent();
if (!File.Exists(path))
{
File.Create(path);
}
}
private void button2_Click(object sender, EventArgs e)
{
using (StreamWriter sw = new StreamWriter(path, true))
{
sw.WriteLine("This text will be writen in the txt file", true);
sw.Close();
}
}
}
I have add to the button, when I pressed it will be written in the next line every time. If you remove "true" from code, it will be overwritten every time.
So, I'm trying to create a login form, but I need to read and write to files etc, first of all; I'm creating a file then writing 'test' to the file, but if I then delete the file and try and issue my commands at the same time:
FileIO.FileCheck("Usernames.pheonix");
FileIO.WriteFile("Usernames.pheonix", "test");
It pulls me an error;
The process cannot access the file 'C:\Users\XXX\Desktop\Pheonix Launcher\Pheonix\bin\Debug\Usernames.pheonix' because it is being used by another process.
I can't seem to get me head around why it keeps on doing this, here are my Read/Write file:
public static void createFile(String FileName)
{
File.Create(FileName);
}
public static void WriteFile(String File ,String Message)
{
FileStream fs1 = new FileStream(File, FileMode.OpenOrCreate, FileAccess.Write);
StreamWriter writer = new StreamWriter(fs1);
writer.Write(Message);
writer.Close();
}
public static void FileCheck(String fileName)
{
if (File.Exists(fileName))
Console.WriteLine("File exists.");
else
createFile(fileName);
}
File.Create does create a file - and return an open stream to it. Put it in a using block. (Don't just call close on it - that would be a bug because it is not exception safe).
Actually, looking closer I see that you don't need this at all due to FileMode.OpenOrCreate. The file will be created anyway.
I am trying to make a text file in memory, add some lines to it and at the end save the file in a text file. I can handle the savedialog part but I dont know how to get the text file from memory. Any help and tips will be appriciated.
What I am doing so far is:
//Initialize in memory text writer
MemoryStream ms = new MemoryStream();
TextWriter tw = new StreamWriter(ms);
tw.WriteLine("HELLO WORLD!");
tw.WriteLine("I WANT TO SAVE THIS FILE AS A .TXT FILE!);
please note
I will call tw.WriteLine() add more lines in different places so I want to save this at end of program (so this shouldent be wrapped between something like using{} )
UPDATE
StringBuilder seems to be a more reliable option for doing this! I get strange cut-outs in my text file when I do it using MemoryStream.
Thanks.
I think your best option here would be to write to a StringBuilder, and when done, File.WriteAllText. If the contents are large, you might consider writing directly to the file in the first place (via File.CreateText(path)), but for small-to-medium files this should be fine.
var sb = new StringBuilder();
sb.AppendLine("HELLO WORLD!");
sb.AppendLine("I WANT TO SAVE THIS FILE AS A .TXT FILE!");
File.WriteAllText(path, sb.ToString());
Or, something nigh-on the same as #Marc's answer, but different enough that I think it's worth putting out there as a valid solution:
using (var writer = new StringWriter())
{
writer.WriteLine("HELLO WORLD!");
writer.WriteLine("I WANT TO SAVE THIS FILE AS A .TXT FILE!");
File.WriteAllLines(path, writer.GetStringBuilder().ToString());
}
Where path is a string representing a valid file system entry path, predefined by you somewhere in the application.
Assume your SaveFileDialog name is "dialog"
File.WriteAllBytes(dialog.FileName, Encoding.UTF8.GetBytes("Your string"));
or
var text = "Your string";
text += "some other text";
File.WriteAllText(dialog.FileName, text);
also in your own solution you can do this :
MemoryStream ms = new MemoryStream();
TextWriter tw = new StreamWriter(ms);
tw.WriteLine("HELLO WORLD!");
tw.WriteLine("I WANT TO SAVE THIS FILE AS A .TXT FILE!);
// just add this
File.WriteAllBytes(dialog.FileName, ms.GetBuffer());
Something like this.
Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
dlg.FileName = "Document"; // Default file name
dlg.DefaultExt = ".text"; // Default file extension
dlg.Filter = "Text documents (.txt)|*.txt"; // Filter files by extension
// Show save file dialog box
Nullable<bool> result = dlg.ShowDialog();
// Process save file dialog box results
if (result == true)
{
// Save document
using (FileStream file = File.CreateText(dlg.FileName)
{
ms.WriteTo(file)
}
}
I haven't worried about whether the file already exists but this should get you close.
You might need a ms.Seek(SeekOrgin.Begin, 0) too.
Another way of appending text to the end of a file could be:
if (saveFileDialog.ShowDialog() == DialogResult.OK) {
using (var writer = new StreamWriter(saveFileDialog.Filename, true)) {
writer.WriteLine(text);
}
}
supposing that text is the string you need to save into your file.
If you want to append new lines to that string in an easy way, you can do:
var sb = new StringBuilder();
sb.AppendLine("Line 1");
sb.AppendLine("Line 2");
and the resulting string will be sb.ToString()
If you already have a Stream object (in your example, a MemoryStream), you can do the same but replace the line:
using (var writer = new StreamWriter(saveFileDialog.Filename, true)) {
by
using (var writer = new StreamWriter(memoryStream)) {
Edit:
About wrapping the statements inside using:
Take in count that this is not a problem at all. In my first example, all you will have to do is to keep that StringBuilder object, and keep adding lines to it. Once you have what you want, just write the data into a text file.
If you are planning to write more than once to the text file, just clear the StringBuilder everytime you write, in order to not get duplicated data.