9

我正在尝试使用以下命令执行我的 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 实现相同的目标?

更新:基于此答案,我尝试将其添加到 build.gradle.kts 但它不是有效的语法:

在此处输入图像描述

4

3 回答 3

20

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以读取用户输入。

在这种情况下,Groovy 和 Kotlin 之间存在差异的原因是因为 Groovy 使用动态类型,但在 Kotlin 中,您必须指定任务类型才能具有自动完成功能,并且仅用于编译配置脚本

于 2017-10-10T08:56:55.333 回答
0

我终于解决了这个问题(Gradle 7.1.1):

plugins {
    application
}

tasks.getByName("run", JavaExec::class) {
    standardInput = System.`in`
}

我对 Kotlin 的了解还不够,无法判断这是否等同于https://stackoverflow.com/a/46662535/253921

于 2021-08-15T00:22:23.400 回答
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术语:/

Kotlin 中的 Gradle 与 Groovy 中的 Gradle

如果有任何帮助,这是我的工作 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
}
于 2017-08-18T03:14:02.203 回答