How to programmatically change filenames on S3 to remove filename extensions? - java

Lets say you have a bunch of images which you want to host on S3 and they are available in various formats: png, jpg, jpeg, gif ... etc.
Writing or using an image-processing service to normalize all image formats, down to a single one, is one approach ... but I'm wondering if its possible to use a shortcut where you can remove the extension name from a filename (after upload) because the file properties now hold the appropriate mime-type anyway?
So after I upload 1.png, 2.jpg, 3.jpeg and 4.gif ... why not programmatically change all filenames to remove the extensions and access the images as:
/my-bucket/1
/my-bucket/2
/my-bucket/3
/my-bucket/4
So, how can someone programmatically change filenames on S3 to remove filename extensions?
I would love to hack on this using substitutions to remove extensions .<ext> from filenames but I think that programmatically its only available for setting up a job for transferring data from devices that you will actually ship to Amazon.

It's not pretty, but it can be done by calling copyObject() for /myBucket/myFile.jpg and setting the new key to be /myBucket/myFile. After the copy is complete, delete the original. At this time I'm not aware of a proper "rename" method available.

Related

Use metadata to uniquely identify files

Hello need to know how to identify the audio file in the storage of a device, the question is as follows:
I am developing a music player and am storing some playback data in the database that are attached to each audio file individually, from time to time the application checks for changes in the user's audio library (on sdcard or internal memory) and inserts the new songs (if any) in the database, the problem is I can not identify if the database already exists because I can not get a common identifier, I tried to use the music path in the storage but in some cases the music name has banned characters that prevent me from using in sqlite so the question is:
How to identify an audio file?
EDIT1:
I think my question was not very clear, what I wanted was a way to individually identify each audio file using for example some metadata of the file that was unique to it and could not be repeated such as the creation date of the file in milliseconds, or any other metadata that is unique to each file, like a fingerprint.
I'm testing a solution that I find not if it is is ideal, I take the path of the file and use the Base64 class to encode it:
String path = "/storage/emulated/0/Download/Disturbed-Ten Thousand Fists.mp3";
Base64.encodeToString(path.getBytes(), Base64.DEFAULT);'
result is: L3N0b3JhZ2UvZW11bGF0ZWQvMC9Eb3dubG9hZC9EaXN0dXJiZWQtVGVuIFRob3VzYW5kIEZpc3Rz
Lm1wMw
The size varies depending on the path but String gets only letters and numbers that are accepted in the database and the result is always the same for each path. What you tink about it?
An audio file can be identified by the extension. A list (not complete) of formats that is used can be found on Wikipedia Audio_file_format
Your best option would probably be to check the file extension and make a list of known extension types related to audio.
This does not, however, cover cases such as an MP4 file with audio and no video.
For the purpose of this, I will assume you already have a variable, either hard coded or in a loop/list, which is the File object you wish to check.
File audioFile;
//this is just for readability, do not write in your code as this should be replaced with the variable you have which is storing the audio file File.
String name = audioFile.getName();
//This is where you can do your logic. The name also returns the extension of the file so you can make sure your music player can handle the file extension, and also check the characters in the name
//Here is an example of detecting the ' character
if(name.contains("'")){
//do something
}
Please let me know if you have further questions!
You must clicked all file format in the file type frame then choose the insert file with audio format such mp3, real, wmp.

Jave Reading Video/Audio Codecs From File

