Java 如何在.JAR文件中执行此代码,而在IDE中则可以
当我在IDEIntelliJ中执行这段代码时,它工作得非常好。但是,当我最终在我的文件.JAR中执行此操作时,它不起作用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
@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
不能表示它们
--编辑--
问题更新后:
- 正如名字所说,
的要点是,这就是你的kotlin文件所在的地方。zip不是kotlin文件。把它们放在src/main/kotlin
中src/main/resources
- url.toString()?我不知道您要如何处理这些复杂问题。请先从一个硬编码字符串开始,而不是从这些复杂的字符串开始。一旦您了解了它是如何工作的,请随意抽象
.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
)
}
}