Kotlin和Gradle - 从stdio读书

Tia*_*ago 5 gradle kotlin gradle-kotlin-dsl

我正在尝试使用以下命令执行我的Kotlin类:

./gradlew -q run < src/main/kotlin/samples/input.txt
Run Code Online (Sandbox Code Playgroud)

这是我的HelloWorld.kt类:

package samples

fun main(args: Array<String>) {

    println("Hello, world!")

    val lineRead = readLine()
    println(lineRead)
}
Run Code Online (Sandbox Code Playgroud)

这是我的build.gradle.kts:

plugins {
    kotlin("jvm")
    application
}

application {
    mainClassName = "samples.HelloWorldKt"
}

dependencies {
    compile(kotlin("stdlib"))
}

repositories {
    jcenter()
}
Run Code Online (Sandbox Code Playgroud)

代码执行,但不显示input.txt文件中包含的数据.这是我得到的输出:

Hello, world!
null
Run Code Online (Sandbox Code Playgroud)

我希望能够执行上面的gradlew命令,并将input.txt流重定向到stdio.我可以很容易地用C++做到这一点.编译完.cpp文件后,我可以运行:

./my_code < input.txt
Run Code Online (Sandbox Code Playgroud)

并按预期执行.

如何用Kotlin和Gradle实现同样的目标?

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

在此输入图像描述

gil*_*dor 8

AjahnCharles的建议run { standardInput = System.in }是正确的,但是要将它移植到kotlin-dsl,你需要一个不同的语法. run在这种情况下是任务名称,您配置application插件的现有任务.要在kotlin-dsl中配置现有任务,您应该使用以下方法之一:

val run by tasks.getting(JavaExec::class) {
    standardInput = System.`in`
}
Run Code Online (Sandbox Code Playgroud)

要么

val run: JavaExec by tasks
run.standardInput = System.`in`
Run Code Online (Sandbox Code Playgroud)

即将推出的Gradle 4.3版本应为插件编写者提供读取用户输入的API.

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


Aja*_*les 0

差不多了,但这行不通:'(

理论上

我的理解:< input.txt为 gradlew 进程设置标准输入,但默认情况下这不会转发到您的程序。

您想将其添加到您的 build.gradle.kts 中:

run {
    standardInput = System.`in`
}
Run Code Online (Sandbox Code Playgroud)

来源:
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
}
Run Code Online (Sandbox Code Playgroud)

  • @eskatos 的建议对我来说很有效,只需进行一个小的调整: ```tasks.withType&lt;JavaExec&gt;() { standardInput = System.`in` }``` (2认同)