Android - Count the number of files in a server directory - java

I'm having trouble with simply counting the number of files stored on one of my directories on a server.
I'm an Android beginner and I know I must be making a simple mistake with my code
File file = null;
try {
file = new File(new URI("http://myURL/directory/userImages/"));
}
catch (URISyntaxException e) {
e.printStackTrace();
}
Log.d(TAG, "Num of Files: " + file.list().length);
I'm getting a URI exception:
Expected file scheme in URI: http://myURL/directory/userImages/
I can't seem to find out the problem here. It's obviously a problem with the URI.
Any help or info would be greatly appreciated. Thanks in advance

This won't work as the URI constructor of the File class that you are using only works with file URIs as documented in the JDK. Concretely this means that your URI has the start with "file://", which in itself means that you can only access local files (or files on remote systems mounted as local drives on your system).
I'm not sure what the exact context is of this particular piece of code, but I'm pretty sure that what you are trying to achieve will need some more complex code.
Particularly, as far as I now, it is not possible to fetch a directory via HTTP. I think you might need FTP/SSH/... access to the particular system to solve this.
If you give some more context, I (or others) might be able to give some more help.

Related

How can I make a loaded jar use resources from itself rather than its loader?

Summary: When I load and run one jar from another jar and that loaded jar attempts to access its resources inside itself, it is unable to find those resources. I believe this is because it is looking inside the jar that loaded it instead of itself. How can I fix this?
The problem in more detail:
I am attempting to programmatically load a jar file -- let's call it "Server" -- into the Java Virtual Machine through my own Java program -- let's call it "ServerAPI" -- and use extension and some other tricks to modify the behavior of and interact with Server. ServerAPI depends on Server, but if Server is not present, ServerAPI still has to be able to run and download Server from a website.
To avoid errors caused by ServerAPI loading without satisfying its dependencies from Server, I have made a launcher -- let's call it "Launcher" -- that is intended to download Server and set up ServerAPI as necessary, then load Server and ServerAPI, then run ServerAPI.
I have gotten to the point where Launcher is successfully able to load Server and ServerAPI. However, when I attempt to run Server through ServerAPI, errors appear because Server is unable to locate certain resources. There resources are located inside the Server jar as they always are.
I had the idea that perhaps, since the resource paths all seem to be relative, Java is searching for these resources inside the jar that initially loaded and ran the entire program, i.e. Launcher. To test this, I took some of those missing resources from the Server jar and put them in the same path in the Launcher jar. The errors related to those missing resources disappeared.
So, then, I need a way to ensure that all resources loaded by code in the Server are found in that jar instead of making Java search for them in the Launcher jar. Copying the assets into the Launcher jar worked for my test, but it would be inconvenient and error-prone for the final product, not to mention the fact that it would increase file sizes as there are a large number of resources to copy and that making multiple copies of the same files could lead to errors under certain circumstances.
Ideas that I have already thought of that will not work:
I cannot copy the resources into the Launcher jar because it would increase the size of Launcher; it further complicates the program and can potentially cause errors in cases where sometimes Server is run on its own and sometimes it is run through ServerAPI using Launcher; and it would not allow ServerAPI to be adapted for use with more than one version of Server.
I cannot move all the resources out of Server and into Launcher to eliminate redundancies and ambiguity because for complicated legal reasons, I cannot modify Server. I can, however, modify Launcher or ServerAPI freely, for I created them.
I cannot modify the paths of the resource calls. My tricks for modifying the behavior of Server using ServerAPI will not work in these sections of the code and even if they did, there are so many calls to so many resources that it would take ages to find them all and modify them all.
Research I have already done on this problem:
This question is the only question I've found that seems to be related to the issue, but I cannot modify each call to the resources for the reason mentioned in the paragraph above.
//EDIT:
It seems that Server's resource calls primarily use the format CLASS.class.getResourceAsStream("/RESOURCE"). Does this help at all?
//END EDIT
//EDIT 2:
I tried using Thread.currentThread().setContextClassLoader() to set the ClassLoader to the one I used to load Server, hoping that since I was using the ClassLoader used to load Server that all resource paths would now be relative to Server. Unfortunately, this did not work.
//END EDIT
//EDIT 3:
Up until now, I was initializing the parent of the ClassLoader used to load Server to be Launcher's own ClassLoader, so I just tried setting the parent to null instead to make it act as a standalone ClassLoader, hoping that would break its bond to Launcher. That didn't work either.
//END EDIT
Any help would be greatly appreciated! Thanks in advance!
Through some trickery and hackish fixes, I managed to make it work!
What I did is instead of using the standard URLClassLoader to load the classes in Server and ServerAPI, I used my own custom ClassLoader class that extends URLClassLoader. It worked basically the same way except that I overrode the getResource() method to prepend (attach to the beginning) the absolute path URL of the jar file, basically forcing it to look for the resource in its specific jar file instead of making it relative to the ClassLoader.
The code for that overridden method looks like this:
#Override
public URL getResource(String path) {
/* eliminate the "/" at the beginning if there is one to avoid
conflicts with the "!/" at the end of the URL */
if (path.startsWith("/"))
path.substring(1);
/* prepend "jar:" to indicate that the URL points to a jar file and use
"!/" as the separator to indicate that the resource being loaded is
inside the jar file */
String URL_string = "jar:" + getURLs()[0] + "!/" + path;
try {
return new URL(URL_string);
} catch (MalformedURLException exception) {
System.out.println("There was something wrong with the URL representing this resource!");
System.out.println("URL=\"" + URL_string + "\"");
exception.printStackTrace();
return null;
}
}
I had to learn this the hard way and come up with the fix myself; I hope this answer helps someone else with the same problem!
Note: This also fixes the Class.getResource() method because Class.getResource() simply prepends a "/" if there isn't already one there, then calls ClassLoader.getResource(). It seems to fix Class(Loader).getResourceAsStream() as well, but don't quote me on that one.

