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)
Related
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.
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.
Suppose that I would like to add extra information about a file, without writing that information as content of that file. How would I do this? A couple of good examples are:
With Word documents, you can add Author tag to a document. And,
MP3 files have lots of info stored inside of them but when you play the file, you don't see that info (unless the program playing the file has been programmed to display that information).
How does Windows do this?
This information is stored in the file system (on windows - NTFS).
In NTFS, you can actually store another file, as part of this information, and it stores much more information about each file than you may expected.
NTFS file streams
Exapmle in C how to consume them
About MP3 and word - In these cases the information is stored inside the file, as part of its format.
What is the best way to open a Word file that was stored as a byte[] in a database?
I have to store some documents in an Access database - Word files, 2003 and up - on an application that is strictly run off of a CD. Unfortunately they have to be in the database and can't be stored loose in folders. I'm storing them as an OLE object, and I can read and write them just fine as a byte[].
However, I don't know the best way of getting these documents back open in Word. Right now I'm using a FileStream to recreate the file in somewhere and then shooting off a System.Diagnostics.Process.Start(filename) to get it to open. This is going to be used on government computers which can have some funky security rules sometimes, so I don't know if this is the best way.
Is it possible to open a file previously stored as a byte[] without using any intermediary file saved to the hard drive? I know they'll at least have Word 2003, so I'm open to using the Word interop.
Thanks for any input!
I doubt you're going to be able to feed Word a file in memory without saving it to at least a RAMDisk or something wild like that.
Why not use the system temp folder or the GetTempFile() method to write the byte array to a file just before opening it using Word and then cleaning up the temp files when you're done?
string fullPathToATempFile = System.IO.Path.GetTempFileName();
// or
string tempDirPath = System.IO.Path.GetTempPath();
I have a table in the database containing "files".
I don't know their filetype.
I need to export some stuff (including these files) and be able to import them into the same application.
So I was thinking about saving the byte array as data.dat (unknown extension).
and when importing just making a byte array from that file and putting it back into the database.
Will this work?
Yes, file extensions are only a clue as to the format/purpose of the file, but don't really mean anything.
From the computer's point of view it doesn't care at all what a file is called (Windows just uses them to associate applications with their files so you can open them by double-clicking).
The extension doesn't influence on the data itself, just the app that will be launched by default when you double-click on it. Yes, it will work.
Just be aware that you should validate the file when importing it to your app.