Store images with unique filenames using hashing - java

I'm looking for a solution for storing unique file names for a web application using Java Servlet.
What I need is to render profile images in a webpage, since I decided to store only file names in the database I have only to be sure they're unique in the image folder: to achieve that I was thinking to name images and save them with a string name composed by the couple:
<user_id>_<hash>.<file-type>
In this manner I think I would be pretty sure there will be no collisions, since user_ids are already unique.
1) Is this solution sound?
2) What algorithm should I pick for this purpose?
I'd like to use it properly so code snippets would be very appreciated.
Thanks

You can use File#createTempFile() wherein you specify the prefix, suffix and folder. The generated filename is guaranteed to be unique.
File file = File.createTempFile("name-", ".ext", new File("/path/to/uploads"));
// ...
No, this file won't be auto-deleted on exit or something, it's just a part of temp file generation mechanism.

Really simple approach would be to append System.currentTimeMillis() to the userid. If userid is unique then it should be pretty safe.

Why attach a hash or anything to it if its a 1 to 1 mapping? 1 user to 1 profile image, just use their id. If its a 1 to many, save the record in the database and get the id of that record and use that as the name. You might want to convert all your images to a particular image format too just to be consistent, so that wouldn't be stored in your database either.
BalusC tempfile method would work perfectly with this presented concept.

Related

Is it possible to decode a text with more than encrypted values in Java?

Into same folder, I want to save files with having same name. It is not possible, of course. Not to lead confusions in the future, In Java I want to hash or encrypt file name with different values then save it. When I callback (I will call with some Id), I want to decrypt and get their names.
I came up with this with this idea, but I am open to different solution.
Thanks
Say you have two xxx.txt files you want to copy to the directory. Then one could save them as xxx.txt.1 and xxx.txt.2. The original file name is still there.
You might the use the same encryption/decryption for all file names if you need unreadable names.

Java framework to manage BLOB data outside of database

I want to store my blobs outside of the database in files, however they are just random blobs of data and aren't directly linked to a file.
So for example I have a table called Data with the following columns:
id
name
comments
...
I can't just include a column called fileLink or something like that because the blob is just raw data. I do however want to store it outside of the database. I would love to create a file called 3.dat where 3 is the id number for that row entry. The only thing with this setup is that the main folder will quickly start to have a large number of files as the id is a flat folder structure and there will be OS file issues. And no the data is not grouped or structured, it's one massive list.
Is there a Java framework or library that will allow me to store and manage the blobs so that I can just do something like MyBlobAPI.saveBlob(id, data); and then do MyBlobAPI.getBlob(id) and so on? In other words something where all the File IO is handled for me?
Simply use an appropriate database which implements blobs as you described, and use JDBC. You really are not looking for another API but a specific implementation. It's up to the DB to take care of effective storing of blobs.
I think a home rolled solution will include something like a fileLink column in your table and your api will create files on the first save and then write that file on update.
I don't know of any code base that will do this for you. There are a bunch that provide an in memory file system for java. But it's only a few lines of code to write something that writes and reads java objects to a file.
You'll have to handle any file system limitations yourself. Though I doubt you'll ever burn through the limitations of modern file systems like btrfs or zfs. FAT32 is limited to 65K files per directory. But even last generation file systems support something on the order of 4 billion files per directory.
So by all means, write a class with two functions. One to serialize an object to a file; given it a unique key as a name. And another to deserialize the object by that key. If you are using a modern file system, you'll never run out of resources.
As far as I can tell there is no framework for this. The closest I could find was Hadoop's HDFS.
That being said the advice of just putting the BLOB's into the database as per the answers below is not always advisable. Sometimes it's good and sometimes it's not, it really depends on your situation. Here are a few links to such discussions:
Storing Images in DB - Yea or Nay?
https://softwareengineering.stackexchange.com/questions/150669/is-it-a-bad-practice-to-store-large-files-10-mb-in-a-database
I did find some addition really good links but I can't remember them offhand. There was one in particular on StackOverFlow but I can't find it. If you believe you know the link please add it in the comments so that I can confirm it's the right one.

Is there a way to associate data with a file in a folder hierarchy?