I have a folder of mixed video files (multiple formats for web display mp4, ogv, webm). When retrieving those files in Java I can verify the format by pulling the extension from the filename. Is there a way to retrieve other information such as video and audio codec data from the file?
To create the files I am using ffmpeg from within Java to transcode video files to the formats and sizes I need, so when the file is being created I do know the codec information. If its not automatically stored somewhere in the file, is there a way to set metadata or something and store the info manually so I can retrieve it later? I am not using a database to store file locations or other data, just simply scanning and retrieving from the file system.
I think ffmpeg can automatically obtain video and audio formats from the files you specify as a source for ffmpeg utility.
If you need the metadata for other purposes then you can try Red5 server sources (java). There are a lot of readers (including MP4Reader) that can be used to obtain metadata.
For example for mp4 files MP4Reader scans the entire file in class constructor and then you can obtain metadata from the first tag:
reader = new org.red5.io.mp4.impl.MP4Reader(myFile)
String v = reader.getVideoCodecId(); // e.g. "avc1" (for h.254), "VP6F"
String a = reader.getAudioCodecId(); // e.g. "mp4a" (for aac), ".mp3" (for mp3)
...
To the best of my knowledge there is no easy way to determine file type by content. You have to make assumptions and then test those assumptions with code (e.g. I think it's type X so I'll inspect the first Y bytes for the pattern that always is present in files of type X.)
Video and audio data streams (e.g. H.264/AVC video, AAC, Dolby Digital audio, etc.) are multiplexed (or 'muxed') together inside file formats that are known as a container formats. MP4 is one such container format and is designed to be able to hold many different types of video and audio stream (see http://www.mp4ra.org/codecs.html for some of the officially registered types).
The different container formats have metadata that identifies the different media streams that are contained so as to help determine what type of decoder should be used to decode a particular media stream.
If you can (you said you're using Java), try using ffprobe to determine the container, video and audio formats used in a media file (plus other metadata). It may not be 100% reliable for all media types (as it may not recognise some) but given that you are encoding with ffmpeg (ffprobe is an ffmpeg-derived tool) it should do the job.

Disguising Image Files In Java

I have a situation where I would like to do some very light image file obfustication. My application ships with a bunch of .png files and I'd like it if they weren't so readily editable.
I'm not looking for a 'secure' solution (I don't believe one really exists), I'd just like Joe Public to be unable to edit the files.
I am currently using;
ImageIO.read(new File("/images/imagefile.png"));
I'd rather not have to use Serialisation, as the ImageIO system is pretty deeply ingrained in the code, each image needs also to remain as its own file on disk.
I was hoping I could just change the file extension eg;
ImageIO.read(new File("/images/imagefile.dat"));
But ImageIO seems to use it to identify the file. Can I tell ImageIO that it is a PNG despite its extension?
Encrypt all the files on disk.
Then in the program, decrypt a file, load it in memory and go rocking.
Java image I/O uses the Service Provider Interface to support new image formats1. I believe it might be possible to add a new decoder using a file extension. If that is the case, there is the route to providing an easily pluggable reader for a custom image format.
Note that you will probably need to change the file extension in the source. That might be the job for an advanced IDE, or a one-time search and replace using grep.
As to the format, one extremely simple way make media files unreadable in common readers is to write the bytes of the image in reverse order. Then flip them back after read, put them in a ByteArrayInputStream, and pass them to ImageIO.read(InputStream).
After you have written the service provider and Jar'd it properly (using a manifest with attributes to identify the file/content type it handles, and the corresponding encoder/decoder), add it to the run-time class-path of the app., and it should be able to read the custom image format.
...or keep all images in a single file and seek() to the start position of each image as you load. You can do this by pre-seeking against a FileInputStream, or conversely by creating a ByteArrayInputStream for ImageIO.read(InputStream).
You could try this:
Iterator rs = ImageIO.getImageReadersByFormatName("png");
ImageReader ir = (ImageReader) rs.next();
File srcFile = new File("/images/imagefile.dat");
ImageInputStream iis = ImageIO.createImageInputStream(srcFile);
ir.setInput(iis);

Creating an uneditable data file in Java

I am currently writing a program which takes user input and creates rows of a comma delimited .csv file. I am in need of a way to save this data in a way in which users are not able to easily edit this data. It does not need to be super secure, just enough so that it couldn't accidentally be edited. I also need another file (or the same file?) created to then be easily accessible (in the file system) by the user so that they may then email this file to a system admin who can then open the .csv file. I could provide this second person with a conversion program if necessary.
The file I save data in and the file to be sent can be two different files if there are any advantages to this. I was currently considering just using a file with a weird file extension, but saving it as a text file so that the user will only be able to open it if they know to try that. The other option being some sort of encryption, but I'm not sure if this is necessary and even if it was where I would start.
Thanks for the help :)
Edit: This file is meant to store the actual data being entered. Currently the data is being gathered on paper forms which are then sent to the admin to manually enter all of the data. This little app is meant to have someone else enter the data from the paper form and then tell them if they've entered it all correctly. After they've entered it all they then need to send the data to the admin. It would be preferable if the sending was handled automatically, but this app needs to be very simple and low budget and I don't want an internet connection to be a requirement.
You could store your data in a serializable object and save that. It would resist casual editing and be very simple to read and write from your app. This page should get you started: http://java.sun.com/developer/technicalArticles/Programming/serialization/
From your question, I am guessing that the uneditable file's purpose is to store some kind of system config and you don't want it to get messed up easily. From your own suggestions, it seems that even knowing that the file has been edited would help you, since you can then avoid using it. If that is the case, then you can use simple checks, such as save the total number of characters in the line as the first or last comma delimited value. Then, before you use the file, you just run a small validation code on it to verify that the file is indeed unaltered.
Another approach may just be to use a ZIP (file) of a "plain text format" (CSV, XML, other serialization method, etc) and, optionally, utilize a well-known (to you) password.
This approach could be used with other stream/package types: the idea behind using a ZIP (as opposed to an object serializer directly) is so that one can open/inspect/modify said data/file(s) easily without special program support. This may or may not be a benefit and using a password may or may not even be required, see below.
Some advantages of using a ZIP (or CAB):
The ability for multiple resources (aids in extensibility)
The ability to save the actual data in a "text format" (XML, perhaps)
Maintain competitive file-sizes for "common data"
Re-use existing tooling support (also get checksum validation for free!)
Additionally, using a non-ZIP file extension will prevent most users from casually associating the file (a similar approach to what is presented in the original post, but subtly different because the ZIP format itself is not "plain text") with the ZIP format and being able to open it. A number of modern Microsoft formats utilize the fact that the file-extension plays an important role and use CAB (and sometimes ZIP) formats as the container format for the document. That is, an ".XSN" or ".WSP" or ".gadget" file can be opened with a tool like 7-zip, but are generally only done so by developers who are "in the know". Also, just consider ".WAR" and ".JAR" files as other examples of this approach, since this is Java we're in.
Traditional ZIP passwords are not secure, and more-so is using a static password embedded in the program. However, if this is just a deterrent (e.g. not for "security") then those issues are not important. Coupled with an "un-associated" file-type/extension, I believe this offers the protection asked for in the question while remaining flexible. It may be possible to entirely drop the password usage and still prevent "accidental modifications" just by using a ZIP (or other) container format, depending upon requirement/desires.
Happy coding.
Can you set file permissions to make it read-only?
Other than doing a binary output file, the file system that Windows runs (I know for sure it works from XP through x64 Windows 7) has a little trick that you can use to hide data from anyone simply perusing through your files:
Append your output and input files with a colon and then an arbitrary value, eg if your filename is "data.csv", make it instead "data.csv:42". Any existing or non-existing file can be appended to to access a whole hidden area (and every file for every value after the colon is distinct, so "data.csv:42" != "data.csv:carrots" != "second.csv:carrots").
If this file doesn't exist, it will be created and initialized to have 0 bytes of data with it. If you open up the file in Notepad you will indeed see that it holds exactly the data it held before writing to the :42 file, no more, no less, but in reality subsequent data read from this "data.csv:42" file will persist. This makes it a perfect place to hide data from any annoying user!
Caveats: If you delete "data.csv", all associated hidden data will be deleted too. Also, there are indeed programs that will find these files, but if your user goes through all that trouble to manually edit some csv file, I say let them.
I also have no idea if this will work on other platforms, I've never thought to try it.

