My Code:
I'm currently developing a game and throughout several different parts of the code I'm using some resources (Images/Sounds/Animations etc.). To avoid loading the same resource twice I wrote a ResourceManager, that returns the wanted resource if I pass a string to it.
Here's an example:
Image myImage = imageManager.getImage("princess");
This way I can reference a resource without knowing the name of the file or position of it, when I want to use it.
The trick here is that I have to load the images before I can get them like so:
imageManager.loadImage("res/princessImage.png", "princess");
This creates the ImageObject from the given file, and stores it into a HashMap with the given key.
My Problem:
I really don't want to hardcode the paths to these resources, because I'd have to change the sourcecode every time I decide to move or rename any of the resource-files.
A possible solution (?):
I thought about creating another HashMap that reads some kind of configFile and maps the in-code-resource-names to the resource-paths in a HashMap. The file would look somewhat like this:
princess: res/princess.png
hero: res/hero.png
sword: res/items/sword.png
This way I could use resource-names like "princess", "hero" or "sword" safely and don't worry about their position on the hard drive while I'm coding. Whenever I move or rename a resource-file I just update the path/name in this configFile and everything would be fine.
On the other hand I think it's pretty ugly to have one giant file that maps every in-code-resource-name to a path. This could result in one giant String to String HashMap which I'd have to store in the ResourceManager aswell. Things could get pretty confusing/unclear.
Does anyone have a better solution for me?
I'd really appreciate your help,
Thanks :)
Using a config or resource file as you described is a fine approach. Instead of populating a HashMap, though, consider using ResourceBundle or PropertyResourceBundle. It is designed to hold/access such things. http://docs.oracle.com/javase/6/docs/api/java/util/ResourceBundle.html
Related
I'm building an application that downloads a set of images from a website, extracts some features from them and then allows a user to compare an image she submits to the downloaded set, to see which one is the closest. At the moment the application downloads the images and extracts the features from them. Then the image and the feature get wrapped in an object and stored in a map, with the key as the name of the image, and the value as the aforementioned wrapped object.
Because this is stored in memory, each time I start the application it has to go through the quite expensive process of downloading and feature extraction. It would be much quicker if it could just load this info from disk, but I'm not sure on the best way to go about it - I've thought about these options:
RDMS: something like Postgres or SQLite
NoSQL: something like
Voldemort or Reddis
Serialisation: use built in java methods to write
objects to a file (could also be used in conjunction with a DB
though...)
I want it to be really light weight; I want to keep the application as small as possible and keep configuration down to a minimum. For this reason serialisation seems like the way to go, but I'd like a second (or more) opinion on that, because something about doing it that way just feels wrong. I can't quite put my finger on why I feel like that...
I should also say that users can add images to the set when the application is running, I'd like to save these images too.
I wouldn't recommend serialzation - just too many pitfalls.
If what you have is really just a map, then i think any of the key-value stores ( like redis) would be appropriate.
If you have more complex data, then you might want to consider a database (whether SQL or no-sql).
I have a RuneScape Private Server project coded in Java, and am trying to code a personal "tag" that players can use. I have managed to do this, but everytime there is a restart on the server, their "tag" gets reset to "null".
Their "tag" is initalized by doing a command ";;settag [name]". Their tag is then set to whatever they want. I have done this through a string:
if (command[0].equals("settag")) {
newTag = getCompleteString(command, 1);
newTag = player.yellTag
player.sendMessage("Your tag is now:" +newTag);
}
I am unsure what the most efficient way to fix this would be, I am thinking of just loading and saving through .xml/.txt files. By the way, player.yellTag is where the next command (::mytag) searches it from, which works fine, until there is a restart of the server.
it all depends on the context of your application. If you are planning on having less than a few hundreds players, then a xml file may be ok. You should look at JAXB, which is, afaict, the standard way to store your objects in Java. You can also store them as JSON files, using gson which is way simpler to use and implement than XML stuff.
But if you get to have more than thousands of players, you may want to get some more efficient way to serialize your tags by putting them in a database, and thus an ORM library like hibernate could help you do that.
You may want to make your own stuff, like a tag directory full of files named after unique ids of your players containing the players' tag... It's a lot more "hackish" but still quite efficient.
Following on from my previous question, my program doesn't detect the 300 images that have just been created in a particular directory; instead, it only detects desktop.ini, which is not the case as I can physically see that the files have been created within said directory and do exist.
Can somebody please explain why this happens as when I run the program the next time, it seems to work just fine?
The only way that something is detected within the directory on the first run is when there is at least one file which exists in the directory before the program is compiled and executed.
Many thanks.
UPDATE: Files are detected as follows:
//Default greyscale image directory (to convert from greyscale to binary).
static File dirGrey = new File("test_images\\Greyscale");
//Array of greyscale image filenames.
static File imgListGrey[] = dirGrey.listFiles();
without knowing how you create the images, this question is akin to 'How many kittens are under my desk right now?'
Are you creating the files yourself? If so, are you closing any file handles referring to those files once they are created?
You're creating the file list in a static array, and it's created when the class containing the array is loaded by the Java class loader, which is probably before you create the image files. That's why the array contains an outdated list.
static is rarely needed, mostly useful for constants (things that never change, such as 42), for pure functions (Math.sqrt()) and a few other special cases. When you use it, you have to learn all the tricky initialization order stuff. Otherwise, just stick with non-static variables.
Most sites I have found are doing the properties in only Java, not using JSP. This says its a beginners guide but it doesn't make much sence to me: Site Link
I can't follow where or how the file is being made, how it is named, and where it is stored. Can you explain this?
Do I need to make a Java class to make this work, or can everything just be done in JSP with an import or two?
Then once it is created, do you have to make defaults for all key's that you plan to use or can you make new keys as you need to add them? (and how?)
When you have those saved, what is the simplest way to pull the value of the key out of the file to use on my webpage? (plan to pull that key and use if/else statements to do stuff based on it).
Sorry this is so many questions. I really have no clue where to even start with this and nothing i've searched so far has helped me get started. Please don't say just look at a tutorial because I have looked at quite a few and nothing so far has helped. Also, please explain in as simple terms as possible and with examples if possible as well. I can understand things better when I'm given an example and its explained to me how to follow it.
Thanks
Look at this description.
While a properties file doesn't need to end in ".properties" it is basically a key->value pairing where
key1=value1
key2=value2
key3=value3
(and so on). There's a java.util.Properties class which can read this file easily (the Properties class) and can write the values easily. The result is a Map where the keys are the "keys" of the properties file, and the stored items are the "values" of the same file.
For those unfamiliar with JNotify, this is a library which provides an easy way to monitor events in a directory.
For instance, when a file gets deleted in the selected folder, the method "fileDeleted" gets called, along with a few parameters. Here's an example of the fileDeleted method:
public void fileDeleted(int wd, String rootPath, String name) {
print("deleted " + rootPath + " : " + name);
}
Now, I would like to know if the deleted file was a file or directory. My usual approach is to create a new File object with the given path, and use the methods isFile() and isDirectory()
However, since this file is already deleted, these methods always return false.
So here's my concrete question: I have the path to a deleted file or directory, how can I tell wether it was a file or a directory? Is there a workaround to this? What's the best practice to do here?
Thank you in advance.
I suggest using a better API for this, like Commons IO. It has this distinction in its interface org.apache.commons.io.monitor.FileAlterationListener and its methods onFile...(), onDirectory...(). Alternatively, and this is probably the best approach, use the new standard feature for this that comes with Java 7, WatchService, as discussed here.
How big is the directory structure you're looking at?
My first instinct is to build an internal representation of the directory structure, using some simple graph traversal algorithm, and then do a lookup every time something is removed to figure out what it was.
<edit>
If you know your directory structure is a strict tree you can use a simple recursion to traverse the file system, and create a map of Files or Strings to boolean, so you can do an easy lookup. Then, once you've got the map built it should be easy to maintain using the JNotify events.
<edit/>
even for medium-sized directories I would think this could be made pretty quick. What is this for? Might there be another way of going about achieving the same goal?
I am facing the same problem. Yet as far as I understand it, Java's WatchService does not allow monitoring of subdirectories, so I cannot use it (task is to monitor changes to a structure containing ~40K folders). I will try and go ahead using the simple (and fallible) heuristic
If it contains a dot ('.'), it's a file.
I will post updates if I come across something more sophisticated...