Pass byte array back to its original file from sql filestream - c#

I have setup filestream on my mssql server, and it works pretty well thus far. Currently, I have one entity in my database, that I have added manually.
When I added my file, it was automatically converted to a byte[], which Similarly appears as a byte[] when I get it through my .NET Core application (surprise).
Optimally, I would like to know, how I can decode this byte array into the original file? I have read several places, that I need to provide the original extension of the file in order to do that.
However, I have not added such a column in my database - I could easily add such a column, but it seems odd to me, if it isn't possible to pass it back to its original format without providing additional parameters.
Therefore, is there a way, in which I can convert the byte array back to its original file so that the user easily can download it, without having to do some sort of comprehensive conversion?
I would happily like to know, if one of you can point me in a direction here.

A filestream column contains the file's contents, not its external metadata, like the original filename, extension, directory location and access control list. If you write the byte[] to disk with, eg, File.WriteAllBytes(string,byte[]) it will be a usable file.

Related

Copy byte array into clipboard

I'm trying to do a client-server program in which it is possible to share the content of the clipboard.
Right now I am able to share it if the content type is audio, image or text.
The idea is that I convert the content in a byte array, send it, convert it back in its original type (Stream, BitmapSource or string) and inject it in the client clipboard by using the methods Clipboard.SetAudio, Clipboard.SetImage or Clipboard.SetText.
My problem is when there are some files in the clipboard. I use the method Clipboard.GetFileDropList to get a list of the files, and for each file in the list I convert it in a byte array and send it to the client. How can I inject this byte array in the client clipboard?
I know there is the method Clipboard.SetFileDropList, but it requires me to provide a file list and since the file does not exist on the client I cannot use it.
How can I solve this problem?
In order to make the client treat the files as pastable, they'll need to exist on the client filesystem in some way, since the clipboard expects a list of filenames when setting clipboard content.
This can be done by transferring the data as a stream to your client, and then making the client immediately unpack that stream to a temp folder, the path to which is obtainable via:
var temp = Environment.ExpandEnvironmentVariables("%TEMP%");
Once done and the files are i place, you can position those files on the clipboard as if they were the ones copied.
Be warned that supporting file copy/paste instead of having an option to "transfer" files could run much slower than other operations, due to how big files can get.

Saving PDFs in SQL Server

From the DB schema that we have I think we are saving images in the SQL Server, I found a column called ImageContents(text null) in our Images table.
Now I have a folder that has bunch of PDF files and I want to save them in that table.
How do we do that? Why is it s text type column?
I Googled the topic but mostly they were saying save the image somewhere else and save a link to its address in the SQL Server but that is not how we do it so I couldn't find an answer by myself.
Since you're stuck with a text field, and you have binary data, you will need to encode your binary data into something that will go in a text column, and you will also have to decode it when you get it out again.
Base 64 encoding is one way to do this. (Note that the encoded form will take somewhat more space.)
Convert.ToBase64String(bytes) and Convert.FromBase64String(string) should get you back and forth, as in this example. (For the byte array step, use File.ReadAllBytes or see Vinikov's link.)
Again, it would probably be better to store a path and filename in the database, and keep the PDF files in the file system, but I understand you don't have the option to do that in this case.
P.S. SQL Server now has a FileStream attribute on varbinary(max) fields, that will store large files like this in the file system (though you have to enable it and configure it). Again, I understand that you don't have the option to use varbinary(max) in this case.
If you are already storing images in your database, look again and probably that you will find a column of type Image or varbinary(max). This is what you need to store your PDF files as they are binary files and not text files. Possibly that you can use the same type of code as what you are already using for storing your images; if such code is available. Otherwise, you shouldn't have any problem to find on the internet how to store an image file into a column of type Image or Varbinary(max). Storing a PDF file is exactly the same as storing an image file; except maybe for the extraction of metadata (such as decoding the width and the length of an image) and the checking of the suffix (.GIF, .PNG, etc.).
Do not use the column of type Text (or of varchar(max) or nvarchar(max)) because there would be a real possibility of corrupting your PDF files.
With the older versions of SQL Server such as 6.5 or 7.0; there was a real performance issue with storing files in a database but these problems have since been corrected.

Append & detach same files in c#

I want to append 2 files and I want to detach the same files?
It's that possible in c#? I did some codes to append its possible but detach I don't know.
Any one know to do that please help .thanks,
To combine files into one and then extract files back you will need to define a file format and store information about file sizes, names, compression method, etc.
Combining exe- and txt-files into one won't work without extra info.
One easy way is to define separator, which will tell you when one file is finished and another one is started (possibly first few bytes after separator will be file name, then 0x00 and actual data).
Another way is to use header, where you keep all info. Header is usually consist of signature and then some data structures (file name, size) so that you can find file related data after reading just header.
Probably easiest for you to combine file would be to actually zip them. See and search for ZipAchieve (.net 4.5).

Is it possible to write to the middle of a file using Filestream in C#

Wanting to know if it is possible to insert text into the middle of a file using FileStream in .NET/C#. If not, is there another way of doing it? I see the option of Truncate and Append, but obviously that isn't what I'm looking for. I suppose I could open a filestream source, create another destination file and write to it as I see fit, then truncate the source and write back to it from the second file or a large buffer, or delete the source and rename the destination file to the original source filename.
I guess my question is, how is this kind of thing most efficiently and safely done.
No - this is fundamentally a limitation of most file systems.
I would recommend the approach you're suggesting (selective copying from the original file to a new file) but then just rename the files rather than copying back over the top of the original.
If you're happy to have the whole file in memory, you can follow the comment in the question and read the whole file into memory, make the change and then overwrite the existing file - but obviously that doesn't scale as well to very large files. It all depends on the context.

Display a file from a byte[] or stream

I've got a winforms app that stores the contents of files in a database. The stored files can be of just about any type (word, excel, PDF, text, image ...) the user can select just about any type of file to load.
The user can then query the database, find a file and then open it.
I've got no problems extracting the byte array from the database, as either a stream or a byte array.
Ideally I'd be able to display the file directly from a byte array or stream; at the moment I'm saving it as a temporary file and then opening that with:
Process.Start(fileName);
How can I display the file with the associated application either from any of the byte array or stream file?
In windows, your only option is to do exactly what you're doing. Outlook, Internet explorer, firefox, all do this
Maybe you want to research a little bit on Memory Mapped File.
you can try to open the directory containing it, but it will be the same thing you're doing right now.. if the associated app is known by the OS, then there will be no problem..
If you store a filename in the DB along with the byte stream, you can determine the file type from the extension. There's two options in this case:
Use the registry to determine what application to use. For more info on this, take a look at this conversation on bytes.com.
P/Invoke SHGetFileInfo to determine what application to use.
NB: With both options you'll still need to write the file data to a temp file on disk in order to load it.
Personally, I'd think what you're doing is probably the easiest option, anyway (unless you'd like to provide custom viewers for certain file-types, etc)

Categories

Resources