Using Java, I am creating a program that indexes a folder structure and allows a user to search for files and also tag a file with keywords and then search for files based off of those tags.
I have been traversing through the folder hierarchy using the FileUtils listFiles method at the moment which is essentially this question: Recursively list files in Java
I haven't yet begun to code the tagging functionality, but thinking ahead I'm fearing that if a file is renamed or moved after I associate it with a tag then it will lose the tag. This defeats the purpose of my program, so can anybody offer suggestions as to how to store each file located in the folder hierarchy or associate the tag so that if a file is renamed or moved it will still have the tag associated with it.
If you want to keep track of a file, even when its name and/or location changes, you should use its unique identifier, which in most file systems is called its inode. (I think NTFS/Windows calls it a "file ID.") You can read a file's inode using its BasicFileAttributes.fileKey:
Object key = Files.getAttribute(file.toPath(), "fileKey");
That key is suitable for use as a HashMap key.
If the OS doesn't support file tagging, you could:
maintain a mapping of file path to tags
maintain a mapping of file hash to tags
Using option #2, your tags would be preserved even if a file was moved. But if someone moved AND modified the file, then the tags would be lost.
I don't think there's a way to do this without updating your tag relationship to the newly create file since the rename/mv operation is at the disk level and there is actually a delete and 'create' file compound action happening in the background. Because of that, there's no guarantee that a file will even be in the same place on the disk. If you know for sure that the file will have the same contents, you could take an MD5 signature of the file's contents in a String object and then always compare those when a tag is queried, of course this has its down falls too when the file's content changes.
Your best bet is to use a hash map w/ the files' paths and tags and then use directory watcher to update the hash map when a file name changes. Thats the best I can think of!

Rapidly changing Configuration/Status File? JAVA

I need some way to store a configuration/status file that needs to be changed rapidly. The status of each key value pair (key-value) is stored in that file. The status needs to be changed rather too rapidly as per the status of a communication (Digital multimedia broadcasting) hardware.
What is the best way to go about creating such a file? ini? XML? Any off the shelf filewriter in Java? I can't use databases.
It sounds like you need random access to update parts of the file frequently without re-writing the entire file. Design binary file format and use RandomAccessFile API to read/write it. You are going to want to use fixed number of bytes for key and for value, such that you can index into the middle of the file and update the value without having to re-write all of the following records. Basically, you would be re-implementing how a database stores a table.
Another alternative is to only store a single key-value pair per file such that the cost of re-writing the file is minor. Maybe you can think of a way to use file name as the key and only store value in the file content.
I'd be inclined to try the second option unless you are dealing with more than a few thousand records.
The obvious solution would be to put the "configuration" information into a Properties object, and then use Properties.store(...) or Properties.storeToXML(...) to save to a file output stream or writer.
You also need to do something to ensure that whatever is reading the file will see a consistent snapshot. For instance, you could write to a new file each time and do a delete / rename dance to replace the the old with the new.
But if the update rate for the file is too high, you are going to create a lot of disc traffic, and you are bound slow down your application. This is going to apply (eventually) no matter what file format / API you use. So, you may want to consider not writing to a file at all.
At some point, configuration that changes too rapidly becomes "program state" and not configuration. If it is changing so rapidly, why do you have confidence that you can meaningfully write it to, and then read it from, a filesystem?
Say more about what the status is an who the consumer of the data is...

How to write data to a file through java?

I want to make a GUI application that contains three functions as follows:
Add a record
Edit a record
Delete a record
A record contains two fields - Name and Profession
There are two restrictions for the application
You can't use database to store info. You have to use a flat file.
Total file should not be re-written for every add/delete operation.
So, my questions are mentioned below:
Q1. Which file format would be better? (.xml or .csv or .txt or any other)
Q2. How can we perform the add/delete operation without the whole file being re-written?
The second part of your question is answered here : Best Way to Write Bytes in the Middle of a File in Java
As for the format - I would go with something as simple as possible. You don't want to have to deal with a bunch of markup processing, as using RandomAccessFile, you will going directly to a byte position. A fixed width style format would be good, so that based on the record number, you can calculate the starting position of a record or field in the file, without having to read everything in the file. The fields would then be padded out to the fixed width with spaces or some other suitable character.
I would go with CSV, zipped. it is both readable, and editable externally.
If CSV is your choice, this can help: http://javacsv.sourceforge.net/
Did you look at this? http://sourceforge.net/projects/flatworm/
Also consider Apache Derbi and HSQLDB
Another solution is this http://www.coyotegulch.com/products/jisp/index.html
You can reinvent the wheel, but that is only required if this is an academic assigment...
Given that the whole file must not be rewritten, I would suggest using RandomAccessFile that allow you to read and write only the record you want.
For the file format, a binary file, using fixed length for the record : ex: Name on 20 characters, Profession on 30.
This will allow you to use the seek() method of RandomAccessFile to directly access your data.

Categories