I need a place to store images. My first thought was to use the database, but many seems to recommend using the filesystem. This seems to fit my case, but how do I implement it?
The filenames need to be unique, how to do that. Should I use a guid?
How to retrieve the files, should I go directly to the database using the filename, make a aspx page and passing either filename or primary key as a querystring and then read the file.
What about client side caching, is that enabled when using a page like image.aspx?id=123 ?
How do I delete the files, when the associated record is deleted?
I guess there are many other things that I still haven't thought about.
Links, samples and guidelines are very welcome!
Uploading Files in ASP.NET 2.0
You seem up in the air about how to do this, so I'll give you a few ideas to get you going.
If you want to use a file system make sure you know the limit of how many files are permitted per directory, so you can set up a system that creates subdirectories. http://ask-leo.com/is_there_a_limit_to_what_a_single_folder_or_directory_can_hold.html
I would make a table something like this :
FileUpload
UploadID int identity/auto generate PK, used as FK in other tables
InternalFileName string
DisplayFileName string
Comment string
MimeType string
FileSizeBytes int
FileHash string MD5 Hash of a File
UploadUserID int FK to UserID
UploadDate date
You would include the UploadID in the table that "owns" this upload, like the Order associated with it, etc. You could add the InternalDirectory column, but I prefer to calculate this based on a constant Root value + some key specific value. For example, the complete file name and directory would be:
Constant_Root+'\'+OrderID+'\'+InternalFileName
You could make the InternalFileName be the UploadID and the file extension from the original file. That way it would be unique, but You'll have to insert the row as the first part of the process, and update it after after you know the file name and identity/auto generate row value. You could make the InternalFileName something like YYYMMDDhhmissmmm and the file extension from the original file, which may be unique enough based on how you use subdirectories.
I like to store a MD5 Hash of a File which makes detecting duplicates easy.
MimeType and FileSizeBytes can be found from the file system, but if you store them in the database, it makes some maintenance easier since you can query for large files or files of certain types.
Related
I need some help. We migrated an Access database to SQL Server. One column had attachment data the Attachment data type in MS Access. The MS Access application is being replaces by an ASP.NET web application.
This data now lives in a column of data type varbinary(MAX), there is no indication of the file name and or type (most attachments are Excel, Word and PDF docs).
In my ASP.Net application I am using a data reader that will allow users to retrieve the attachments by downloading them using a browser. (I have a new table for new attachments that contains the full file name and content type, and when present it works like a charm). Without the file types, all attachments come across as xml/garbles data files like shown in this image below (can't yet post images, been a long time reader, first contribution. Here is the text in which I had planned to highlight some key values:
ÿÿÿÿWorksheetExcel.Sheet.12****Access.OLE2Link¾ÐÏࡱá>þÿ þÿÿÿÿÿÿÿÿÿÿÿÿÿ]þÿÿÿþÿÿÿ !"#$%&'()*+,-./0123456789:;<=>?#ABCDEFGHIJKLMNOPQRSTUVWXYZ[\þÿÿÿþÿÿÿÿÿRoot EntryÿÿÿÿÿÿÿÿàÆ©÷òï…ÝŒkˆZ‚Å7Ï€Ole ÿÿÿÿÿÿÿÿÿÿÿÿCompObjÿÿÿÿeOlePres000ÿÿÿÿÿÿÿÿš þÿÿÿþÿÿÿþÿÿ‹ÀF CENTRA~1.XLSÿÿÞHBCentral Dispatch Process Map.xlsxºÀF'C:\Users\MA~1\Desktop\CENTRA~1.XLSÿÿÞ]|C:\Users\ine\Desktop\Central Dispatch Process Map.xlsxÕLÀFƒ •Æh5)ÏBy>*Ϧc{>*ÏS5ŽŒ2S5&D%¯ CENTRA~1.XLSpï¾&D6®&D%¯*ƒœ2Central Dispatch Process Map.xlsxm-lkÑÊC:\Users\ine\Desktop\Central Dispatch Process Map.xlsx(
It appears that the content is there from which I should be able to extract the file name and types.
Here is my question, how do I migrate my attached files. I need to determine the content type and file names from the original data stored in varbinary(max), I then need to move the files from the current location into my new table with the attributes that describes the file name and file type.
Thanks
I'm developing a web application, Computerized Voting System using ASP.NET. i want to compare thumb impression from database. I'm using disconnected data access. is it possible to compare an input thumb impression with a thumb print already saved in SQL database? if yes then then how?
please describe some details of the application.
The images that are saved in the database, are they uploaded with the same application ? If so, you should add a new column where you will store the hash of the image.
You will have a table like this: |ID|ImageData|Hash|
This is how you can compute the hash:
string hash;
using(SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider())
{
hash = Convert.ToBase64String(sha1.ComputeHash(byteArray));
}
Then, when you want to check if an uploaded image already exists in the database, you should compute the hash for it and send a query like:
string.Format("SELECT ID FROM Images WHERE Hash={0}", hash);
This will tell you if the exact same bytes are already in the database. If the image is similar, it will not work. It must be identical.
NOTE: you will have to convert your image into a byte array. This should not be a problem if you already do this when saving images in the database.
You might want to look in Computer Vision and Principal Component Analysis if you want to look for similarities between images.
how can I change my Drupal filesystem root in the database ?
I moved Drupal to another path. I'm looking for this value to update in the database.
thanks
<EDIT>if you want to change it in the database (why?), you can do it by changing the value of file_directory_path in the variable table:
UPDATE variable SET file_directory_path = 's:5:"files";';
values in the variable table are stored as serialized php variables. the serialized value in the example above means file_directory_path is a string (s) of length 5 with the value files. you have to adapt this to your specific value.
also note that Drupal variables are cached (in the cache table, under the cid variables). for your change in the database to take effect, you have to clear that cache, like DELETE FROM cache WHERE cid = 'variables';.</EDIT>
if you mean the File system path: it's at Administer > Site configuration > File system, or http://yourdrupalsite.com/index.php?q=admin/settings/file-system.
You could also do the following:
//Get the path of the files folder (ex. sites/default/files)
$files_dir = variable_get('file_directory_path', '');
//To set a new path programmatically
variable_set('file_directory_path', 'sites/new-path/files');
Funny, I just had to do that yesterday.
Since i have phpmyadmin available to me, I used that to export the files table, then do some search/replace routines, then import the table, overwriting the data.
But had I not had phpmyadmin to help, I would have created an SQL query to replace the outdated paths...
Funny, I just moved my drupal to another folder, and it was working. Probably I didn't explain my question very well..
how to store files (pdf and word files) into sql database and how to display that files with an option of "save" , "open" from sql data base when user click. i am doing project using c# + asp.net web application
You need to do several things here:
1) Create UI page that allows users to upload files.
This page will have a FileUpload control to check for the desired extentions
2) Write code to save these files to a database
The files can be stored as binary blobs. It will be up to you and your application to decide the schema of your database. You may also choose one of many ORM tools to provide you access to the database from your code see
Linq2SQL
EntityFramework
ADO.net
Or see Creating A Data Access Layer
You have many choices, choose whatever seems most natural / easy for you.
3) Create a UI for the user to select existing files
This will use your ORM data layer to read back the lists of files and display some sort of buttons / links for the user to select and download
4) Retrieve the files from the database once the user selects one and return the file
Read this MSDN article about returning binary files
Furthermore, google around a bit, you'll probably find lots of existing solutions with frameworks like DNN etc.
To store files, you should check out Filestream from SQL Server 2008: http://msdn.microsoft.com/en-us/library/cc716724.aspx
Other traditional platforms have similar support (with binary or image data types).
An alternative is you can store the file in a shared filesystem, and only store the path to the file in the SQL table.
The most common way is to have two columns in the database for the file to be stored propley. 1 column holds the filename with its extensions(ex: file1.txt) and the 2nd column will be of datatype binary.
at the application level. a method gets the uploaded filename and converts it to an array of bytes. then this array is stored in sql in the binary field. the filename is stored in the 1st field.
to read the file back, another method will read the binary field from sql and convert it back to a FileStream then save it with the original filename(extension).
Use a fileUploaded to upload the file.
Read the file into a byte array:
byte[] data = System.File.ReadAllByte(File Path);
convert the byte[] to hex and store it in a nvarchhar data field in SQL
stringBuilder sb = new StringBuilder()
foreach(byte b in data)
{
sb.Append(b.ToString("X");
}
When you need to display it, convert it back to byte[] and create a file out of it, and let the user Open/Save it from there.
I am working on a website, where user can upload photos of product they want to advertise.
I am saving photos in a folder on the web. In the table where I keep reference of photos, there is a key field photoid which is Identity field(primary key).
My repository has following methods
Photo photo = rep.NewPhoto();
photo.Title="Some Title";
rep.InsertPhoto(photo);
rep.SaveAll();
rep.SavePhoto(photo,uploadedPhoto);
rep.SaveAll();
I am using Linq to SQL for my data model.
Now my problem is, if I want to save my files
with a name which is coming from photoid, I have to Call the rep.SaveAll()
method to get the new created photoid and then save the photo with new id
and then I have to Call SaveAll() method to update it again with the changes
happend in SavePhoto() method.
Other option is I save the file with some random file number first and then Save the photo record in one step.
This is second approach.
Photo photo = rep.NewPhoto();
photo.Title="Some Title";
string filename = rep.SavePhoto(uploadedPhoto);
photo.FileName=filename;
rep.InsertPhoto(photo);
rep.SaveAll();
Saving files with photoid has one good point, photos can be easily loaded using its id.
What is a good approach to achieve this kind of functionality.
Help will be appritiate.
Cheers
Parminder
Second approach is definitely more efficient; other option could be to create a unique in your application layer(you can use guids ) and then use this as key DB record and same as file name.
If you are using the latest SQL Server, you might want to look into the new FILESTREAM field type:
http://technet.microsoft.com/en-us/library/bb933993.aspx
It's for exactly this kind of thing -- trying to get large blobs out of the table structure and onto the filesystem.
Other than that, I think you have the right idea with either way you go -- if you need two saves, you might want to consider a transaction if you care about what happens if the second save or SavePhoto fails.
A couple of things:
1) Consider storing the photos as VARBINARY(MAX) in the database. It will be much easier for people to manage as far as backups and restores go, and it's better for your database's integrity.
2) Consider using the partial methods of your L2SQL Photo class in order to achieve what you want. You should be able to change your Photo class's Update method to save your photo as well. Hope this helps.