I get the exception: "URI scheme is not file"
What I am doing is trying to get the name of a file and then save that file (from another server) onto my computer/server from within a servlet.
I have a String called "url", from thereon here is my code:
url = Streams.asString(stream); //gets the URL from a form on a webpage
System.out.println("This is the URL: "+url);
URI fileUri = new URI(url);
File fileFromUri = new File(fileUri);
onlyFile = fileFromUri.getName();
URL fileUrl = new URL(url);
InputStream imageStream = fileUrl.openStream();
String fileLoc2 = getServletContext().getRealPath("pics/"+onlyFile);
File newFolder = new File(getServletContext().getRealPath("pics"));
if(!newFolder.exists()){
newFolder.mkdir();
}
IOUtils.copy(imageStream, new FileOutputStream("pics/"+onlyFile));
}
The line causing the error is this one:
File fileFromUri = new File(fileUri);
I have added the rest of the code so you can see what I am trying to do.
The URI "scheme" is the thing that comes before the ":", for example "http" in "http://stackoverflow.com".
The error message is telling you that new File(fileUri) works only on "file:" URI's (ones referring to a pathname on the current system), not other schemes like "http".
Basically, the "file:" URI is another way of specifying a pathname to the File class. It is not a magic way of telling File to use http to fetch a file from the web.
Your assumption to create File from URL is wrong here.
You just don't need to create a File from URL to the file in the Internet, so that you get the file name.
You can simply do this with parsing the URL like that:
URL fileUri = new URL("http://local.wasp.uwa.edu.au/~pbourke/miscellaneous/domefisheye/ladybug/fish4.jpg");
int startIndex = fileUri.toString().lastIndexOf('/');
String fileName = fileUri.toString().substring(startIndex + 1);
System.out.println(fileName);
Related
I use Eclipse + Vaadin framework.
At first I save my image into the WEB-INF folder.
Then I load this image into the FileResource variable, create Image variable and then add Image variable into Layout.
The page URL to the image resource looks like: http://servername/sitename/APP/connector/0/16/source/qwerty1.png
How to get URL in that format for use image externally?
Variable basepath returned local path: "..../WEB-INF/qwerty1.png"
String str = (String) VaadinService.getCurrent().getBaseDirectory().
getAbsolutePath() +"/WEB-INF/qwerty1.png";
File temp = new File(str);
FileOutputStream fos = new FileOutputStream(temp);
fos.write(os.toByteArray());
fos.flush();
fos.close();
String basepath = VaadinService.getCurrent().getBaseDirectory().
getAbsolutePath() +"/WEB-INF/qwerty1.png";
FileResource resource = new FileResource(new File(basepath));
Image image2 = new Image("Image from file", resource);
addComponent(image2);
If you put the file in ...src/main/webapp/VAADIN/image.png, it should be available using for example localhost:8080/VAADIN/image.png.
I don't get it - I'm trying to get the path of a file so that the file (an image) can be included as an attachment in an email.
My system consists of two parts - a web app and a jar. (actually three parts - a common shared jar containing DAOs etc.)
They're both built using maven.
They both contain this image in this path:
src/main/resources/logo_48.png
WebApp:
String logo1 = getClass().getClassLoader().getResource("logo_48.png").getPath();
This works perfectly - both on local (Windows) and Linux
Jar Application:
String logo1 = getClass().getClassLoader().getResource("logo_48.png").getPath(); //doesn't work
I've taken advice from here:
How to access resources in JAR file?
here:
Reading a resource file from within jar
here:
http://www.coderanch.com/t/552720/java/java/access-text-file-JAR
and others
Most answers offer to load the file as a stream etc. but I'm only wishing to get the path assigned to the String. Other resources have led me to hacking the code for hours only to find the end result doesn't work.
After so many instances of /home/kalton/daily.jar!logo_48.png does not exist errors I was frustrated and settled on the following workaround:
Copy the logo_48.png directly to the folder where the jar resides (/home/kalton/)
Alter my jar application code to:
String logo1 = "/home/kalton/logo_48.png";
And it works.
Could anyone show me the right way to get the PATH (as a String) of a file in the resources folder from a JAR that is not unpacked?
This issue was driving me crazy for weeks!
Thanks in advance.
KA.
Adding actual use code of 'path' for clarity of use:
public static MimeMultipart assemble4SO(String logoTop, String emailHTMLText) throws MessagingException, IOException {
MimeMultipart content = new MimeMultipart("related");
String cid = Long.toString(System.currentTimeMillis());
String cidB = cid + "b";
String cssStyle = "";
String body = "<html><head>" + cssStyle + "</head><body><div>" + "<img src='cid:" + cid + "'/>" + emailHTMLText + "<img src='cid:" + cidB + "'/></div></body></html>";
MimeBodyPart textPart = new MimeBodyPart();
textPart.setContent(body, "text/html; charset=utf-8");
content.addBodyPart(textPart);
//add an inline image
MimeBodyPart imagePart = new MimeBodyPart();
imagePart.attachFile(logoTop);
imagePart.setContentID("<" + cid + ">");
imagePart.setDisposition(MimeBodyPart.INLINE);
content.addBodyPart(imagePart);
.............
From the top…
A .jar file is actually a zip file. A zip file is a single file that acts as an archive. The entries in this archive are not separate files, they're just sequences of compressed bytes within the zip file. They cannot be accessed as individual file names or File objects, ever.
Also important: The getPath method of the URL class does not convert a URL to a file name. It returns the path portion of the URL, which is just the part after the host (and before any query and/or fragment). Many characters are illegal in URLs, and need to be “escaped” using percent encoding, so if you just extract the path directly from a URL, you'll often end up with something containing percent-escapes, which therefore is not a valid file name at all.
Some examples:
String path = "C:\\Program Files";
URL url = new File(path).toURI().toURL();
System.out.println(url); // prints file:/C:/Program%20Files
System.out.println(url.getPath()); // prints /C:/Program%20Files
File file = new File(url.getPath());
System.out.println(file.exists()); // prints false, because
// "Program%20Files" ≠ "Program Files"
String path = "C:\\Users\\VGR\\Documents\\résumé.txt";
URL url = new File(path).toURI().toURL();
// Prints file:/C:/Users/VGR/Documents/r%C3%A9sum%C3%A9.txt
System.out.println(url);
// Prints /C:/Users/VGR/Documents/r%C3%A9sum%C3%A9.txt
System.out.println(url.getPath());
File file = new File(url.getPath());
System.out.println(file.exists()); // prints false, because
// "r%C3%A9sum%C3%A9.txt" ≠ "résumé.txt"
Based on your edit, I see that the real reason you want a String is so you can call MimeBodyPart.attachFile. You have two options:
Do the work of attachFile yourself:
URL logo = getClass().getLoader().getResource("logo_48.png");
imagePart.setDataHandler(new DataHandler(logo));
imagePart.setDisposition(Part.ATTACHMENT);
Copy the resource to a temporary file, then pass that file:
Path logoFile = Files.createTempFile("logo", ".png");
try (InputStream stream =
getClass().getLoader().getResourceAsStream("logo_48.png")) {
Files.copy(stream, logoFile, StandardCopyOption.REPLACE_EXISTING);
}
imagePart.attachFile(logoFile.toFile());
As you can see, the first option is easier. The second option also would require cleaning up your temporary file, but you don't want to do that until you've sent off your message, which probably requires making use of a TransportListener.
I'd like to get the absolute path of a file, so that I can use it further to locate this file. I do it the following way:
File file = new File(Swagger2MarkupConverterTest.class.getResource(
"/json/swagger.json").getFile());
String tempPath = file.getAbsolutePath();
String path = tempPath.replace("\\", "\\\\");
The path irl looks like this:
C:\\Users\\Michał Szydłowski\\workspace2\\swagger2markup\\bin\\json\\swagger.json
However, since it contains Polish characters and spaces, what I get from getAbsolutPath is:
C:\\Users\\Micha%c5%82%20Szyd%c5%82owski\\workspace2\\swagger2markup\\bin\\json\\swagger.json
How can I get it to do it the right way? This is problematic, because with this path, it cannot locate the file (says it doesn't exist).
The URL.getFile call you are using returns the file part of a URL encoded according to the URL encoding rules. You need to decode the string using URLDecoder before giving it to File:
String path = Swagger2MarkupConverterTest.class.getResource(
"/json/swagger.json").getFile();
path = URLDecoder.decode(path, "UTF-8");
File file = new File(path);
From Java 7 onwards you can use StandardCharsets.UTF_8
path = URLDecoder.decode(path, StandardCharsets.UTF_8);
The simplest way, that doesn't involve decoding anything, is this:
URL resource = YourClass.class.getResource("abc");
Paths.get(resource.toURI()).toFile();
// or, equivalently:
new File(resource.toURI());
It doesn't matter now where the file in the classpath physically is, it will be found as long as the resource is actually a file and not a JAR entry.
URI uri = new File(Swagger2MarkupConverterTest.class.getResource(
"/json/swagger.json").getFile()).toURI();
File f = new File(uri);
System.out.println(f.exists());
You can use URI to encode your path, and open File by URI.
You can use simply
File file = new File("file_path");
String charset = "UTF-8";
BufferedReader reader = new BufferedReader(new InputStreamReader(
new FileInputStream(file), charset));
give the charset at the time of read the file.
I am trying to get a URI to a resource in my res/raw/ directory. The goal is to give this URI to a VideoView, but this has been problematic, and I seem to be unable to open the file with test code.
I have the following test code:
String uri = "android.resource://com.my.package/" + R.raw.sample_video;
File inputFile = new File(uri);
try {
InputStream is = new FileInputStream(inputFile);
byte[] bytes = new byte[50];
is.read(bytes);
Log.d("test", new String(bytes));
} catch(IOException e) {
}
The new FileInputStream line throws a FileNotFoundException regardless of what variation i try on the URI, but every piece of evidence I see seems to agree that this is the correct form.
For reasons relating to the architecture of the project, the Resource methods that return an InputStream directly aren't an option here, so the URI is the only option that I can see.
What is going wrong? Am I mistaken in how to specify the URI for this file? Is this test code not representative of whether or not the VideoView will be able to read the file? If not, what is? Does this test code work for you (which would indicate that something must be wrong with my project configuration)?
To get the URI of sample_video in raw folder :
Uri videoUri = Uri.parse("android.resource://" + getPackageName() + "/"
+ R.raw.sample_video); //do not add any extension
To play the video :
videocontainer.setVideoURI(Uri.parse(videoUri));
videocontainer.start();
where videocontainer of type videoview.
If I have a resource on a classpath, I can both load it as stream fine, and there is even a URL representation of it. Unfortunately some implementations of the Url do not implement lastModified correctly.
What I would like is to take a path to something in the classpath, and then resolve it to a file that it is in on disk - if it in a jar, then a File pointing to the jar is fine. I can then get the lastModified from the File object instead of the URL, which will be more helpful.
Roughly speaking:
URL url = this.getClass().getResource(myResource);
String fileName;
if (url.getProtocol().equals("file")) {
fileName = url.getFile();
} else if (url.getProtocol().equals("jar")) {
JarURLConnection jarUrl = (JarURLConnection) url.openConnection();
fileName = jarUrl.getJarFile().getName();
} else {
throw new IllegalArgumentException("Not a file");
}
File file = new File(fileName);
long lastModified = file.lastModified();
Should do what you want. You will need to catch IOException.
No. This can't be done generally because URL can represent resources which are not associated with a file. For example, it can be HTTP, FTP or JNDI etc.
You can check for protocol and create the File yourself if the protocol is file-based, like "file://path", "jar://path!...".