This piece of code worked perfectly in VS 2010. Now that I have VS 2013 it no longer writes to the file. It doesn't error or anything. (I get an alert in Notepad++ stating that the file has been updated, but there is nothing written.)
It all looks fine to me. Any Ideas?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
String line;
try
{
//Pass the file path and file name to the StreamReader constructor
StreamReader sr = new StreamReader("C:\\Temp1\\test1.txt");
StreamWriter sw = new StreamWriter("C:\\Temp2\\test2.txt");
//Read the first line of text
line = sr.ReadLine();
//Continue to read until you reach end of file
while (line != null)
{
//write the line to console window
Console.WriteLine(line);
int myVal = 3;
for (int i = 0; i < myVal; i++)
{
Console.WriteLine(line);
sw.WriteLine(line);
}
//Write to the other file
sw.WriteLine(line);
//Read the next line
line = sr.ReadLine();
}
//close the file
sr.Close();
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e.Message);
}
finally
{
Console.WriteLine("Executing finally block.");
}
}
}
}
You need to close StreamWriter. Like this:
using(var sr = new StreamReader("..."))
using(var sw = new StreamWriter("..."))
{
...
}
This will close streams even if exception is thrown.
You need to Flush() the StreamWriter after write.
By default StreamWriter is buffered that means it won't output until it receives a Flush() or Close() call.
Also you can also try to close it like this:
sw.Close(); //or tw.Flush();
You can also have a look at StreamWriter.AutoFlush Property
Gets or sets a value indicating whether the StreamWriter will flush
its buffer to the underlying stream after every call to
StreamWriter.Write.
The other option which is now a days very popular and recommended is to use the using statement which takes care of it.
Provides a convenient syntax that ensures the correct use of
IDisposable objects.
Example:
using(var sr = new StreamReader("C:\\Temp1\\test1.txt"))
using(var sw = new StreamWriter("C:\\Temp2\\test2.txt"))
{
...
}
Related
I am doing a project Windows form for assignment in Uni, I want to search an already created text file to match a first name and last name then write some additional information if the name and last name exist. I have the code constructed and showing no errors, however when I run and attempt to add information I am being provided with an error which essentially says the next process (Streamreader writer can not access the file as it is already in use by another process) I assume this process is streamreader, I have tried to code it to stop reading to no avail. I am in my first 3 months learning coding and would appreciate some assistance if possible, I have put a snippet of my code below.
//check if there is a file with that name
if (File.Exists(sFile))
{
using (StreamReader sr = new StreamReader(sFile))
{
//while there is more data to read
while (sr.Peek() != -1)
{
//read first name and last name
sFirstName = sr.ReadLine();
sLastName = sr.ReadLine();
}
{
//does this name match?
if (sFirstName + sLastName == txtSearchName.Text)
sr.Close();
}
//Process write to file
using (StreamWriter sw = new StreamWriter(sFile, true))
{
sw.WriteLine("First Name:" + sFirstName);
sw.WriteLine("Last Name:" + sLastName);
sw.WriteLine("Gender:" + sGender);
}
You are using your writer inside the reader, using the same file.
A using disposes the object inside it, after the closing curly braces.
using(StreamReader reader = new StreamReader("foo")){
//... some stuff
using(Streamwriter writer = new StreamWriter("foo")){
}
}
Do it like so :
using(StreamReader reader = new StreamReader("foo")){
//... some stuff
}
using(Streamwriter writer = new StreamWriter("foo")){
}
As per my comment regarding the using statement.
Rearrange to the below. I've tested locally and it seems to work.
using (StreamReader sr = new StreamReader(sfile))
{
//while there is more data to read
while (sr.Peek() != -1)
{
//read first name and last name
sFirstName = sr.ReadLine();
sLastName = sr.ReadLine();
//does this name match?
if (sFirstName + sLastName == txtSearchName.Text)
break;
}
}
using (StreamWriter sw = new StreamWriter(sfile, true))
{
sw.WriteLine("First Name:" + sFirstName);
sw.WriteLine("Last Name:" + sLastName);
sw.WriteLine("Gender:" + sGender);
}
I've replaced the sr.Close with a break statement to exit out. Closing the reader causes the subsequent peek to error as it's closed.
Also, I've noticed that you are not setting gender? unless its set elsewhere.
hope that helps
You can use FileStream. It gives you many options to work with file:
var fileStream = new FileStream("FileName", FileMode.Open,
FileAccess.Write, FileShare.ReadWrite);
var fileStream = new FileStream("fileName", FileMode.Open,
FileAccess.ReadWrite, FileShare.ReadWrite);
I think this is what you want/need. You can't append to a file the way you are trying to do it. Instead you'll want to read your input file, and write a temp file as you are reading through. And, whenever your line matches your requirements, then you can write the line with your modifications.
string inputFile = "C:\\temp\\StreamWriterSample.txt";
string tempFile = "C:\\temp\\StreamWriterSampleTemp.txt";
using (StreamWriter sw = new StreamWriter(tempFile))//get a writer ready
{
using (StreamReader sr = new StreamReader(inputFile))//get a reader ready
{
string currentLine = string.Empty;
while ((currentLine = sr.ReadLine()) != null)
{
if (currentLine.Contains("Clients"))
{
sw.WriteLine(currentLine + " modified");
}
else
{
sw.WriteLine(currentLine);
}
}
}
}
//now lets crush the old file with the new file
File.Copy(tempFile, inputFile, true);
I'm trying to make betting program in C#, storing the user's data in a txt file. I have no problem reading the data from it. However, I can't manage to overwrite it.
From what I've tested, if I call the StreamWriter part alone the overwriting happens just fine. When I put the same code after the StreamReader part, the code will reach the Console.WriteLine("reached"); line and ignore everything after it (username is never written in the console). No error is detected and compilation won't stop either.
Here's the class code:
class Dinero
{
private List<string> data;
private string path = #"C:\Users\yy\Documents\Visual Studio 2015\Projects\ErikaBot\ErikaBot\img\bank_data.txt";
...
some other methods here
...
public void thing(string username, int money)
{
FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
data = new List<string>();
using (StreamReader sr = new StreamReader(fs))
{
string a = sr.ReadLine();
for (int i = 0; a != null; i++)
{
if (a != username)
{
data.Add(a);
}
else i++;
a = sr.ReadLine();
}
}
string b = Convert.ToString(money);
Console.WriteLine("reached");
using (StreamWriter tw = new StreamWriter(fs))
{
Console.WriteLine(username);
if (data != null)
{
for (int i = 0; i < data.Count; i++)
{
tw.WriteLine(data.ElementAt(i));
}
}
string money2 = Convert.ToString(money);
tw.WriteLine(username);
tw.WriteLine(money2);
}
}
}
By disposing StreamReader you also dispose the FileStream.
Either repeat the filestream initialisation before the using statement for StreamWriter or put the latter in the using statement for StreamReader.
I simply want to merge all text files in a given directory, similar to the following command prompt command:
cd $directory
copy * result.txt
I've written the following code, which almost accomplishes what I want, but it's doing something strange. When the StreamWriter writes the first file (or when i = 0), it doesn't actually write any content - the file size remains 0 bytes, despite the first file being ~300 KB. However, the other file writes execute successfully.
If I compare the output from the command prompt to the output from the C# code in diff, you can see that a large block of text is missing. Additionally, the command prompt result is 1,044 KB where the C# result is 700 KB.
string[] txtFiles = Directory.GetFiles(filepath);
using (StreamWriter writer = new StreamWriter(filepath + "result.txt"))
{
for (int i = 0; i < txtFiles.Length; i++)
{
using (StreamReader reader = File.OpenText(txtFiles[i]))
{
writer.Write(reader.ReadToEnd());
}
}
}
Am I using the StreamWriter / StreamReader incorrectly?
Minimalistic implementation, reading the bytes and writing them instead of using a stream for reading - please note, that you should handle the IOException correctly to avoid misbehavior:
var newline = Encoding.ASCII.GetBytes(Environment.NewLine);
var files = Directory.GetFiles(filepath);
try
{
using (var writer = File.Open(Path.Combine(filepath, "result.txt"), FileMode.Create))
foreach (var text in files.Select(File.ReadAllBytes))
{
writer.Write(text, 0, text.Length);
writer.Write(newline, 0, newline.Length);
}
}
catch (IOException)
{
// File might be used by different process or you have insufficient permissions
}
Here, hope it helps you. Note: By copying from a stream to another you save some ram and greatly improve performance.
class Program
{
static void Main(string[] args)
{
string filePath = #"C:\Users\FunkyName\Desktop";
string[] txtFiles = Directory.GetFiles(filePath, "*.txt");
using (Stream stream = File.Open(Path.Combine(filePath, "result.txt"), FileMode.OpenOrCreate))
{
for (int i = 0; i < txtFiles.Length; i++)
{
string fileName = txtFiles[i];
try
{
using (Stream fileStream = File.Open(fileName, FileMode.Open, FileAccess.Read))
{
fileStream.CopyTo(stream);
}
}
catch (IOException e)
{
// Handle file open exception
}
}
}
}
}
I wrote your code , it works properly! only change the line :
using (StreamWriter writer = new StreamWriter(filepath + "result.txt"))
to:
using (StreamWriter writer = new StreamWriter(filepath + "/result.txt"))
i guess you can't see the file because it is saved in another folder .
Im working on a little ATM program and I'm stuck on a StreamWritter problem.
On load, my program must use a StreamReader to read in 4 .txt files all located in my bin/debug. Then the user is asked to either Deposit or Withdraw money from the bank accounts located in the .txt files. Everything works fine for the StreamReader which loads all the bank accounts on program loading and for the StreamWriter to write the changes in the .txt files when I add/remove money.
My problem is when I close the program, the loading of the files works just fine but I can't write in the files anymore. My StreamWriter jumps straight to the Catch part and cannot be instantiated. How is that possible if it worked just fine on first use.
Heres the StreamReader Code :
public bool ReadSavingAccount()
{
string strLine;
string[] strArray;
char[] charArray = new char[] { ',' };
FileStream aFile;
StreamReader sr;
try
{
aFile = new FileStream("mySavingAccount.txt", FileMode.Open);
sr = new StreamReader(aFile);
strLine = sr.ReadLine();
while (strLine != null)
{
strArray = strLine.Split(charArray);
Savings monSave = new Savings(strArray[0], Convert.ToDouble(strArray[1]));
mySavingAccount.Add(monSave);
strLine = sr.ReadLine();
}
sr.Close();
aFile.Close();
}
catch
{
return false;
}
return true;
}
And the StreamWrite Code:
public bool WriteSavingAccount()
{
FileStream aFile;
StreamWriter sw;
string myString;
try
{
aFile = new FileStream("mySavingAccount.txt", FileMode.Create);
sw = new StreamWriter(aFile);
}
catch
{
return false;
}
foreach (Savings mySave in mySavingAccount)
{
myString = mySave.AccountNumber + "," + mySave.AccountBalance;
sw.WriteLine(myString);
}
sw.Close();
return true;
}
Any idea what the problem could be ?
Thanks in advance and let me know if you need any other parts of the code.
Try adding a second parameter of boolean to your StreamWriter call. This is the append parameter. True to append to the file, false to overwrite it.
sw = new StreamWriter(aFile, false);
Create your StreamWriter in a using statement to ensure it is closed properly.
I have a stream reader that I am using to read lines from a stream. This works well however I would like to be able to get the last line which will never end with a line break so the readLine() will not capture it.
I will store this is a global variable and append to the stream before the next run.
Is this possible at all?
void readHandler(IAsyncResult result)
{
tcpClient = (TcpClient)result.AsyncState;
StreamReader reader ;
string line;
using (reader = new StreamReader(stream))
{
while((line = reader.ReadLine()) != null){
System.Diagnostics.Debug.Write(line);
System.Diagnostics.Debug.Write("\n\n");
}
}
getData();
}
ReadLine does capture the final line of the stream even if it doesn't have a line-break after it. For example:
using System;
using System.IO;
class Test
{
static void Main()
{
string text = "line1\r\nline2";
using (TextReader reader = new StringReader(text))
{
string line;
while((line = reader.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
}
}
Prints:
line1
line2
ReadLine() will only return null when it's reached the end of the stream and returned all of the data.
Unless you really need to do this line by line, you could do away with this entire loop and just use the StreamReader.ReadToEnd method. That will give you everything that's currently in the buffer.