StreamWriter not overwriting while writing a stream - c#

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.

Related

Difference Between StreamReader(string filepath) and StreamReader(Stream _stream)

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.

Passing a FileStream as an argument to StreamWriter

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..

Cannot access the file because it is being used by another process

My web method creates a pdf file in my %temp% folder and that works. I then want to add some custom fields (meta) to that file using the code below.
The class PdfStamper generates an IOException, whether I use its .Close() method or the using block just ends. The process that is still holding on to the file handle is the webdev web server itself (I'm debugging in VS2010 SP1).
private string AddCustomMetaData(string guid, int companyID, string filePath)
{
try
{
PdfReader reader = new PdfReader(filePath);
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
{
PdfStamper st = new PdfStamper(reader, fs);
Dictionary<string, string> info = reader.Info;
info.Add("Guid", guid);
info.Add("CompanyID", companyID.ToString());
st.MoreInfo = info;
st.Close();
}
reader.Close();
return guid;
}
catch (Exception e)
{
return e.Message;
}
}
No matter what I try, it keeps throwing the exception at st.Close();, to be more precise:
The process cannot access the file 'C:\Users[my
username]\AppData\Local\Temp\53b96eaf-74a6-49d7-a715-6c2e866a63c3.pdf'
because it is being used by another process.
Either I'm overlooking something obvious or there's a problem with the PdfStamper class I'm as of yet unaware of. Versions of itextsharp used are 5.3.3.0 and 5.4.0.0, the issue is the same.
Any insight would be greatly appreciated.
EDIT: I'm currently "coding around" the issue, but I haven't found any solution.
Your problem is that you are writing to a file while you are also reading from it. Unlike some file types (JPG, PNG, etc) that "load" all of the data into memory, iTextSharp reads the data as a stream. You either need to use two files and swap them at the end or you can force iTextSharp to "load" the first file by binding your PdfReader to a byte array of the file.
PdfReader reader = new PdfReader(System.IO.File.ReadAllBytes(filePath));
I suggest you to use the FileShare enumerator when you open the file, so Try to open a file with None sharing
File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.None);
Try to .Dispose() your PDF reader (or whatever you use for creating it) when you save the file for the first time
Try this solution if you think its feasible for you - Once the webmethod creates file in Temp folder, you need to copy the file and paste it into other location or same location with different name and pass newly copied file path to your PDF reader.

FileStream, only producing one result?

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.)

How to open a file in memory?

I have see this term branded around but I don't really understand how you open a file in memory.
I have the files written to disk in a temp location but this needs cleaning when a certain form closes and I can't do it when it's open. It's a must that this folder gets emptied. I was wondering if I opened files in memory instead whether it would make a difference?
MemoryStream inMemoryCopy = new MemoryStream();
using (FileStream fs = File.OpenRead(path))
{
fs.CopyTo(inMemoryCopy);
}
// Now you can delete the file at 'path' and still have an in memory copy
I think you want to work with Memory Mapped files added recently to .NET 4.
http://blogs.msdn.com/b/salvapatuel/archive/2009/06/08/working-with-memory-mapped-files-in-net-4.aspx
Memory Mapped Files .NET
I think it means to read the content of that file into memory as a whole and then close the connection to the file. Assuming it's a file that's not too big you could just read it into a byte[]:
byte[] fileContent = File.ReadAllBytes(fileName);
If it's a text file read it into a string using
string fileContent = File.ReadAllText(fileName);
Once you've done that use a StreamReader to read it later as you would a file on disk.
You can use DeleteOnClose parameter of FileStream constructor:
FileStream fs = new FileStream("<Path Here>", FileMode.Create,
FileAccess.ReadWrite, FileShare.None, 1024, FileOptions.DeleteOnClose);
and the file will be deleted when closed.

Categories

Resources