Storing Instances with Serialization - java

I am making a program that needs to save objects for retrieval at a future date. The program will be given out away as a jar file to different people.
I can already store and retrieve instances of classes when giving the Object input/output stream a absolute path (String) as a parameter.
I can also save images and text files in the resources folder and get it as a resource with getClass().getResource(String path).
Here is the problem:
I have tried every way possible to save/get Objects to/from the resources folder. It gets really weird dealing with URLS and Files and not ordinary Strings. Can someone please help me? I need to be able to save and retrieve objects relative to the classpath so that i can access the objects when the program is a jar file saved in different paths on the computer.

1: resource folder (in jar), is read-only.
You can create datas, store in the jar when you package, but after, it is finished: only to read.
2: so you want user can read and write (and it is not embedded in your app).
if it is personal datas, you can use (for PC):
String appdata= System.getenv("APPDATA");
System.out.println(appdata);
String dataFolder = System.getProperty("user.home") + "\\Local Settings\\ApplicationData";
System.out.println(dataFolder);
String dataFolder2 = System.getenv("LOCALAPPDATA");
System.out.println(dataFolder2);
on my PC, it gives:
C:\Users\develop2\AppData\Roaming
C:\Users\develop2\Local Settings\ApplicationData
C:\Users\develop2\AppData\Local
see this: What is the cross-platform way of obtaining the path to the local application data directory?
it is is for everybody, same principles, but you can encounter security issues
like this:
String programdata = System.getenv("PROGRAMDATA");
System.out.println(programdata);
String allusersprofile = System.getenv("ALLUSERSPROFILE");
System.out.println(allusersprofile); // same thing !
String publicdir = System.getenv("PUBLIC");
System.out.println(publicdir);

Related

How can I use project folders(drawable, raws, etc) as directories inside the application?

If I want to access a directory, I would to the following:
File f = new File(getFilesDir()+"/name");
And then, if f is a directory, I can iterate through the files and do a lot of things.
Can I do the same with the drawable/raw folder? I know how to get the id of a file using the name or the name using the id, but I am not sure how can I use drawable as a directory. I also need to use FileInputStream on some files, so I need a file type, not an id or a name.
I found some 'some what' related questions, like this one: Retrieving all Drawable resources from Resources object
But my problem is a bit different. I know how to get a resource in this way. By getting the id you can do lots of things, but as far as I know, you can not use FileInputStream. That's what I need: the possibility to use FileInputStream on a resource that is inside a project folder(drawable or raw).
Can I do the same with the drawable/raw folder?
Not really.
the possibility to use FileInputStream on a resource that is inside a project folder(drawable or raw)
Resources are not files. You cannot get a FileInputStream on them.
For raw resources, you can call openRawResource() on a Resources object to get an InputStream, though.

Serving file resources contents from subfolder safely, securely

A user can submit a subfolder/filename to download.
The subfolder/filename will then be used to serve a file from a predertemined folder.
In the end, I am doing new File(folder, "subfolder/filename").
But before I do that, I also check that !"subfolder/filename".contains("..")
But is this enough? Is there possibly a scenario where two dots (..) may not come after each other, but still be interpreted as two dots when passed to new File(...) ?
Are there any other way a user can navigate back and reach content outside this folder?
Do you need to do something else to secure such a subfolder/filename access from folder?
One can get the absolute paths, from the OS, so a bit slow.
String folderPath = folder.getCanonicalPath() + File.separator;
File file = new File(folder, "subfolder/filename");
String path = file.getCanonicalPath();
if (!path.startsWith(folderPath)) {
log(Level.ERROR, "Security breach attempt: ...");
return;
}
A simple check would probably do too:
Pattern BREACH = Pattern.compile("\\.[\\\\]*\\.");
if (BREACH.matcher(path).find()) { ... }
Mind when you use version control or other "protected" files/folders, then names of files or folders starting with a dot are illegal too.
You can execute something like
cd ./\.\.
In Unix it will change directory to parent. May be You can resolve file and when check if it under right parent?
UPD: looks like in java You cannot use \.\. pattern http://goo.gl/4Rszg5 still it does not mean what check for ".." is sufficient. Better check canonical path

Android get file using path (in String format)

