Is there anything wrong with this piece of code ? It's opening the file , yet it doesn't write on it.
fl = new FileStream(path, FileMode.OpenOrCreate);
sw = new StreamWriter(fl);
sw.WriteLine("Hello ");
The proper way of doing this would be:
using (StreamWriter sw = new StreamWriter(new FileStream(path, FileMode.OpenOrCreate)))
sw.WriteLine("Hello ");
This will call sw.Flush(), sw.Close() and sw.Dispose().
StreamReader uses a buffer. You can force the output by using Flush(), but in most cases you should just make sure you use using() which will call Dispose at the end and flush all remaining data.
Have you tried to call Flush method?
sw.Flush();
Related
It's like that that right now I'm trying to open my file with FileStream where I saw a little further into the code to use streamwriter compared to writing it into the file every time it goes through Streamwriter.
When it runs through the first time then do it without any problems but as soon as I run it through the second lap. then it fails where it then writes "Stream was not writable"
int count = 0;
using (FileStream fs = new FileStream(#"C:\jpe\Projekt\Utilities\Icons\Icons/WriteLines.txt", FileMode.Append, FileAccess.Write))
{
foreach (SPSite tmpSite in tmpRootColl)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(string.Format("Title {0}", tmpSite.RootWeb.Title));
//Enumerate through each sub-site
foreach (SPWeb tmpWeb in tmpSite.AllWebs)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine(string.Format("Title {0}", tmpWeb.Title));
//Enumerate through each List
foreach (SPList tmpList in tmpWeb.Lists)
{
if (tmpList.BaseTemplate == SPListTemplateType.DocumentLibrary)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine(string.Format("Title {0}", tmpList.Title));
using (StreamWriter outputFile = new StreamWriter(fs)) //Errors come here when it runs the second round through.
{
await outputFile.WriteLineAsync($"{tmpSite.RootWeb.Title} - {tmpList.Title} {count}");
}
count++;
}
}
}
Console.WriteLine("__________________________________________________");
}
}
What I want to achieve with this is that it has to insert text into the file every time it runs through StreamWriter. It should not first make it to the last when it is finished.
i have read:
https://stackoverflow.com/a/7306243/18055701
C# how to update file(leave old data)
Currently you're creating a StreamWriter, writing to it, and disposing it for every list, this is what's causing the issue. Internally the Dispose method closes the underlying stream causing the exception. To solve this we can do one of 2 things
Tell our StreamWriter to not close the underlying stream.
Not dispose our StreamWriter until we're also done with the underlying stream.
Here's how to do #1:
Simply replace your call to the constructor with this
using (StreamWriter outputFile = new StreamWriter(fs, leaveOpen: true))
Here's how to do #2:
Move the using (StreamWriter ... block up to be "one level deeper" than the using (FileStream ... block
using (FileStream fs = new FileStream("..."))
{
using (StreamWriter outputFile = new StreamWriter(fs))
{
// Your foreach loops here
}
}
Personally I'd go with #2 as I'm not a fan of creating and disposing objects in a loop
Assuming you are using at least .NET framework 4.5.
The StreamWriter closes the base stream in its Dispose() method. You can adjust that behavior by using another construcor: https://learn.microsoft.com/en-us/dotnet/api/system.io.streamwriter.-ctor?view=netcore-3.1#system-io-streamwriter-ctor(system-io-stream-system-text-encoding-system-int32-system-boolean)
Here is my code. :
FileStream fileStreamRead = new FileStream(pathAndFileName, FileMode.OpenOrCreate, FileAccess.Read, FileShare.None);
FileStream fileStreamWrite = new FileStream(reProcessedFile, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
StreamWriter sw = new StreamWriter(fileStreamWrite);
int readIndex = 0;
using (StreamReader sr = new StreamReader(fileStreamRead))
{
while (!sr.EndOfStream) {
Console.WriteLine("eof" + sr.EndOfStream);
readIndex++;
Console.WriteLine(readIndex);
string currentRecord = "";
currentRecord = sr.ReadLine();
if (currentRecord.Trim() != "")
{
Console.WriteLine("Writing " + readIndex);
sw.WriteLine(currentRecord);
}
else {
Console.WriteLine("*******************************************spaces ***********************");
}
}
It is cutting off 2 lines with one test file and half a line, and then 1 line and half a line with the other test file I am running it against.
I am not a streamreader/writer expert you can probably see.
Any ideas or suggestions would be greatly appreciated as this is driving me batty. I am sure it is me using these incorrectly.
You are missing Flush/Close or simply using for your writer.
using(FileStream fileStreamWrite =
new FileStream(reProcessedFile, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
{
using(StreamWriter sw = new StreamWriter(fileStreamWrite))
{
// .... write everything here
}
}
Right after the closing brace of the using statement, do this:
sw.Flush();
sw.Close();
There, that should do it.
You need to Flush your StreamWriter. A StreamWriter has a buffer, and it writes to disk only when the buffer is full. By flushing at the end you make sure all the text in the buffer is written to the disk.
In addition to other answers (use using, and/or flush/close), would say that they do not actually respond to the question: "why it may cut several lines."
I have an idea on subject that it is related to a fact that you use StreamReader and call EndOfStream twice: in a while loop header, and another inside it.
The only possible way of understanding if the stream ends is try to read some data from it. So I suspect EnfOfStream does it, and reading it twice, may create a problem in stream processing.
To resolve an issue:
Or use simple TextReader, considering that you are reading text file (seems to me)
Or change your logic to call only once, so no more call to Console.WriteLine("eof" + sr.EndOfStream);
Or change your logic, so do not use EndOFStream at all, but read line by line till the line is null.
You're not using StreamWriter properly. Also, since you're always reading lines, I would use a method that already does all that for you (and manages it properly).
using (var writer = new StreamWriter("path"))
{
foreach(var line in File.ReadLines("path"))
{
if (string.IsNullOrWhiteSpace(line))
{ /**/ }
else
{ /**/ }
}
}
... or ...
/* do not call .ToArray or something that will evaluate this _here_, let WriteAllLines do that */
var lines = File.ReadLines("path")
.Select(line => string.IsNullOrWhiteSpace(line) ? Stars : line);
var encoding = Encoding.ASCII; // whatever is appropriate for you.
File.WriteAllLines("path", lines, encoding);
I used the following code to write on *.txt file, but nothing happens. Even, there is no exception.
FileStream fs = new FileStream(#"D:\file.txt",FileMode.OpenOrCreate,FileAccess.Write,FileShare.None); //Creating a stream with certain features to a file
StreamWriter writer = new StreamWriter(fs); //Use the fs to write
// writer.WriteLine(Text.Text); none of the following methods works
writer.Write("aaaaaaaaaaaa");
fs.Close();
Thanks
Try to enclose it in a using block like this:
using ( FileStream fs = new FileStream(#"D:\file.txt",FileMode.OpenOrCreate,FileAccess.Write,FileShare.None))
using (StreamWriter fw = new StreamWriter(fs))
{
fw.Write("aaaaaaaaaaaa");
}
A StreamWriter buffers data before writing it to the underlying stream. You need to flushes the buffer by disposing the StreamWriter
I am reading a file using StreamReader fileReader = File.OpenText(filePath). I would like to modify one line in the file in memory and push the modified stream to another method.
What I would like to avoid is reading the whole file into a string and modifying the string (doesn't scale). I would also like to avoid modifying the actual file.
Is there a straightforward way of doing this?
There is no built-in way to do that in .Net framework.
Stream and StreamReader/StreamWriter classes are designed to be chained if necessary (like GZipStream wraps stream to compress it). So you can create wrapper StreamReader and update data as you need for every operation after calling wrapped reader.
You can open two stream -one for read, one for write- at the same time. I tested simple code that works, but not sure that's what you want:
// "2.bar\r\n" will be replaced by "!!!!!\r\n"
File.WriteAllText("test.txt",
#"1.foo
2.bar
3.fake");
// open inputStream for StreamReader, and open outputStream for StreamWriter
using (var inputStream = File.Open("test.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (var reader = new StreamReader(inputStream))
using (var outputStream = File.Open("test.txt", FileMode.Open, FileAccess.Write, FileShare.Read))
using (var writer = new StreamWriter(outputStream))
{
var position = 0L; // track the reading position
var newLineLength = Environment.NewLine.Length;
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
// your particular conditions here.
if (line.StartsWith("2."))
{
// seek line start position
outputStream.Seek(position, SeekOrigin.Begin);
// replace by something,
// but the length should be equal to original in this case.
writer.WriteLine(new String('!', line.Length));
}
position += line.Length + newLineLength;
}
}
/* as a result, test.txt will be:
1.foo
!!!!!
3.fake
*/
As you can see, both streams can be accessed by StreamReader and StreamWriter at the same time. And you can also manipulate both read/write position as well.
I am still newbie to C# and I'm making a test program that writes the DateTime.Now every second. I tried using this and it worked:
StreamWriter sw = new StreamWriter("D:\Hello.txt", true);
sw.WriteLine(DateTime.Now);
sw.Close();
However, when I tried including a FileStream, it didn't work. What seems to be the problem? Here's my code:
FileStream fs = new FileStream(#"D:\Hello.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
StreamWriter sw = new StreamWriter(fs);
sw.WriteLine(DateTime.Now);
sw.Close();
fs.Close();
Note: I am using a timer, it executes the code every second..
Update:
I tried placing the code(the one that has the filestream) inside a button (w/out timer). Whenever I clicked the button, it just replaces the line in the textfile.. This is a code that appends a text to the textfile:
StreamWriter sw = new StreamWriter("D:\Hello.txt", true);
How will I do it in a filestream? I cannot use FileMode.Append in FileStream because it required=s the FileAccess to be write-only.
Since you are executing the code every second then its not a good idea to create FileStream and StreamWriter object everytime, because sometimes the file will remain under lock condition and the filestream will miss to acquire the handle.
As you are writing to single file its good to initialize a FileStream and subsequent StreamWriter in the constructor while leaving the refrence to them in class scope;then calling it every second on a thread for sw.WriteLine(DateTime.Now); should help.
And further never miss try catch in a filestream. They help a lot to locate the discrepancies.
May be try to use File?
File.AppendAllText(#"D:\Hello.txt", DateTime.Now.ToString());
or
File.WriteAllText(#"D:\Hello.txt", DateTime.Now.ToString());
to overwrite
You should use something like this because it works fine for me. If it does not work for you, you have to add more details
using (var fs = new FileStream("path", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
{
fs.Seek(0, SeekOrigin.End);
using (StreamWriter sw = new StreamWriter(fs) { AutoFlush = true })
{
sw.WriteLine("my text");
}
}
But remember I would not create it every second. Why don t you store a Streamwriter object as field when you call Timer.Start?
So you would not have to create it every second. (rememer to dispose it when you stop the timer)
Should work:
FileStream fs = new FileStream(#"D:\Hello.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
StreamWriter sw = new StreamWriter(fs);
sw.WriteLine(DateTime.Now);
sw.Flush();
sw.Close();
fs.Close();
I already solved it.. :) I just have to use FileMode.Append, FileAccess.Write as an argument in the filestream. Reason for not doing FileMode.Append earlier is because it needs FileAccess to be Write only. I thought switching the FileAcess to Write only will prevent the user from reading the file. So stupid of me.. This is my code:
private void timer1_Tick(object sender, EventArgs e)
{
FileStream fs = new FileStream(#"D:\Hello.txt", FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
StreamWriter sw = new StreamWriter(fs);
sw.WriteLine(DateTime.Now);
lbTimer.Items.Add(DateTime.Now);
sw.Close();
fs.Close();
}
Last question, what is setting the FileAccess to Write only for when you can still read it?
Try calling StreamWriter.Flush() before StreamWriter.Close().
You might wanna look here
How to: Write to a Text File (C# Programming Guide)
http://msdn.microsoft.com/en-us/library/8bh11f1k.aspx