Creating a folder within web server under /public_html/ in Java

I am trying to create a folder within web server using Java File handling APIs in my RESTFul web service developed using JERSEY.
According to my understanding, when I target "xyz.com" , it by default points out /home/xyz/public_html/ in my server.
So when I try to create a folder as follows
String appFolderPath = "/xyz.com/appFolder/";
File userNameFolder = new File(appFolderPath + userName);
if (!userNameFolder.exists()) {
folderPath = userNameFolder.mkdir();
}
The above code fails, I am not getting any exception, and no folder is created.
How exactly I suppose to do it ? How to give path for public_html/ folder ?
Another point is, is it not happening because of permission issue ? , I actually tried another way , I manually created /appFolder under public_html/ and give full read write permission to that folder, but still I couldn't create any folder within that using above code.
Please let me know how to achieve it ? Any Sample code ?
Also if possible let me know if JERSEY does give me APIs to make it simple ?
To point to public web directory use
ServletContext context = request.getServletContext();
String path = context.getRealPath("/");
and append your path to the path (above resolved)
According to my understanding, when I target "xyz.com" , it by default points out /home/xyz/public_html/ in my server.
What makes you think so? You're operating files in the code snippet given, so your path means /xyz.com/appFolder/ and nothing more. And it's very likely you're facing a permission issue trying to create folders like this.
As for absense of exception, that's a design feature of Java file API not to throw exceptions on certain failures, but rather return erroneous error codes. Check what is returned by mkdir() call and you'll find false there, as a signal of failure.

How to get filepath?

I am working on an Eclipse Web Dynamic Project, and trying to access a file that exists in my local machine/server.
What I am looking for is something like "base_url()" in CodeIgniter, which automatically points to the directory the server is located.
I am using a Mac.
try{
model.read(new FileInputStream(url),"");
}catch(IOException e)
{
System.out.println("Exception caught"+e.getMessage());
}
This is the part of the code I am working on, which I am trying to feed the correct URL path to read.
After searching StackOverflow and other places, I came across this piece of code:
String url = request.getRequestURL().toString().replace(request.getRequestURI().substring(1), request.getContextPath())
+"/WebContent/WEB-INF/test.xml";
Which did not seem to work.
I then tried to hard code the path directory in, only to realise that I dont know how Mac file systems work :/
Can anyone share some light on this?
Thank you in advance
I did not understand very well if you are using a servlet or something else (like a WS), however the request object exposes a method called getRealPath() which gives well... the real path of the servlet's context in your file system.
So you need to change your code with this:
String url = this.getServletContext().getRealPath("")+"/test.xml";
It has nothing to do with OS, as you surely know java is portable.
I think what you want is
String path = getServletContext().getRealPath("/");
which point to the bas directory of your application in the server
e.g. /opt/tomcat/webapps/MyApp
I always use getResourceAsStream and suck it up off of my class path. Flat file names are problematic inside of web applications.