My app needs to get an existing file for processing. Now I have the path of the file in String format, how can I get the File with it? Is it correct to do this:
File fileToSave = new File(dirOfTheFile);
Here dirOfTheFile is the path of the file. If I implement it in this way, will I get the existing file or the system will create another file for me?
That's what you want to do. If the file exists you'll get it. Otherwise you'll create it. You can check whether the file exists by calling fileToSave.exists() on it and act appropriately if it does not.
The new keyword is creating a File object in code, not necessarily a new file on the device.
I would caution you to not use hardcoded paths if you are for dirOfFile. For example, if you're accessing external storage, call Environment.getExternalStorageDirectory() instead of hardcoding /sdcard.
The File object is just a reference to a file (a wrapper around the path of the file); creating a new File object does not actually create or read the file; to do that, use FileInputStream to read, FileOutputStream to write, or the various File helper methods (like exists(), createNewFile(), etc.) for example to actually perform operations on the path in question. Note that, as others have pointed out, you should use one of the utilities provided by the system to locate directories on the internal or external storage, depending on where you want your files.
try this..
File fileToSave = new File(dirOfTheFile);
if(fileToSave.exists())
{
// the file exists. use it
} else {
// create file here
}
if parent folder is not there you may have to call fileToSave.getParentFile().mkdirs() to create parent folders

Is it possible to read a shapefile using geotools WITHOUT specifying the url of the file?

I am creating a web application which will allow the upload of shape files for use later on in the program. I want to be able to read an uploaded shapefile into memory and extract some information from it without doing any explicit writing to the disk. The framework I am using (play-framework) automatically writes a temporary file to the disk when a file is uploaded, but it nicely handles the creation and deletion of said file for me. This file does not have any extension, however, so the traditional means of reading a shapefile via Geotools, like this
public void readInShpAndDoStuff(File the_upload){
Map<String, Serializable> map = new HashMap<>();
map.put( "url", the_upload.toURI().toURL() );
DataStore dataStore = DataStoreFinder.getDataStore( map );
}
fails with an exception which states
NAME_OF_TMP_FILE_HERE is not one of the files types that is known to be associated with a shapefile
After looking at the source of Geotools I see that the file type is checked by looking at the file extension, and since this is a tmp file it has none. (Running file FILENAME shows that the OS recognizes this file as a shapefile).
So at long last my question is, is there a way to read in the shapefile without specifying the Url? Some function or constructor which takes a File object as the argument and doesn't rely on a path? Or is it too much trouble and I should just save a copy on the disk? The latter option is not preferable, since this will likely be operating on a VM server at some point and I don't want to deal with file system specific stuff.
Thanks in advance for any help!
I can't see how this is going to work for you, a shapefile (despite it's name) is a group of 3 (or more) files which share a basename and have extensions of .shp, .dbf, .sbx (and usually .prj, .sbn, .fix, .qix etc).
Is there someway to make play write the extensions with the tempfile name?

Extract resource folder from running jar in Java 7

My resources folder inside my jar includes a directory with several binary files. I am attempting to use this code to extract them:
try(InputStream is = ExternalHTMLThumbnail.class.getResourceAsStream("/wkhtmltoimage")) {
Files.copy(is, Paths.get("/home/dan/wkhtmltoimage");
}
This is throwing the error
java.nio.file.NoSuchFileException: /home/dan/wkhtmltoimage
Which comes from
if (errno() == UnixConstants.ENOENT)
return new NoSuchFileException(file, other, null);
in UnixException.java. Even though in Files.java the correct options are passed:
ostream = newOutputStream(target, StandardOpenOption.CREATE_NEW,
StandardOpenOption.WRITE);
from Files.copy. Of course there's not! That's why I'm trying to make it. I don't yet understand Path and Files enough to do this right. What's the best way to extract the directory and all its contents?
Confused because the docs for Files.copy claims
By default, the copy fails if the target file already exists or is a symbolic link
(Apparently it fails if the target file doesn't exist as well?)
And lists the possible exceptions, and NoSuchFileException is not one of them.
If you're using Guava:
URL url = Resources.getResource(ExternalHTMLThumbnail.class, "wkhtmltoimage");
byte[] bytes = Resources.toByteArray(url);
Files.write(bytes, new File("/my/path/myFile"));
You could of course just chain that all into one line; I declared the variables to make it more readable.
The file that does not exist may actually be the directory you're trying to create the file in.
/home/dan/wkhtmltoimage
Does /home/dan exist? Probably not if you're on a Mac.

Categories