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

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);
}

Related

Replacing a certain word in a text file

I know this has been asked a few times, but I have seen a lot of regex etc., and I'm sure there is another way to do this with just a stream reader/writer. Below is my code. I'm trying to replace "tea" with the word "cabbage". Can somebody help? I believe I have the wrong syntax.
namespace Week_9_Exer_4
{
class TextImportEdit
{
public void EditorialControl()
{
string fileName;
string lineReadFromFile;
Console.WriteLine("");
// Ask for the name of the file to be read
Console.Write("Which file do you wish to read? ");
fileName = Console.ReadLine();
Console.WriteLine("");
// Open the file for reading
StreamReader fileReader = new StreamReader("C:\\Users\\Greg\\Desktop\\Programming Files\\story.txt");
// Read the lines from the file and display them
// until a null is returned (indicating end of file)
lineReadFromFile = fileReader.ReadLine();
Console.WriteLine("Please enter the word you wish to edit out: ");
string editWord = Console.ReadLine();
while (lineReadFromFile != null)
{
Console.WriteLine(lineReadFromFile);
lineReadFromFile = fileReader.ReadLine();
}
String text = File.ReadAllText("C:\\Users\\Greg\\Desktop\\Programming Files\\story.txt");
fileReader.Close();
StreamWriter fileWriter = new StreamWriter("C:\\Users\\Greg\\Desktop\\Programming Files\\story.txt", false);
string newText = text.Replace("tea", "cabbage");
fileWriter.WriteLine(newText);
fileWriter.Close();
}
}
}
If you don't care about memory usage:
string fileName = #"C:\Users\Greg\Desktop\Programming Files\story.txt";
File.WriteAllText(fileName, File.ReadAllText(fileName).Replace("tea", "cabbage"));
If you have a multi-line file that doesn't randomly split words at the end of the line, you could modify one line at a time in a more memory-friendly way:
// Open a stream for the source file
using (var sourceFile = File.OpenText(fileName))
{
// Create a temporary file path where we can write modify lines
string tempFile = Path.Combine(Path.GetDirectoryName(fileName), "story-temp.txt");
// Open a stream for the temporary file
using (var tempFileStream = new StreamWriter(tempFile))
{
string line;
// read lines while the file has them
while ((line = sourceFile.ReadLine()) != null)
{
// Do the word replacement
line = line.Replace("tea", "cabbage");
// Write the modified line to the new file
tempFileStream.WriteLine(line);
}
}
}
// Replace the original file with the temporary one
File.Replace("story-temp.txt", "story.txt", null);
In the end i used this : Hope it can help out others
public List<string> EditorialResponse(string fileName, string searchString, string replacementString)
{
List<string> list = new List<string>();
using (StreamReader reader = new StreamReader(fileName))
{
string line;
while ((line = reader.ReadLine()) != null)
{
line = line.Replace(searchString, replacementString);
list.Add(line);
Console.WriteLine(line);
}
reader.Close();
}
return list;
}
}
class Program
{
static void Main(string[] args)
{
TextImportEdit tie = new TextImportEdit();
List<string> ls = tie.EditorialResponse(#"C:\Users\Tom\Documents\Visual Studio 2013\story.txt", "tea", "cockrel");
StreamWriter writer = new StreamWriter(#"C:\Users\Tom\Documents\Visual Studio 2013\story12.txt");
foreach (string line in ls)
{
writer.WriteLine(line);
}
writer.Close();
}
}
}

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;

Filtering a line out of a string c#

I want to read a .txt file in c# and filter a line out of the string and only show that line. If the match is on the first line, i get a good output using streamreader.ReadLine. But if it's on the second line, i need to get it filtered. (i tought by creating a ReadLine loop?)
Thanks in advance
private void comboBox3_SelectedIndexChanged(object sender, EventArgs e)
{
StreamReader sr = new StreamReader(textBox1.Text);
string BoxLM1 = sr.ReadLine();
if (comboBox3.Text == "Anderlecht")
{
if (BoxLM1.Contains("Anderlecht"))
{
label5.Text = BoxLM1;
}
else
{
string BoxLM2 = sr.ReadToEnd();
MessageBox.Show(BoxLM2);
}
You can check all lines at once using File.ReadLines() method and LINQ:
var firstAnderlecht = File.ReadLines(textBox1.Text).FirstOrDefault(s => s.Contains("Anderlecht"));
if (firstAnderlecht != null) {
label5.Text = firstAnderlecht;
}
The ReadLines produces an enumerable of lines from the file; the FirstOrDefault method lets you apply a condition to all lines of the file without a loop, and pick the first line where the condition applies.
If you are manipulating big files i recommend to use this iterator:
private static IEnumerable FileIterator(String filePathe)
{
using (StreamReader streamReader = new StreamReader(filePathe))
{
String line;
while ((line = streamReader.ReadLine()) != null)
{
yield return line;
}
yield break;
}
}
it will prevent the loading of full file to RAM

C# read line from file with StreamReader with DownloadFileAsync

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;

Delete Lines in a textfile

Hi I have a text file with table schema and data when user checks not schema required then i need to delete schema and leave the data . I am using StreamReader to read the file and checking one condition and it should delete all the lines in the file till it satisfies my condition .
Let say if i am checking
using (StreamReader tsr = new StreamReader(targetFilePath))
{
do
{
string textLine = tsr.ReadLine() + "\r\n";
{
if (textLine.StartsWith("INSERT INTO"))
{
// It should leave these lines
// and no need to delete lines
}
else
{
// it should delete the lines
}
}
}
while (tsr.Peek() != -1);
tsr.Close();
Please suggest me how to delete lines and note if textline finds "InsertInto" it should not delete any content from there .
Use a second file where to put only required lines, and, at the end of the process, remove original file and rename new one to target file.
using (StreamReader tsr = new StreamReader(targetFilePath))
{
using (StreamWriter tsw = File.CreateText(targetFilePath+"_temp"))
{
string currentLine;
while((currentLine = tsr.ReadLine()) != null)
{
if(currentLine.StartsWith("A long time ago, in a far far away galaxy ..."))
{
tsw.WriteLine(currentLine);
}
}
}
}
File.Delete(targetFilePath);
File.Move(targetFilePath+"_temp",targetFilePath);
You could use Linq:
File.WriteAllLines(targetFilePath, File.ReadAllLines(targetFilePath).Where(x => x.StartsWith("INSERT INTO")));
You read in the file just the same way you were doing. However, if the line doesn't contain what you are looking for, you simply skip it. In the end, whatever data you are left over with you then write to a new text file.
private void button1_Click(object sender, EventArgs e)
{
StringBuilder newText = new StringBuilder();
using (StreamReader tsr = new StreamReader(targetFilePath))
{
do
{
string textLine = tsr.ReadLine() + "\r\n";
{
if (textLine.StartsWith("INSERT INTO"))
{
newText.Append(textLine + Environment.NewLine);
}
}
}
while (tsr.Peek() != -1);
tsr.Close();
}
System.IO.TextWriter w = new System.IO.StreamWriter(#"C:\newFile.txt");
w.Write(newText.ToString());
w.Flush();
w.Close();
}

Categories