Reputation: 561
My file structure:
This is how it looks using netbeans project:
-src
-images
-*.jpg
-stock
-*.java
-images (exact copy of -images)
and here is my jar
-jar
-images
-*.jpg
-stock
-*.java
-images (folder is created but files don't get copied)
My files imagesCopy is the one that I create and ImagesOrg is the one inside .jar / src
File imagesCopy = new File("images");
File imagesOrg = new File(URLDecoder.decode(getClass().getResource("/images").getPath()));
if (!imagesCopy.exists()) {
imagesCopy.mkdir();
for(final File child : imagesOrg.listFiles()) {
try{
Files.copy(child.toPath(), Paths.get(imagesCopy.getAbsolutePath()+"/"+child.getName()), REPLACE_EXISTING);
}catch(Exception e){
System.out.println(e);
}
}
}
The problem definitely lies with:
File imagesOrg = new File(URLDecoder.decode(getClass().getResource("/images").getPath()));
When compiling it it gives me, which is the proper directory
D:\Code\build\classes\images
which is the right directory, but when using this program from jar file I get:
D:\Code\dist\file:\D:\Code\dist\egz.jar!\images
and I assume that it should just be:
D:\Code\dist\egz.jar!\images
without that first part
Upvotes: 3
Views: 1197
Reputation: 2070
Probably the simplest way to do it is like this:
public static void main(String[] args) throws URISyntaxException, IOException {
File imagesCopy = new File("C:\\Users\\<YOURNAMEHERE>\\images");
URI uri = ImageCopy.class.getResource("/images").toURI();
if (!uri.toString().startsWith("file:")) {
Map<String, String> env = new HashMap<>();
env.put("create", "true");
FileSystems.newFileSystem(uri, env);
}
Path imagesOrg = Paths.get(uri);
System.out.println(imagesOrg);
if (!imagesCopy.exists()) {
imagesCopy.mkdir();
try(DirectoryStream<Path> paths = Files.newDirectoryStream(imagesOrg)) {
for (final Path child : paths) {
System.out.println(child);
try {
String targetPath = imagesCopy.getAbsolutePath() + File.separator + child.getFileName().toString();
System.out.println(targetPath);
Files.copy(child, Paths.get(targetPath), StandardCopyOption.REPLACE_EXISTING);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
It's not super-pretty, but it works. Might need to fiddle with the code if you have nested directories.
Note that you must create the FileSystem before accessing it (as per the Oracle Docs). I don't know why this is required, but there we go.
I've tested this and it will copy files from inside your JAR to wherever you would like.
Upvotes: 3
Reputation: 23361
Here is a simple code to do it. You can adapt as you need.
package br.com.jjcampos.main;
//imports here
public class CopyImage {
private static ClassLoader loader = CopyImage.class.getClassLoader();
public static void main(String[] args) throws IOException {
InputStream stream = loader.getResourceAsStream("br/com/jjcampos/images/test.jpg");
OutputStream outputStream =
new FileOutputStream(new File("c:/temp/newImage.jpg"));
int read = 0;
byte[] bytes = new byte[1024];
while ((read = stream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
outputStream.close();
}
}
Understand that you can't copy a source from a stream (your jar) as a list of files. Unless you want to unpack it first. My suggestion is you to add a txt file with the list of your images then you read this file and use suggested code to copy each one.
Something like this:
public class CopyImage {
private static ClassLoader loader = CopyImage.class.getClassLoader();
public static void main(String[] args) throws IOException {
copyImages("c:/temp/");
}
public static void copyImages(String pathDestiny) throws IOException{
InputStream listOfFiles = loader
.getResourceAsStream("br/com/jjcampos/images/listImages.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(listOfFiles));
String line;
while ( (line = reader.readLine())!=null ){
InputStream stream = loader.getResourceAsStream("br/com/jjcampos/images/"
+ line);
OutputStream outputStream =
new FileOutputStream(new File(pathDestiny + line));
int read = 0;
byte[] bytes = new byte[1024];
while ((read = stream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
outputStream.close();
}
}
}
And your listImages.txt
with
test.jpg
And you should decide if you put the full path on the text file or not to use in your code.
Upvotes: 1