I can't solve this error! I get a red underline in VisualStudio 2010 below outfile in the second row. I have written the code exactly as it is in my book.
FileStream outFile = new FileStream("movies.txt", FileMode.Create, FileAccess.Write);
StreamWriter writer = new StreamWriter(outFile);
The error message: A field initializer cannot reference the non-static field, method, or property 'MyMovies.FileManager.outFile'
I also have a question about saving a textfile if there is possible to save or replace a string of text at selected row in a file?
EDIT: The code I use to save
StreamWriter writer = File.CreateText("MinaFilmer/filmer.txt");
writer.WriteLine("Test");
I suspect that in the book, these are local variables, declared inside a method - whereas you're declaring them directly in a class as instance variables.
Do you really want these to be instance variables? Both of them? Where possible, I'd attempt to do this only within a method, so you can keep all the clean-up local to the method.
You could write this:
StreamWriter writer = new StreamWriter(new FileStream("movies.txt",
FileMode.Create, FileAccess.Write));
although you'd be better with:
StreamWriter writer = File.CreateText("movies.txt");
Then:
I also have a question about saving a textfile if there is possible to save or replace a string of text at selected row in a file?
We'd need more detail to answer that, and it really is a separate question, which should be asked separately.
Related
I have 27 csv files containing employee timesheet data with about 2000 lines of data in total, and is growing day by day.
I am writing an application that compiles the data in each file to a single csv file for analysis in Excel. I do this by reading each file, write its contents to a string list and then write the string list to a new file. Below is the code writing the list to the file:
FileStream fs = new FileStream(saveFileDialog1.FileName, FileMode.CreateNew, FileAccess.ReadWrite);
StreamWriter sw = new StreamWriter(fs);
foreach (string l in reader)//reader is a List<string> pouplated earlier
{
sw.WriteLine(l);
}
fs.Close();
reader is a list containing about 1170 lines of timesheet entries. When I query the contentents of reader all of the data is present.
The problem comes when I open the compiled csv, all of the data is present except for the last few lines of the last timesheet file. The compiled file contains only 1167 full lines with line 1168 cut off at some arbitrary point. After scrutinizing different files with different contents I noticed that each file is exactly 160840bytes in size.
For debugging purposes I modified the code like this:
string line = "";//A string to test whether the foreach loop completes
FileStream fs = new FileStream(saveFileDialog1.FileName, FileMode.CreateNew, FileAccess.ReadWrite);
StreamWriter sw = new StreamWriter(fs);
foreach (string l in reader)//reader is a List<string> pouplated earlier
{
line = l;
sw.WriteLine(line);
sw.WriteLine("testline")//write random content to see if it has effect on the data
}
fs.Close();
MessageBox.Show(line);
With this modification the message that pops up after the code is run displays the correct entry that should have been written to the file (but is not); this is evidence that the foreach loop loops through all the data. The compiled file now has a larger size of around 200kB. When I scrutinize it, all of the "testline" lines are added, the actual timesheet entry is still cut off at the same arbitrary point as when the "testline" lines were not written.
In summary:
I'm trying write a string list to a file
All of the necessary data is present in the list
The code loops through all of the data in the list
The final written file does not contain all of the data in the list
Can anyone advise me on what is going wrong? I will try a different approach to write the contents to the file, but I would still like to know what happens here and what I can do to prevent it.
The StreamWriter class has its own buffer, if you don't dispose/close it, the rest of the buffer will be lost, exactly as you've observed.
There are multiple ways to flush this buffer.
You could explicitly flush it:
sw.Flush();
but that's not the advice I would want to give, instead you should dispose of the StreamWriter instance which will also flush the buffer to the underlying stream, and as a general guideline, any object that implements IDisposable should be disposed of when you're done with it.
So modify your code like this:
using (FileStream fs = new FileStream(saveFileDialog1.FileName, FileMode.CreateNew, FileAccess.ReadWrite))
using (StreamWriter sw = new StreamWriter(fs))
{
foreach (string l in reader)//reader is a List<string> pouplated earlier
{
sw.WriteLine(l);
}
}
If you want to dig deeper into how the StreamWriter class works I suggest examining the Reference Source Code of StreamWriter.
I am little confused between two different constructor of StreamReader class i.e
1.StreamReader(Stream)
I know it takes stream bytes as input but the respective output is same.
here is my code using StreamReader(Stream) contructor
string filepath=#"C:\Users\Suchit\Desktop\p022_names.txt";
using(FileStream fs = new FileStream(filepath,FileMode.Open,FileAccess.Read))
{
using(StreamReader sw = new StreamReader(fs))
{
while(!sw.EndOfStream)
{
Console.WriteLine(sw.ReadLine());
}
}
}
2. StreamReader(String)
This conrtuctor takes the physical file path,
where our respective file exists but the output is again same.
Here is my code using StreamReader(String)
string filepath=#"C:\Users\Suchit\Desktop\p022_names.txt";
using (StreamReader sw = new StreamReader(filePath))
{
while(!sw.EndOfStream)
{
Console.WriteLine(sw.ReadLine());
}
}
So, Which one is better? When and where we should use respective code,
so that our code become more optimized and readable?
A class StreamReader (as well as StreamWriter) is just a wrapper for
FileStream, It needs a FileStream to read/write something to file.
So basically you have two options (ctor overloads) :
Create FileStream explicitly by yourself and wrap SR around it
Let the SR create FileStream for you
Consider this scenario :
using (FileStream fs = File.Open(#"C:\Temp\1.pb", FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
using (StreamReader reader = new StreamReader(fs))
{
// ... read something
reader.ReadLine();
using (StreamWriter writer = new StreamWriter(fs))
{
// ... write something
writer.WriteLine("hello");
}
}
}
Both reader and writer works with the same filestream. Now if we change it to :
using (StreamReader reader = new StreamReader(#"C:\Temp\1.pb"))
{
// ... read something
reader.ReadLine();
using (StreamWriter writer = new StreamWriter(#"C:\Temp\1.pb"))
{
// ... write something
writer.WriteLine("hello");
}
}
System.IOException is thrown "The process cannot access the file C:\Temp\1.pb because it is being used by another process... This is because we try to open file with FileStream2 while we still use it in FileStream1. So generally speaking if you want to open file, perform one r/w operation and close it you're ok with StreamReader(string) overload. In case you would like to use the same FileStream for multiple operations or if by any other reason you'd like to have more control over Filestream then you should instantiate it first and pass to StreamReader(fs) .
Which one is better?
None. Both are same. As the name suggests StreamReader is used to work with streams; When you create an instance of StreamReader with "path", it will create the FileStream internally.
When and where we should use respective code
When you have the Stream upfront, use the overload which takes a Stream otherwise "path".
One advantage of using Stream overload is you can configure the FileStream as you want. For example if you're going to work with asynchronous methods, you need to open the file with asynchronous mode. If you don't then operation will not be truly asynchronous.
When at doubt don't hesitate to check the source yourself.
Note that the Stream overload doesn't take a FileStream. This allows you to read data from any sub class of Stream, which allows you to do things like read the result of a web request, read unzipped data, or read decrypted data.
Use the string path overload if you only want to read from a file and you don't need to use the FileStream for anything else. It just saves you from writing a line of code:
using (var stream = File.OpenRead(path))
using (var reader = new StreamReader(stream))
{
...
}
File.OpenText also does the same thing.
Both are same, just overloads, use one of them according to your need. If you have a local file then you can use StreamReader(string path) otherwise if you have just stream from online or some other source then other overload helps you i-e StreamReader(Stream stream)
Well after searching the new open source reference. You can see that the latter internaly expands to the former one. So passing a raw file path into the StreamReader makes him expand it internaly to a FileStream. For me this means, both are equivalent and you can use them as you prefer it.
My personal opinion is to use the latter one, because its less code to write and its more explicit. I don't like the way java is doing it with there thousand bytereader, streamreader, outputreaderreader and so on...
Basically both works same that is doing UTF8Encodeing and use Buffer of 1024 bytes.
But The StreamReader object calls Dispose() on the provided Stream object when StreamReader.Dispose is called.
You can refer the following Stream and String
You can use either of them depending on what you have in hand Stream or String file path.
Hope this makes it clear
StreamReader(string) is just an overload of StreamReader(Stream).
In the context of your question, you are probably better off using the StreamReader(string) overload, just because it means less code. StreamReader(Stream) might be minutely faster but you have to create a FileStream using the string you could have just put straight into the StreamReader, so whatever benefit you gained is lost.
Basically, StreamReader(string) is for files with static or easily mapped paths (as appears to be the case for you), while StreamReader(Stream) could be thought of as a fallback in case you have access to a file programmatically, but it's path is difficult to pin down.
In some code for writing and reading a file first create FileStream object then pass it as an argument to StreamWrite or StreamReader, my question is why they don't just creat StreamWrite or StreamReader ? and does each StreamWrite or StreamReader create FileStream automatically ?
FileStream output=new FileStream(fileName,FileMode.OpenOrCreate,FileAccess.Write);
StreamWriter fileWriter=new StreamWriter(output)
Thanks a lot
You're right, it is possible to instantiate a SteamWriter directly with a FilePath and a FileStream will be created automatically under the hood.
But remember that a StreamWriter is an object that is able to write to any Stream (not just FileStreams); the convenience constructor of creating a FileStream underneath the hood is normally good enough. But if someone has some special need to open up a FileStream with very specific options set, they will first create the FileStream, then pass it to the StreamWriter.
If you want to write or read a file you can use the File class.
File.ReadAllText(path);
File.WriteAllText(path,txt);
File.ReadAllLines(path);
File.WriteAllLines(path,lineArray);
No need to use FileStream..
To answer your question of why StreamWriter and StreamReader need to be passed a FileStream..
So that StreamWriter and StreamReader could be reused..
readStream(new FileStream(path,FileMode.Open));//read file stream
readStream(new NetworkStream(url));//read newtwork stream
readStream(new MemoryStream(object));//read memory stream
public void readStream(StreamReader sr)//general reader method
{
//read stream
}
This method is so general it could read almost any stream thereby reusing the code..
I have two filestreams which collects different information from different files:
FileStream dataStruc = new FileStream("c:\\temp\\dataStruc.txt", FileMode.Create, FileAccess.ReadWrite);
FileStream csvFile = new FileStream("c:\\temp\\" + fileName + ".txt", FileMode.Create, FileAccess.ReadWrite);
StreamWriter sw = new StreamWriter(csvFile);
StreamWriter swc = new StreamWriter(dataStruc);
when both streamwriters are used to get the same piece of information like shown below:
sw.WriteLine(sheet);
swc.WriteLine(sheet);
then sw streamwriter has information from file. Have I set up my filestreams incorrectly?
Assuming you don't get any exceptions/errors and that basic stuff like the correct path for the csvFile FileStream is verified and found to be correct: Try adding a Flush() or propery closing the stream using Close(). Even better: use a using statement.
EDIT
After reading your question again: are you sure you just didn't switch the filestreams?
StreamWriter sw = new StreamWriter(csvFile);
StreamWriter swc = new StreamWriter(dataStruc);
as opposed to
StreamWriter sw = new StreamWriter(dataStruc);
StreamWriter swc = new StreamWriter(csvFile);
Your question and description is rather vague: "both streamwriters are used to get the same piece of information". How would stream writers be used to get information? Also: "sw streamwriter has information from file": could you be more specific? This doesn't make sense.
Whatever the case may be; use the debugger luke!
I suppose that you have conflicting concurrent access to the file by both StreamWriters.
You open the streams with FileMode.Create. See the MSDN documentation (highlights by me):
Specifies that the operating system should create a new file. If the
file already exists, it will be overwritten. This operation requires
FileIOPermissionAccess.Write permission. System.IO.FileMode.Create is
equivalent to requesting that if the file does not exist, use
CreateNew; otherwise, use Truncate.
I am not sure if the second StreamWriter, depending on the order of the initialization, overwrites the file of the first StreamWriter or simply fails. Either way, they do try conflicting work.
Possible solutions:
Make sure the streams access the file only one after the other, e.g. by closing the first stream before the second one accesses the file, e.g. with a using block.
Change the FileMode on the streams so that an existing file does not get overridden if possible. (See the documentation above.)
I have my code like this
IsolatedStorageFileStream ostream = new IsolatedStorageFileStream("Conditions.txt", FileMode.Create, FileAccess.Write, store);
try
{
StreamWriter swi = new StreamWriter(ostream);
swi.WriteLine(System.DateTime.Now.Date.ToString());
swi.Close();
}
This is in a loop, in 2nd iteration when this code runs, streamwriter appends the time to the file, I want it to overwrite.
By giving false as a second parameter i can do that but that works only when we are passing path of the file to stringwriter as first parameter.
Can some one help me with this?
You could try use the CreateNew or Truncate Enum value of the FileMode in the IsolatedStorage Constructor.
http://msdn.microsoft.com/en-us/library/system.io.filemode.aspx
Use FileMode.CreateNew Instead of FileMode.Create. So a new file will be created always.
Write down ostream.Close() or ostream.Dispose() just after swi.Close();
It closes the current stream and releases any resources (such as sockets and file handles) associated with the current stream.