I have got a code snippet as follows:
Dim fstream = new filestream(some file here)
dim bwriter = new binarywriter(fstream)
while not end of file
read from source file
bwriter.write()
bwriter.flush()
end while
The question I have is the following. When I call bwriter.flush() does it also flush the fstream object? Or should I have to explicitly call fstream.flush() such as given in the following example:
while not end of file
read from source file
bwriter.write()
bwriter.flush()
fstream.flush()
end while
A few people suggested that I need to call fstream.flush() explicitly to make sure that the data is written to the disk (or the device). However, my testing shows that the data is written to the disk as soon as I call flush() method on the bwriter object.
Can some one confirm this?
According to Reflector, BinaryWriter.Flush calls the Flush method of the underlying stream.
Related
I am using
using (StreamWriter writer = new StreamWriter(Response.OutputStream, System.Text.Encoding.UTF8));
In order to directly write some lines of text and send them to the browser as an attachment.
I now though also want to save that text locally in a file, but Id rather avoid changing too much of my code. Can I write the contents of Response.OutputStream into a text file before ending the response?
I believe what you ask for is not doable. I am quite sure Response.OutpuStream is not seekable (property CanSeek yielding false), meaning you won't be able to get at its start for reading its content. It is probably not readable either (property CanRead yielding false).
Attempting any of those operations would yield a NotSupportedException.
If your needs are for some basic logging, you may work around that by enabling .Net standard network traces. Or code an IHttpModule as suggested here.
Otherwise, you may use an intermediate MemoryStream with your StreamWriter, then reset this MemoryStream to Position 0, write it to OutputStream, reset it again to Position 0, write it to your file.
You can use the CopyTo method of the Stream object. At the end you can copy the whole OutputStream to an other one which write it to a file. (https://msdn.microsoft.com/en-us/library/dd782932(v=vs.110).aspx)
I am doing the following:
if (File.Exists(filePath))
{
string base64 = File.ReadAllText(filePath);
return new ImageContentDTO
{
ImageContentGuid = imageContentGuid,
Base64Data = base64
};
}
This works perfectly fine. What I want to ask is if I need to Close the file or anything similar after I am done reading from it. And if so, how?
No, you don't have to explicitly close the file, File.ReadAllText takes care of that for you.
The documentation contains this information very explicitly:
This method opens a file, reads each line of the file, and then adds each line as an element of a string. It then closes the file.
[...]
The file handle is guaranteed to be closed by this method, even if exceptions are raised.
You don't need to close anything when using File.ReadAllText since the underling stream reader is closed implicitely.
MSDN: File.ReadAllText
Opens a text file, reads all lines of the file, and then closes the
file.
Here's the implementation in .NET 4 (ILSpy):
string result;
using (StreamReader streamReader = new StreamReader(path, encoding))
{
result = streamReader.ReadToEnd();
}
return result;
The using statement disposes the StreamReader (even on error), that also closes it.
I know this question has been answered and this is almost a year now but for those who search and read this question, I would like to suggest you close a file when done with it, or at least do an investigation like my answer shows.
I am no programming expert but I have come across this situation recently.
I created a WinForms c# program and used File.ReadAllText to copy text to a string. Afterwards I tried to delete the file, directly from the folder not through the program, but I got an error that the file was still open in another program. I then stopped running the program and was able to delete the file.
That's my experience in Visual Studio 2012 Ultimate. It might be supposed to do something different, but that's what it did for me.
When I used StreamReader.ReadToEnd then StreamReader.Close on the same file, I had no problem deleting the file while running the program.
You have to close IDisposable instances only, usually by means of using, e.g.:
// StreamReader is IDisposable and should be Closed/Disposed
// either explicitly or by using
using (StreamReader sr = new StreamReader(filePath)) {
String base64 = sr.ReadToEnd();
...
}
since you don't have an IDisposable instance in your code (File.ReadAllText
returns String which is not IDisposable) you have nothing to Close/Dispose
StreamWriter outputFile = new StreamWriter(#"C:\Users\Marc\Desktop\_App\files\Data" + dat1 + ".txt");
outputFile.WriteLine(sb.ToString());
outputFile.Close();
StreamWriter outputFileex = new StreamWriter(#"C:\Users\Marc\Desktop\_App\files\DataEx" + dat1 + ".txt");
outputFileex.WriteLine(sbex.ToString());
outputFileex.Close();
Here's a working example I just did with a stringbuilder: "sb". If I remove one of those closes' the file gets generated but the file shows up blank with no data. I had to add in a close to get it to work properly.
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 a Web Application in which I am using asp:FileUpload Control to upload user XSD and reading its content(actually not uploading the XML Schema) using following Statement in a Click button function
using (StreamReader reader = new StreamReader(FileUploadControlName.FileContent))
this reader object is used in Click button function to read XMLSchema and thus I generate collection on basis of that.
I just wanted to know is there any way to use this StreamReader object again so that I can handle the manipulation on other control action in Web-Application.
Means can there be a way to write the reader into Memorystream and reuse the MemoryStream.
Sorry I am new to this.
You can reuse MemoryStream by setting the Position property to 0.
Example:
Stream s = new MemoryStream();
StreamReader sr = new StreamReader(s);
// later... after we read stuff
s.Position = 0;
And if you want to reuse the same object trough the application then you can use a Session variable. Then when you need to reuse it just set position to 0 again and read it with StreamReader.
By calling using the SteamReader will be disposed after the block ends, but not the stream itself. You can store the stream in a Session variable and reuse it like that, but I suggest you keep in mind to clear the Session variable. You can use MemoryStream or you can move the file to e TEMP location and store the file location in a Session variable. I would go with that option.
For the ExcelPackage constructor you need a FileInfo object. I rather use some kind of stream object(f.i. MemoryStream), because I don't need to save the file to the server itself, but expose it as a FileStream anyway to the user. I don't want to make files which I have to delete lateron from servers which are only there for generating purposes and never used again. Apart from that, otherwise I need also the necessary rights for the application/user on the directory/file on the server.
So my question is then: How can I convert a stream object to a FileInfo object.
You can't convert the Stream as such to a FileInfo; they represent entirely different things. A Stream contains data thay may or may not represent a file on disk. A FileInfo on the other hand contains metadata about a file, that may or may not exist.
What you can do is to write the contents of the Stream to a file on disk, create a FileInfo pointing at that file and pass that FileInfo to the constructor.
Yes you can
var excelPackage = new ExcelPackage();
excelPackage.Load(fileStream);
A FileInfo class is a simple wrapper around a path to a file on disk.
It is not possible to have a FileInfo wrap a memory stream.
However, you can download the source code and add a constructor that takes a Stream. (The file path is only used in the WriteDebugFile method)
Adding the following constructor to ExcelPackage makes it possible to use Streams instead.
public ExcelPackage( Stream stream ) {
_package = Package.Open( stream, FileMode.Create, FileAccess.ReadWrite );
Uri uriDefaultContentType = new Uri( "/default.xml", UriKind.Relative );
PackagePart partTemp = _package.CreatePart( uriDefaultContentType, "application/xml" );
XmlDocument workbook = Workbook.WorkbookXml;
_package.CreateRelationship( Workbook.WorkbookUri, TargetMode.Internal, schemaRelationships + "/officeDocument" );
_package.DeletePart( uriDefaultContentType );
}
You cant do that , what you should be doing is outputting the memory stream to file and getting the FileInfo object for the newly created file and passing it to the ExcelPackage.
Looking at the source code for ExcelPackage, it uses the Package.Open method on the FullName property of the FileInfo object passed to the constructor, with FileMode.Open and FileAccess.ReadWrite, to initialize a Package object.
The Package.Open method can also accept a Stream directly.
If you wanted, you could overload the ExcelPackage constructor yourself to accept a Stream parameter, and simply call Package.Open on that Stream object--which could easily be, for example, a MemoryStream.
As mentioned by Fredrik Mörk, this is not possible as their is no default conversion available between both types and is not a recommended as well.
Just for reference, You can though provide your own Conversion logic by implementing IConvertible Interface. again not right approach in this scenario, but may be helpful somewhere else.
class CustomStream : Stream, IConvertible
{
public FileInfo ConvertToFileInfo()
{
return new FileInfo("");
}
}
This is how you convert It
CustomStream stream = new CustomStream();
FileInfo fileInfo = stream.ConvertToFileInfo();