How to close FileStream without causing an error in "Syncfusion.PdfViewer"? - c#

I'm using Syncfusion.PdfViewer in my project. When I click an item in a list, the related pdf file is loaded and shown in the PdfViewer:
private void PdfReport(string address)
{
//Load the stream from the local system.
FileStream fs = new FileStream(address, FileMode.Open);
PdfSource = fs;
}
The problem is that each time I load a pdf file, a new instance of FileStream is created and the memory usage increases. When I try to close FileStream like the following code, the pdf is not shown in the viewer:
private void PdfReport(string address)
{
//Load the stream from the local system.
FileStream fs = new FileStream(address, FileMode.Open);
PdfSource = fs;
fs.Dispose();
}
How can I solve this problem?

You should check if a PdfSource exists and if so close/ dispose that before creating the new filestream, so just
if (PdfSource is not null)
PdfSource.Dispose();
PdfSource = new FileStream(address, FileMode.Open);

In Syncfusion PDFViewer, while loading the PDF document as stream/file, it unloads the existing loaded document internally. While unloading the document, it will dispose the file stream. Hence, we don’t need to dispose the file stream on the sample side.

Related

Nancy httpfile issue

i have problems during parsing request files.
my file size is 1338521 bytes, but Nancy says, that file size is some times 1751049 or 3200349.
on my windows pc it works fine, on linux server this problem appears, so i can't save file.
string result = Convert.ToBase64String(Core.ReadBytesFromStream(file.Value));
using (MemoryStream ms = new MemoryStream(Convert.FromBase64String(result)))
{
using (Bitmap bm2 = new Bitmap(ms))
{
bm2.Save(path);
}
}
any ideas?
You don't need to convert the file like that.
var filename = Path.Combine(storagePath, Request.Files[0].Name);
using (var fileStream = new FileStream(filename, FileMode.Create))
{
Request.Files[0].Value.CopyTo(fileStream);
}
Validate the file when it comes in to ensure the extension is accepted, create a save path, and copy the stream to a new file on the filesystem.
That's it.

Zip File getting corrupted when i save it to isolated storage

I have downloaded a zip file from blob storage and save it to isolated storage of windows phone like this :- FileStream fs is downloaded from blob.
public static void SaveToIsolatedStorage(FileStream fs, string fileName)
{
var isolatedStorage = IsolatedStorageFile.GetUserStoreForApplication();
using (var streamWriter =
new StreamWriter(new IsolatedStorageFileStream(fileName,
FileMode.Create,
FileAccess.ReadWrite,
isolatedStorage)))
{
streamWriter.Write(fs);
}
}
But when checked this zip file using IsoStoreSpy it is showing corrupted. I have checked it by reading from isolated storage and tried to unzip it but not working. I am sure that it is corrupted because when i replace this file using IsoStoreSpy with some other zip and then tried to unzip it then it is working.
Edit:-
Code for downloading from Blob
private async Task DownloadFileFromBlobStorage()
{
var filename = "AppId_2.zip";
var blobContainer = GetBlobClient.GetContainerReference("testwpclientiapcontainer");
var blob = blobContainer.GetBlockBlobReference(filename);
using (var filestream = new FileStream(filename, FileMode.Create))
{
await blob.DownloadToStreamAsync(filestream);
SaveToIsolatedStorage(filestream, filename);
}
}
So anybody know how can i save the zip file to isolated storage without getting it corrupted ?
You're using a StreamWriter. That's for text. You shouldn't be using it to copy a zip file at all. Never use any TextWriter for binary data.
Next you're using StreamWriter.Write(object), which is basically going to call ToString on the FileStream. That's not going to work either.
You should just create an IsolatedStorageStream, and then call fs.CopyTo(output).
public static void SaveToIsolatedStorage(Stream input, string fileName)
{
using (var storage = IsolatedStorageFile.GetUserStoreForApplication())
{
// Simpler than calling the IsolatedStorageFileStream constructor...
using (var output = storage.CreateFile(fileName))
{
input.CopyTo(output);
}
}
}
In your edit you've shown code which saves to a FileStream first, and then copies the stream from the current position. As you've noted in comments, you needed to rewind it first.
Personally I wouldn't use a FileStream at all here - why do you want to save it as a normal file and an isolated file? Just use a MemoryStream:
using (var stream = new MemoryStream())
{
await blob.DownloadToStreamAsync(filestream);
stream.Position = 0;
SaveToIsolatedStorage(stream, filename);
}
(Note that your SaveToIsolatedStorage method is still synchronous... you may wish to consider an asynchronous version.)

