I'm working on an application that syncs data. For Mac OS, files are uploaded and if they contain resource fork information, the fork is read and stored as a string using: file/..namedfork/rsrc
Users can access their files using a Web application(Java) that's running on a Linux server, is there a way that I can generate a valid AppleDouble format file using only the data fork and the string I read from the namedfork? I don't mind losing the Finder Metadata.
Note: The generated file will be downloaded (using the Web Application) as a single file for Mac OS users.
Is this possible?
Regards
As far as I'm aware, OS 9/OS X can only natively access the resource forks on files served by AppleTalk shares. For other media, e.g. SMB (Microsoft Networking) or HTTP, the only way to preserve the resource fork is to place the file in an archive.
There are several Mac-specific archive formats that support this, for example, StuffIt and HQX. I very much doubt the Linux binaries for StuffIt would allow packaging a resource fork from a separate file, but at least there is something for you to evaluate.
Looking at the AppleDouble Wikipedia entry, it seems it may be possible to create such a file from a non-Apple machine using an open source tool, and sending the resultant file using the multipart/appledouble MIME type. Perhaps you could call this binary from your Java code?
The wikipedia article states:
AppleSingle combined both file forks and the related Finder meta-file information into a single file, whereas AppleDouble stored them as two separate files.
The apple knowledgebase article states:
The second new file has the name of the original file prefixed by a "._ " and contains the resource fork of the original file.
So I assume you just have to save the content of your resource fork string into the appropriately named file.
Edit:
After your comment I'm not sure what you want. Your question was how to
Create AppleDouble formatted file in Linux
and the documentation I linked to shows that you need to create two files to do that one containing the data and one containing the resource fork with a name that has ._ prefixed. If that is not what you want then you need to ask a different question.
Related
Summary:
I have a program I want to ship as a single jar file.
It depends on three big resource files (700MB each) in a binary format. The file content can easily be accessed via indexing, my parser therefore reads these files as RandomAccessFile-objects.
So my goal is to access resource files from a jar via File objects.
My problem:
When accessing the resource files from my file system, there is no issue, but I aim to pack them into the jar file of the program, so the user does not need to handle these files themselves.
The only way I found so far to access a file packed in a jar is via InputStream (generated by class.getResourceAsStream()), which is totally useless for my application as it would be much too slow reading these files from start to end instead of using RandomAccessFile.
Copying the file content into a file, reading it and deleting it in runtime is no option eigher for the same reason.
Can someone confirm that there is no way to achieve my goal or provide a solution (or a hint so I can work it out myself)?
What I found so far:
I found this answer and if I understand the answer it says that there is no way to solve my problem:
Resources in a .jar file are not files in the sense that the OS can access them directly via normal file access APIs.
And since java.io.File represents exactly that kind of file (i.e. a thing that looks like a file to the OS), it can't be used to refer to anything in a .jar file.
A possible workaround is to extract the resource to a temporary file and refer to that with a File.
I think I can follow the reasoning behind it, but it is over eight years old now and while I am not very educated when it comes to file systems and archives, I know that the Java language has evolved quite much since then, so maybe there is hope? :)
Probably useless background information:
The files are genomes in the 2bit format and I use the TwoBitParser from biojava via the wrapper class TwoBitFacade?. The Javadocs can be found here and here.
Resources are not files, and they live in a JAR file, which is not a random access medium.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions must demonstrate a minimal understanding of the problem being solved. Tell us what you've tried to do, why it didn't work, and how it should work. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I want to recover files from a disk by Java without using native libraries
I'm doing this using Java 8
As far as I know deleted files remain on the disk until they are overwritten
I have direct access to disk on linux and I can read raw data, but, how can I parse deleted files on an ext4 or NTFS file system for example?
Thanks.
Recovering deleted files requires knowledge of how the underlaying file system is implemented, so you have a bit of reading to do before you can get anywhere.
In theory, YES, you can definitely do this in pure Java; you just need to find out how to read data from a raw disk, bypassing the file system. On a Unix system this is simple: open the device node as a file (you'll need root permissions) and just read. On Windows there is probably a similar process; at worst you'll have to create a helper library in C or C++ to read the data for you.
Once you get access to the raw data, look up how files are stored in your particular file system and start looking for similar patterns in the data that you read.
This is not something you can do in an afternoon though.
Update: How to bypass the file system.
On a Unix system you can read from a partition or volume like this:
InputStream sda1 = new FileInputStream("/dev/sda1");
int firstByte = sda1.read();
On Windows you would read from \\.\PhysicalDisk0. From Naming Files, Paths, and Namespaces:
Another example of using the Win32 device namespace is using the CreateFile function with "\\.\PhysicalDiskX" (where X is a valid integer value) or "\\.\CdRomX". This allows you to access those devices directly, bypassing the file system. This works because these device names are created by the system as these devices are enumerated, and some drivers will also create other aliases in the system. For example, the device driver that implements the name "C:\" has its own namespace that also happens to be the file system.
APIs that go through the CreateFile function generally work with the "\\.\" prefix because CreateFile is the function used to open both files and devices, depending on the parameters you use.
If you're working with Windows API functions, you should use the "\\.\" prefix to access devices only and not files.
Most APIs won't support "\\.\"; only those that are designed to work with the device namespace will recognize it. Always check the reference topic for each API to be sure.
I don't know if the Java API is implemented using CreateFile or if it does some name mangling that means you can't access the device namespace. In the worst case you'll have to create a wrapper library that calls CreateFile and turns the HANDLE it returns into a file descriptor that can be used in Java; that's no work at all.
Files by definition are named sequences of bytes stored on permanent storage device.
Files are managed by OS component named file system. File system operates with term "file" and translates this term to lower level terms like volume, sector, block etc.
Mapping between file name (and path) and blocks on your disk where the information is actually stored is named files table and is managed by file system.
When you delete file you ask file system to remove appropriate entry from file table. This means that indeed the file content is not deleted from disk physically and if you are lucky enough can probably be restored. Why probably? Because once the file entry is removed from the table the space occupied by file can be re-used and therefore other information can be stored there.
There are tools that try to restore the information. These tools work on level under file system, i.e. use lower level APIs. Probably they are talking directly to driver. Java does not provide API for doing this.
Therefore you have the following solutions.
Implement this task in native language.
Use existing tools that do this task and provide either API or command line interface.
I am working on rewriting a Java web application to Rails which relies heavily on collections (100's or 1000's) of large (50-100MB) TIFF files. In the Java version, the user specifies a local root path (such as a mounted SAN drive) for these files in the application configuration, and they are read by the application using these paths. The application also writes new files to those paths.
Essentially, users must be able to add files to the application in two ways:
1) Specify a storage location as the 'root' for a collection of TIFFs, which could already contain many TIFFs. These are then processed.
2) Upload new files to an existing collection, which would then be written to the above path and processed.
I guess the gist of my question is: What is the standard way to store, retrieve, and write to such large files in the context of web applications? Should the availability of a local file system with enough storage space be assumed, or is there a better way to do it?
I would look into storing the files with paperclip or carrierwave. They are two great file upload and management gems that allow you to store your files in many different ways.
I have included links to two great sceencasts above and here are the github pages for paperclip and carrierwave.
I am doing a project in java and in that i need to add and modify my
text file at runtime,which is grouped in the jar.
I am using class.getResourceAsStream(filename) this method we
can read that file from class path.
i want to write into the same textfile.
What is the possible solution for this.
If i can't update the text file in jar what other solution is there?
Appreciate any help.
The easiest solution here is to not put the file in the jar. It sounds like you are putting files in your jar so that your user only needs to worry about one file that contains everything related to that program. This is an artificial constraint and just add headaches.
There is a simple solution that still allows you to distribute just the jar file. At start up, attempt to read the file from the file system. If you don't find it, use default values that are encoded in you program. Then when changes are made, you can write it to the file system.
In general, you can't update a file that you located using getResourceAsStream. It might be a file in a JAR/ZIP file ... and writing it would entail rewriting the entire JAR file. It might be a remote file served up by a Url classloader.
For your sanity (and good practice), you should not attempt to update files that you access via the classpath. If you need to, read the file out of the JAR file (or whatever), copy it into the regular file system, and then update the copy.
I'm not saying that it is impossible to do this in all cases. Indeed, in most normal cases you can do it with some effort. However, this is not supported, and there are no standard APIs for doing this.
Furthermore, attempts to update resources are liable to cause anomalies in the classloader. For example, I'd expect resources in JAR files to not update (from the perspective of the application) until the application restarted. But resources in exploded JAR files probably would update ... though new resources might not show up.
Finally, there are cases where updating a resource is impossible:
When the user doesn't have write access to the application's installation directory. This is typical for a properly administered UNIX / Linux machine.
When the JAR file is fetched from a remote server, you are likely not to be able to write the updates back.
When you are using an arbitrary custom classloader, you've got no way of knowing where the actual bytes of an updated resource should be stored, and no way of storing them.
All JAR rewriting techniques in Java look similar. Open the Jar file, read all of it's contents, and write a new Jar file containing the unmodified contents (and the modifications you whished to make). Such techniques are not advisable for a Jar file on the class path, much less a Jar file you're running from.
If you decide you must do it this way, Java World has a few articles:
Modifying Archives, Part 1
Modifying Archives, Part 2
A good solution that avoids the need to put your items into a Jar file is to read (if present) a properties file out of a hidden subdirectory in the user's home directory. The logic looks a bit like this:
if (the hidden directory named after my application doesn't exist) {
makeTheHiddenDirectory();
writeTheDefaultPropertiesFile();
}
Properties appProps = new Properties();
appProps.load(new FileInputStream(fileInHiddenDir));
...
... After the appProps have changed ...
...
appProps.store(new FileOutputStream(fileInHiddenDir), "Do not modify this file");
Look to java.util.Properties, and keep in mind that they have two different load and store formats (key = value based and XML based). Pick the one that suits you best.
If i can't update the text file in jar what other solution is there?
Store the information in any of:
Cookies
The server
Deploy the applet using 1.6.0_10+, launch it using JWS and use the PersistenceService to store the information. Here is my demo. of the PersistenceService.
Also, if your users will agree to a trusted applet (which seems overkill for this), you might write the information to a sub-directory of user.home.
I am attempting to store the change made to my application's properties. The .properties file is located in resources package, which is different from the package that contains my UI and model.
I opened the package using:
this.getClass().getClassLoader().getResourceAsStream("resources/settings.properties")
Is there a functional equivalent of this that permits me to persist changes to the Properties Class in the same .Properties file?
In general, you cannot put stuff back into a resource you got from the classloader:
Class loader resources are often read-only; i.e. held in read-only files / read-only directories.
If you got the resource from a JAR file, JAR files are not simply updateable. (To "update" you need to extract the old JAR's contents and create a new JAR with the updated contents. It is all to do with the structure of ZIP files ...)
In some cases, the class loader resource will have been downloaded on-the-fly, and there is no way to push changes back to the place where you downloaded from.
Even if you can update a resource you got from the classloader, it is a bad idea / bad practice.
Doing this "pollutes" the clean application installation with a user's preferences. Among other things, this means that the installation cannot be shared with other users (unless you handle preferences for multiple users ...).
There are security issues with having applications installed as writeable so that embedded preferences can be updated. Think viruses! Think one user who might be inclined to trash another user's preferences!
There are administration issues with having user-specific copies of applications. And if the user has to install his own copy of an app, there are potential security issues with that as well.
There may be technical issues with file locking or caching on some platforms that either get in the way of (safe) updates or make it difficult for an application to load the updated resource without a restart.
Finally, this is NOT the way that system administrators (and educated users) expect software to behave. Java applications should deal with user preferences in the expected way:
You can use the Java Preferences API.
You can write a Properties file containing the preferences to an OS-appropriate user-writable directory.
On Windows, you could use a Windows-specific API to store the preferences in the Windows registry, except that this makes your application Windows dependent. (I can't see any real advantage in doing this, but I am not a Window expert.)
When you wrap your app up as a JAR file, your properties file will be one (possibly compressed) file within that JAR, and it would be a bad idea to try to write to your own JAR.
getResourceAsStream() is meant to open resources for reading, and these can be anywhere on the classpath. You can't write to URLs or inside JARs, you can only write to files, so it doesn't make sense to give you the same API for output.
Find yourself a directory you're allowed to write into, and write your properties there.
It may be a good idea to copy your properties from your installation classpath (possibly inside a JAR) directly out to a file if it doesn't yet exist, as a first operation upon application startup. This will give you a properties file you can write to, yet the master copy of this properties file will come from your project deliverable.
It sounds like you want to store user preferences. Consider using the Java Preferences API for that.
In addition to Carl's answer, if you're going to read and write to this file frequently, and expect that your application will expand in scope, consider whether to go one step (or several steps) further and use a file-based database like SQLite. There are a few JDBC wrappers for SQLite that would allow you to go beyond the basic string key-value lookup that the Java Properties interface provides.
even though writing the file into resources is not good practical, we still need to do it when our application only run in IDEA locally without deployment, then we can do it as below:
URL resource = Thread.currentThread().getContextClassLoader().getResource("settings.properties");
String path= resource.getPath();
OutputStream outputStream = new FileOutputStream(path);
//outputStream write