blocking (synchronous) ftp download in java?

I'm currently using commons-net library for FTP client in my app. I have to download from remote server some files, by some criteria based on the file name. This is a very simplified and reduced version of my actual code (because I do some checks and catch all possible exceptions), but the essence is there:
//ftp is FTPClient object
//...
files = ftp.listFiles();
for (FTPFile ftpFile : files) {
String name = ftpFile.getName();
if(conformsCriteria(name)) {
String path = outDirectory + File.separatorChar + name;
os = new FileOutputStream(path);
ftp.retrieveFile(name, os);
}
}
Now, what I noticed is that when I run this code, wait a few seconds, and then plug out network cable, output directory contains some "empty" files plus the files actually downloaded, which leads me to believe that this method is working somewhat asynchronously... But then again, some files are downloaded (size > 0KB), and there are these empty files (size = 0KB), which leads me to believe that it is still serialized download... Also, function retrieveFile() returns, I quote documentation:
True if successfully completetd, false if not
What I need is serialized download, because I need to log every unsuccessful download.
What I saw browsing through the commons-net source is that, if I'm not wrong, new Socket is created for each retrieveFile() call.
I'm pretty confused about this, so If someone could explain what is actually happening, and offer solution with this library, or recommend some other FTP java library that supports blocking download per file, that would be nice.
Thanks.
You could just use the java.net.URLConnection class that has been present forever. It should know how to handle FTP URLs just fine. Here is a simple example that should give the blocking behavior that you are looking for.
The caveat is that you have to manage the input/output streams yourself, but this should be pretty simple.
Ok, to briefly answer this in order not to confuse people who might see this question.
Yes, commons-net for FTP is working as I thought it would, that is, retrieveFile() method blocks until it's finished with the download.
It was (of course) my own "mistake" in the code that let me think otherwise.

Java Desktop API not working with network paths? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Not possible to launch a file on a network using Java Desktop?
I am trying to use the Desktop API to launch the appropriate app for a file. So i am using this :
if (Desktop.isDesktopSupported())
Desktop.getDesktop().open(new File(path));
where "path" is a String pointing to the file.
Everything works fine until i try to launch a jpg that resides at a network location (for instance "\\MyNet\folder\image.jpg") when i get an IOException :
java.io.IOException: Failed to open
file:////MyNet/folder/image.jpg
Any one knows if there is a way to fix this?
I believe you need to specify the file location/name in standard URI format - which is close to the standard format except for servers. See the javadocs for the URI Class for more information.
At the highest level a URI reference (hereinafter simply "URI") in string form has the syntax
[scheme:]scheme-specific-part[#fragment]
And a little later:
A hierarchical URI is subject to further parsing according to the syntax
[scheme:][//authority][path][?query][#fragment]
so the URI should look something like the following:
file://MyNet/folder/image.jpg
where "file://" is the protocol, "MyNet" is the server, and "/folder/image.jpg" is the directory location under the share.
Hope this helps a little.
file:////MyNet/folder/image.jpg is not a file path. It's an URL.
File f = new File("\\\\192.168.0.4\\mybookrw\\save\\command.txt");
Desktop.getDesktop().open(f);
Worked fine for me. The one caveat is that you have to be authenticated against the share already. If you paste the path into the run box and it prompts you for a username and password then its not going to work from an app.
Everyone so far has assumed that the file isn't being found.
However, looking at the Desktop open() function, an IOException is thrown
if the specified file has no associated
application or the associated
application fails to be launched
Now, having said that, what happens if you open a jpg on your local machine? Also, what happens if you try manually launching the jpg through the network?
Edit: Actually, the problem may be that the default program set to open jpg files doesn't understand file:// uris. Sticking with UNC paths might be a better choice.

Categories

Resources