File is already in use FileAccess C#

public void WriteListToFile(Lists lists, string filePath)
{
FileStream outFile;
BinaryFormatter bFormatter = new BinaryFormatter();
// Ppen file for output
outFile = new FileStream(filePath, FileMode.Create, FileAccess.Write);
// Output object to file via serialization
bFormatter.Serialize(outFile, lists);
// Close file
outFile.Close();
}
Whenever I try to output data to a .dat file I get an error saying that the file is already in use. How do I fix this?
EDT: Turns out it wouldn't let me save to an empty file so I create a new void to input data and then it allowed me to save over the file.
The immediate answer is "release the lock that some process has on the file".
Something already has the file open. You need to look at code and other processes that may access that file to find the root cause.
I note that you're not making use of using statements. If an exception were thrown in the block of code you show, outputFile.Close() would never execute, leaving the file open.
Try rewriting your code (and any similar code) like
public void WriteListToFile(Lists lists, string filePath)
{
BinaryFormatter bFormatter = new BinaryFormatter();
// Ppen file for output
using (FileStream outFile = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
// Output object to file via serialization
bFormatter.Serialize(outFile, lists);
// Close file
outFile.Close();
}
}
The using keyword is a syntactic shortcut for
var outFile = new FileStream(filePath, FileMode.Create, FileAccess.Write);
try
{
// Do stuff with outFile
}
finally
{
outFile.Dispose();
}
and ensures that outFile is disposed (which also closes it) whether or not an exception is thrown.
you can try this:
outFile.Dispose();

Save as using EPPlus?

