Java 如何在.JAR文件中执行此代码,而在IDE中则可以

Java 如何在.JAR文件中执行此代码,而在IDE中则可以,java,kotlin,intellij-idea,windows-10,javafx-8,Java,Kotlin,Intellij Idea,Windows 10,Javafx 8,当我在IDEIntelliJ中执行这段代码时,它工作得非常好。但是,当我最终在我的文件.JAR中执行此操作时,它不起作用 @Throws(IOException::class) fun extractZipMachineFromJar(file: String?, destination: String?) { var `in`: ZipInputStream? = null var out: OutputStream? = null try { // Open the

当我在IDEIntelliJ中执行这段代码时,它工作得非常好。但是,当我最终在我的文件.JAR中执行此操作时,它不起作用

@Throws(IOException::class)
fun extractZipMachineFromJar(file: String?, destination: String?) {
    var `in`: ZipInputStream? = null
    var out: OutputStream? = null
    try { // Open the ZIP file
        `in` = ZipInputStream((URL(file)).openStream())
        // Get the first entry
        var entry: ZipEntry? = null
        while (`in`.nextEntry.also { entry = it } != null) {
            val outFilename = entry!!.name
            // Open the output file
            if (entry!!.isDirectory) {
                File(destination, outFilename).mkdirs()
            } else {
                out = FileOutputStream(File(destination, outFilename))
                // Transfer bytes from the ZIP file to the output file
                val buf = ByteArray(1024)
                var len: Int
                while (`in`.read(buf).also { len = it } > 0) {
                    out.write(buf, 0, len)
                }
                out.close()
            }
        }
    } finally { // Close the stream
        `in`?.close()
        if (out != null) {
            out.close()
        }
    }
}
在我点击的按钮中

val file = File(System.getProperty("user.dir") + "\\src\\main\\kotlin\\extractFolder\\myFiles.zip").path.toString()
extractZipMachineFromJar(file, folderWhereIExtractTo)
我怀疑这就是我如何访问.Jar文件中的资源的方法。但我不知道,因为当我从IDE执行它时,它会工作

有人知道这个代码示例在.JAR文件中是如何工作的吗

我正在使用IntelliJ IDEA 2019.3.5社区版, Kotlin 1.3.70, Java 1.8.0_271, Java Fx 8.0.241, 第1.7.20节, 视窗1019041.746

谢谢

更新:

我尝试了这个解决方案,但我认为我应用正确的代码是错误的

原因:java.lang.IllegalStateException:MainView::class.java.get…/myFiles.zip”)不能为null

这是我修改过的代码和我的项目、文件夹和文件的截图

这是我的MainApp.kt

fun main() {
    launch<MainApp>()
}

class MainApp : App(MainView::class) { // me inyecta una clase

    override fun start(stage: Stage) {
        stage.minHeight = pantallaProgramaAlto
        stage.minWidth = pantallaProgramaAncho
        stage.resizableProperty().set(true)
        super.start(stage)
}

是的,
current working dir/src/main/kotlin/blabla
显然不保证存在。current working dir不保证有任何用处,此代码已被破坏

应该使用
MyClass.class.getResource(“relative path.txt”)加载应用程序中与编译类文件一样多的资源
。这将从JVM加载类文件的同一位置加载文件。具体而言,该指令将查看JVM找到的“目录”
MyClass.class
(带有表示MyClass类的字节码的类文件,可以在磁盘上,也可以在jar文件中,也可以在jmod中,或者在数据库中,或者是动态生成的-类加载系统非常抽象!)-并在那里查找文件
relative path.txt
。即使它在该数据库中,也在jar文件、jmod文件等中

以斜杠开始您的“相对路径”,它看起来与类路径根相对(因此,如果您有一个包含
/com/foo/yourapp/Main.class
/img/open.png
,则
Main.class.getResource(“/img/open.png”)
的JAR文件

.getResource
为您提供了一个URL对象,可以将其传递给swing JLabels等。
.getResourceAsStream
为您提供了一个inputstream(请确保在try with resources构造中调用它!)

File
是非初学者。File只能表示实际文件(因此得名),java应用程序通常不是作为“一堆文件”发布的。它们是作为“一个jar文件或一堆jar文件”发布的。其中的内容是jar文件中的条目,而不是文件。
java.io.File
不能表示它们

--编辑--

问题更新后:

  • 正如名字所说,
    src/main/kotlin
    的要点是,这就是你的kotlin文件所在的地方。zip不是kotlin文件。把它们放在
    src/main/resources

  • url.toString()?我不知道您要如何处理这些复杂问题。请先从一个硬编码字符串开始,而不是从这些复杂的字符串开始。一旦您了解了它是如何工作的,请随意抽象


我尝试了您的解决方案,但我认为我应用正确的代码是错误的。原因是:java.lang.IllegalStateException:MainView::class.java.get…/myFiles.zip”)不能为null这是我修改过的代码以及我的项目、文件夹和文件的屏幕截图。然后你要么搞乱了字符串参数(
.getResourceAsStream
如果您指定了一个不存在的资源,则返回
null
,这会导致您看到的错误),或者您的生成已中断,并且没有将资源复制到正确的位置。您没有提供足够的详细信息,说明您现在将代码更改为什么,或者您的生成如何工作(你是如何获得那个jar文件的?)来详细说明问题所在。我已经用更多信息更新了我的问题。现在你也可以看到我的项目文件夹和build.gradle。无论你需要什么,请告诉我。谢谢。
val url : URL = MainView::class.java.getResource("/folderWithZip/myFiles.zip")
extractZipMachineFromJar(url, rutaCarpetasDLLMasBinDentro)
fun main() {
    launch<MainApp>()
}

class MainApp : App(MainView::class) { // me inyecta una clase

    override fun start(stage: Stage) {
        stage.minHeight = pantallaProgramaAlto
        stage.minWidth = pantallaProgramaAncho
        stage.resizableProperty().set(true)
        super.start(stage)
}
class MainView : View(versionBarra) {
    override val root = tabpane() {
        tab<TabView>()
    }
}
plugins {
    id 'org.jetbrains.kotlin.jvm' version '1.3.70'
    id 'com.github.johnrengelman.shadow' version '5.2.0'
    id 'java'
}

group 'org.example'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
    implementation "no.tornado:tornadofx:1.7.20"
    implementation "com.squareup.okhttp3:mockwebserver:4.4.0"
}

compileKotlin {
    kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
    kotlinOptions.jvmTarget = "1.8"
}

//Definir clase principal para jar.
def mainClassName = 'playlistoPaquetorro.MainAppKt'

jar {
    manifest {
        attributes(
                'Main-Class': mainClassName
        )
    }
}