working - java file copy thread




jar 파일을 jar 파일 외부로 복사하는 방법은 무엇입니까? (6)

0 바이트 파일에 대한 귀하의 의견을 감안할 때, 나는 당신이 프로그래밍 방식으로 이것을하려는 것으로 가정해야하고, 당신의 태그가 주어진다면, 당신은 자바로 그것을하고있다. 사실이라면 Class.getResource() 를 사용하여 JAR 파일을 가리키는 URL을 가져온 다음 Apache Commons IO FileUtils.copyURLToFile() 을 사용하여 파일 시스템에 복사한다. 예 :

URL inputUrl = getClass().getResource("/absolute/path/of/source/in/jar/file");
File dest = new File("/path/to/destination/file");
FileUtils.copyURLToFile(inputUrl, dest);

대부분의 코드에서 현재 문제는 버퍼링 된 출력 스트림을 사용하여 파일에 쓰지만 (잘못) 닫지 못하는 것입니다.

오, 당신이 질문을 편집해서 정확히 어떻게 하고 싶은지를 명확히해야합니다 (프로그램 적으로, 언어가 아닌 ...)

jar 파일을 복사하려고합니다. 복사 할 파일이 작업 디렉토리 외부로 복사됩니다. 몇 가지 테스트를 해봤는데 모든 메소드는 0 바이트 파일로 끝납니다.

편집 : 나는 수동으로 프로그램을 통해 할 파일의 복사 싶어요.


Java 8 (사실 FileSystem은 1.7 이후에 존재합니다)에는이를 처리 할 멋진 새로운 클래스 / 메소드가 있습니다. 누군가 JAR 파일이 기본적으로 ZIP 파일이라고 언급 했으므로

final URI jarFileUril = URI.create("jar:file:" + file.toURI().getPath());
final FileSystem fs = FileSystems.newFileSystem(jarFileUri, env);

( Zip 파일 참조)

다음과 같은 편리한 메소드 중 하나를 사용할 수 있습니다.

fs.getPath("filename");

그럼 Files 클래스를 사용할 수 있습니다.

try (final Stream<Path> sources = Files.walk(from)) {
     sources.forEach(src -> {
         final Path dest = to.resolve(from.relativize(src).toString());
         try {
            if (Files.isDirectory(from)) {
               if (Files.notExists(to)) {
                   log.trace("Creating directory {}", to);
                   Files.createDirectories(to);
               }
            } else {
                log.trace("Extracting file {} to {}", from, to);
                Files.copy(from, to, StandardCopyOption.REPLACE_EXISTING);
            }
       } catch (IOException e) {
           throw new RuntimeException("Failed to unzip file.", e);
       }
     });
}

참고 : 테스트를 위해 JAR 파일의 압축을 풀어 보았습니다.


무엇보다도 먼저 게시 된 답변은 전적으로 정확하다고 말하고 싶지만 GPL로 오픈 소스 라이브러리를 사용할 수 없기 때문에 또는 XD를 다운로드하기에는 너무 게으르거나 또는 이제까지 이유는 독립 실행 형 솔루션입니다.

아래 함수는 Jar 파일 옆에있는 리소스를 복사합니다.

  /**
     * Export a resource embedded into a Jar file to the local file path.
     *
     * @param resourceName ie.: "/SmartLibrary.dll"
     * @return The path to the exported resource
     * @throws Exception
     */
    static public String ExportResource(String resourceName) throws Exception {
        InputStream stream = null;
        OutputStream resStreamOut = null;
        String jarFolder;
        try {
            stream = ExecutingClass.class.getResourceAsStream(resourceName);//note that each / is a directory down in the "jar tree" been the jar the root of the tree
            if(stream == null) {
                throw new Exception("Cannot get resource \"" + resourceName + "\" from Jar file.");
            }

            int readBytes;
            byte[] buffer = new byte[4096];
            jarFolder = new File(ExecutingClass.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getParentFile().getPath().replace('\\', '/');
            resStreamOut = new FileOutputStream(jarFolder + resourceName);
            while ((readBytes = stream.read(buffer)) > 0) {
                resStreamOut.write(buffer, 0, readBytes);
            }
        } catch (Exception ex) {
            throw ex;
        } finally {
            stream.close();
            resStreamOut.close();
        }

        return jarFolder + resourceName;
    }

ExecutingClass를 클래스 이름으로 변경하고 다음과 같이 호출하십시오.

String fullPath = ExportResource("/myresource.ext");

Java 7+ 용 편집 (사용자의 편의를 위해)

GOXR3PLUS 가 대답하고 Andy Thomas가 지적한 GOXR3PLUS 과 같이 할 수 있습니다.

Files.copy( InputStream in, Path target, CopyOption... options)

자세한 내용은 GOXR3PLUS 응답 을 참조하십시오.


항아리는 단지 zip 파일 일뿐입니다. 압축을 풀고 (원하는 모든 방법을 사용하여) 파일을 정상적으로 복사하십시오.


Java 7 이상 에서 더 빨리 수행 할 수있는 방법과 현재 디렉토리를 가져 오는 코드 :

   /**
     * Copy a file from source to destination.
     *
     * @param source
     *        the source
     * @param destination
     *        the destination
     * @return True if succeeded , False if not
     */
    public static boolean copy(InputStream source , String destination) {
        boolean succeess = true;

        System.out.println("Copying ->" + source + "\n\tto ->" + destination);

        try {
            Files.copy(source, Paths.get(destination), StandardCopyOption.REPLACE_EXISTING);
        } catch (IOException ex) {
            logger.log(Level.WARNING, "", ex);
            succeess = false;
        }

        return succeess;

    }

테스트 ( icon.png 는 응용 프로그램 패키지 이미지 내의 이미지입니다) :

copy(getClass().getResourceAsStream("/image/icon.png"),getBasePathForClass(Main.class)+"icon.png");

코드 줄에 대해 ( getBasePathForClass(Main.class) ) : -> 여기에 추가 한 답변을 확인하십시오 :) -> Java에서 현재 작업 디렉토리 가져 오기


${JAVA_HOME}/bin/jar -cvf /path/to.jar




working-directory