Does any one know how to use the package.Saveas function?
package.SaveAs(tempFolderPathAlt + saveas + ".xlsx");
At the moment this is underlined in red with the following error:
The best overloaded method match for
'OfficeOpenXml.ExcelPackage.SaveAs(System.IO.Stream)' has some invalid
arguments
At the moment i'm saving the file in the following way.
FileStream aFile = new FileStream(tempFolderPathAlt + saveas + ".xls", FileMode.Create);
byte[] byData = package.GetAsByteArray();
aFile.Seek(0, SeekOrigin.Begin);
aFile.Write(byData, 0, byData.Length);
aFile.Close();
But this way the package remains open and i cant work with files it has used.
The save as will close the package properly, but its not accepting my file path.
Edit
I tried this:
using (FileStream aFile = new FileStream(tempFolderPathAlt + saveas + ".xlsx", FileMode.Create))
{
byte[] byData = package.GetAsByteArray();
aFile.Seek(0, SeekOrigin.Begin);
package.SaveAs(aFile);
//aFile.Write(byData, 0, byData.Length);
aFile.Close();
}
But Get the following error?
Package object was closed and disposed, so cannot carry out operations on this object or any stream opened on a part of this package.
The package will be closed & disposed after you call any of functions GetAsByteArray, Save, SaveAs. That is the reason why you got message
Package object was closed and disposed, so cannot carry out operations on this object or any stream opened on a part of this package.
The solution is that after the saving you call Load function to continue processing on excel file. Or if you just want to get both ByteArray & FileOutput, I'm sure with you they both are same.
You can read data after have saved file to the disk:
string path = #"C:\test1.xlsx";
Stream stream = File.Create(path);
package.SaveAs(stream);
stream.Close();
byte[] data = File.ReadAllBytes(path);
Or you can save data to disk after get the ByteArray:
byte[] data = package.GetAsByteArray();
string path = #"C:\test1.xlsx";
File.WriteAllBytes(path, data);
I came looking for the answer to this but the existing answers were not clear to me.
Here is what I did using EPPlus and System.Windows.Forms:
ExcelPackage xlPackage = new ExcelPackage(xlsTmpFileName)
// Populate the Excel spreadsheet here.
SaveFileDialog sfd = new SaveFileDialog();
using (FileStream fs = new FileStream(sfd.FileName, FileMode.Create))
{
xlPackage.SaveAs(fs);
}
I dont know from which version onwards but EPPlus's SaveAs method accepts a FileInfo. So you could do something like this:
using (var app = new ExcelPackage(new FileInfo(inputPath)))
{
//process
app.SaveAs(new FileInfo(outputPath));
}
Unlike the Save method SaveAs method overwrites file as well in case file name already exists.
SaveAs would be accepting your aFile Stream.
You can find out such things yourself by looking at the function signature: SaveAs(System.IO.Stream). It takes a Stream. Passing a string cannot possibly compile so you have to somehow make up a useful Stream (which you did).
Get rid of the surplus package.GetAsByteArray call and you should solve it.
I just ran:
using (FileStream aFile = new FileStream(#"C:\Temp\asdf.xlsx", FileMode.Create))
{
aFile.Seek(0, SeekOrigin.Begin);
package.SaveAs(aFile);
aFile.Close();
}
// See here - I can still work with the spread sheet.
var worksheet = package.Workbook.Worksheets.Single();

Enable writing to file that is mapped to memory

I will like to use a memory mapped file to virtualize opening a file on windows when that file is realy on the internet.
So I create the memory mapped file as:
// data that we write to the file. we will get this a tcp
var data = System.Text.Encoding.UTF8.GetBytes("Hello World");
var fileStream = new FileStream("SomeFile.txt", FileMode.Create);
using (MemoryMappedFile memoryMapped = MemoryMappedFile.CreateFromFile(fileStream, "MapName", 1024,
MemoryMappedFileAccess.ReadWrite, new MemoryMappedFileSecurity(), HandleInheritability.Inheritable, true))
{
var viewStream = memoryMapped.CreateViewStream();
viewStream.Write(data, 0, data.Length); // write hello world
}
And I can read from it on windows but not save it:
Note how I was able to open the file (meanwhile the data was on memory and not the hard disk) but the moment I tried saving changes I was not able. So my question is: How could I enable saving changes to that file and be just changing the content in memory of the memory mapped file without actually trying to save anything to disk.
You need to specify the sharing mode when creating the file stream.
var fileStream =
new FileStream("SomeFile.txt", FileMode.Create,
FileAccess.ReadWrite, FileShare.ReadWrite);
Also, you need to dispose of your FileStream when done, e.g. with a using statement.
UPDATE
It worked just fine for me. Using Notepad I had to manually re-open the file, but I could update it while Notepad had it open (Notepad just did not check for external modifications).
Side note: The code writes a bunch of NUL (0x00) bytes to the end of the file. You'll probably want to look into that.
Here's the exact code I used (note the local path to C:\Temp. Change if needed):
static private void WriteMMF()
{
// data that we write to the file. we will get this a tcp
var data = System.Text.Encoding.UTF8.GetBytes("Hello World 2");
using (var fileStream = new FileStream(#"C:\Temp\SomeFile.txt", FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite))
using (MemoryMappedFile memoryMapped = MemoryMappedFile.CreateFromFile(fileStream, "MapName", 1024,
MemoryMappedFileAccess.ReadWrite, new MemoryMappedFileSecurity(), HandleInheritability.Inheritable, true))
{
var viewStream = memoryMapped.CreateViewStream();
viewStream.Write(data, 0, data.Length); // write hello world
}
}
static void Main(string[] args)
{
Console.WriteLine("Writing MMF");
WriteMMF();
Console.WriteLine("Done. Press a key.");
var ch = Console.ReadKey();
return;
}

Categories

Resources