我正在尝试使用以下命令执行我的Kotlin类:
./gradlew -q run < src/main/kotlin/samples/input.txt
这是我的 HelloWorld.kt 类:
package samples
fun main(args: Array<String>) {
println("Hello, world!")
val lineRead = readLine()
println(lineRead)
}
这是我的 build.gradle.kts :
plugins {
kotlin("jvm")
application
}
application {
mainClassName = "samples.HelloWorldKt"
}
dependencies {
compile(kotlin("stdlib"))
}
repositories {
jcenter()
}
代码执行,但不显示input.txt文件中包含的数据。这是我得到的输出:
Hello, world!
null
我希望能够执行上面的gradlew命令,并将input.txt流重定向到stdio。我可以很容易地用C ++做到这一点。编译完.cpp文件后,我可以运行:
./my_code < input.txt
并按预期执行。
我如何用Kotlin和Gradle实现同样的目标?
更新:基于this answer,我尝试将其添加到build.gradle.kts,但它不是有效的语法:
答案 0 :(得分:6)
AjahnCharles关于run { standardInput = System.in }
的建议是正确的,但要将其移植到kotlin-dsl,您需要不同的语法。
在这种情况下,run
是任务名称,您配置application
插件的现有任务。
要在kotlin-dsl中配置现有任务,您应该使用以下方法之一:
val run by tasks.getting(JavaExec::class) {
standardInput = System.`in`
}
或
val run: JavaExec by tasks
run.standardInput = System.`in`
即将推出的Gradle 4.3版本应提供API for plugin writers来读取用户输入。
在这种情况下Groovy和Kotlin之间存在差异的原因是因为Groovy使用动态类型,但在Kotlin中,您必须指定任务类型以具有自动完成功能并且只需编译配置脚本
答案 1 :(得分:0)
我的理解:< input.txt
设置了gradlew进程的标准输入,但默认情况下不会将其转发到您的程序。
您想将此添加到build.gradle.kts:
run {
standardInput = System.`in`
}
<强>来源:强>
https://discuss.gradle.org/t/why-doesnt-system-in-read-block-when-im-using-gradle/3308/2
https://discuss.gradle.org/t/how-can-i-execute-a-java-application-that-asks-for-user-input/3264
这些构建配置看起来与我大致相同,但 Groovy工作,而Kotlin不。我开始认为Gradle Kotlin DSL还不支持standardInput
术语:/
如果有任何帮助,这是我正在使用的Groovy版本:
apply plugin: 'kotlin'
apply plugin: 'application'
buildscript {
ext.kotlin_version = '1.1.4'
repositories {
jcenter()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
repositories {
jcenter()
}
dependencies {
// api => exported to consumers (found on their compile classpath)
// implementation => used internally (not exposed to consumers)
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
mainClassName = "samples.HelloWorldKt"
run {
standardInput = System.in
}