Saving Multiple Images in a Single File

In my program i want the user to be able to take some images from a directory, and save them under a single file, that can be transferred to another computer possibly, and actually read and displayed(using the same program).
How would i go about doing this, especially if i want to save other data along with it, perhaps objects and such. I know you can use the ObjectOutputStream class, but im not sure how to integrate it with images.
So overall, i want the program to be able to read/write data, objects, and images to/from a single file.
Thanks in Advance.
[EDIT - From Responses + Comment regarding Zip Files]
A zip might be able to get the job done.
But i want it to be read only be the program. ( You think making it a zip, changing the file extension would work, then when reading it just chaing it back and reading as a zip?? ) I dont want users to be able to see the contents directly.
Ill elaborate a bit more saying its a game, and users can create their own content using xml files, images and such. But when a user creates something i dont want other users to be able to see exactly how they created it, or what they used, only the end result.
You can programatically create a zip file, and read a zip file from Java, no need to expose it as a regular .zip file.
See: java.io.zip pacakge for more information, and these others for code samples on how to read/write zip using java.
Now if you want to prevent the users from unzipping this file, but you don't want to complicate your life by encrypting the content, or creating a complex format, you can emulate a simple internet message format, similar to the one used for e-mails to attach files.
You can read more about the internet message format here
This would be a custom file format only used by your application so you can do it as simple as you want. You just have to define your format.
It could be:
Header with the names ( and number ) of files in that bundle.
Followed by a list of separators ( for instance limit.a.txt=yadayada some identifier to know you have finished with that content )
Actual content
So, you create the bundle with something like the following:
public void createBundle() {
ZipOutputStream out = ....
writeHeader( out );
writeLimits( out yourFiles );
for( File f : youFiles ) {
writeFileTo( f, out );
}
out.close();
}
Sort of...
And the result would be a zipped file with something like:
filenames =a.jpg, b.xml, c.ser, d.properties, e.txt
limits.a.jpg =poiurqpoiurqpoeiruqeoiruqproi
limits.b.xml =faklsdjfñaljsdfñalksjdfa
limit.s.ser =sdf09asdf0as9dfasd09fasdfasdflkajsdfñlk
limit.d.properties =adfa0sd98fasdf90asdfaposdifasdfklasdfkñm
limit.e.txt =asdf9asdfaoisdfapsdfñlj
attachments=
<include binary data from a.jpg here>
--poiurqpoiurqpoeiruqeoiruqproi
<include binary data from b.xml here>
--faklsdjfñaljsdfñalksjdfa
etc
Since is your file format you can keep it as simple as possible or complicate your life at infinitum.
If you manage to include a MIME library in your app, that could save you a lot of time.
Finally if you want to add extra security, you have to encrypt the file, which is not that hard after all, the problems is, if you ship the encrypting code too, your users could get curious about it and decompile them to find out. But a good encrypting mechanism would prevent this.
So, depending on your needs you can go from a simple zip, a zip with a custom format, a zip with a complicated customformat or a zip with a custom complicated encrypted format.
Since that's to broad you may ask about specific parts here: https://stackoverflow.com/questions/ask
In your case I would use a ZIP library to package all the images in a ZIP file. For the metadata you want to save along with these, use XML files. XML and ZIP are quite a de-facto standard today, simple to handle and though flexible if you want to add new files or metadata. There are also serializing tools to serialize your objects into XML. (I don't know them exactly in Java, but I'm sure there are.)
Yep, just pack/unpack them with java.util.zip.* which is pretty straightforward to go. Every Windows Version since XP has built in zip support, so your good to go. There are many good (and faster) free zip libraries for java/c#, too.
I know you can use the ObjectOutputStream class, but im not sure how to integrate it with images.
Images are binary data, so reading it into a byte[] and writing the byte[] to ObjectOutputStream should work. It's however only memory hogging since every byte eats at least one byte of JVM's memory. You'll need to take this into account.

Categories