简体   繁体   English

Gradle 无法将 sysout 写入文件 - java.io.IOException:无法删除文件

[英]Gradle unable to write sysout to file - java.io.IOException: Unable to delete file

I am trying to put output of a command to some file.我正在尝试将命令的输出放入某个文件。 Before writing the file i want to delete the file and than do write operation.在写入文件之前,我想删除文件而不是进行写入操作。 Here is my gradle script这是我的gradle脚本


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

task deletefiles(type: Delete){
    delete "$projectDir/somefile.txt"
}

task writefile(type: Exec, dependsOn: deletefiles){
    commandLine 'echo', "Hello World"
    standardOutput = new FileOutputStream("$projectDir/somefile.txt")
}

But when i run writefile tasks , I get below error但是当我运行 writefile 任务时,出现以下错误

Execution failed for task ':deletefiles'.
> java.io.IOException: Unable to delete file 'D:\workspace\code\repo\sample-gradle-mono\somefile.txt'

Any idea what's wrong?知道出了什么问题吗?

One thing i guess is that gradle is somehow acquiring lock on file before deletefiles tasks could start.我猜的一件事是 gradle 在deletefiles任务可以开始之前以某种方式获取文件锁定。 If that is the case, How can we achieve this?如果是这样,我们如何才能实现这一目标?

Edit 1: Enviroment info -编辑 1:环境信息 -

------------------------------------------------------------
Gradle 6.3
------------------------------------------------------------

Build time:   2020-03-24 19:52:07 UTC
Revision:     bacd40b727b0130eeac8855ae3f9fd9a0b207c60

Kotlin:       1.3.70
Groovy:       2.5.10
Ant:          Apache Ant(TM) version 1.10.7 compiled on September 1 2019
JVM:          11.0.4 (Oracle Corporation 11.0.4+11)
OS:           Windows 10 10.0 amd64

the problem that in your gradle the following line executed at project configuration phase在项目配置阶段在您的 gradle 中执行以下行的问题

standardOutput = new FileOutputStream("$projectDir/somefile.txt")

it means that stream is created and file locked even before any gradle task was started..这意味着即使在启动任何 gradle 任务之前,流已被创建并被锁定。

try this groovy configuration to see the issue:尝试这个 groovy 配置以查看问题:


class MyStream extends FileOutputStream{
    MyStream(String f){ 
        super(f)
        println "write $f stream created" 
    }
}

task deletefiles(type: Delete){
    println "delete init"
    doFirst{
        println "delete doFirst" //triggered just before deletion
    }
    delete "out.txt"
}

task writefile(type: Exec, dependsOn: deletefiles){
    println "write init"
    commandLine 'cmd', '/C', 'echo', "Hello World"
    standardOutput = new MyStream("out.txt")
}

in output you can see that stream is created before tasks execution:在输出中,您可以看到在任务执行之前创建了流:

cmd> gradle writeFile

> Configure project :
delete init
write init
write out.txt stream created

> Task :deletefiles FAILED
delete doFirst

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':deletefiles'.
> java.io.IOException: Unable to delete file 'out.txt'

To fix it - define the standardOutput just before the "Exec" task is executed:要修复它- 在执行“Exec”任务之前定义standardOutput

class MyStream extends FileOutputStream{
    MyStream(String f){ 
        super(f)
        println "write $f stream created" 
    }
}

task deletefiles(type: Delete){
    println "delete init"
    doFirst{
        println "delete doFirst"
    }
    delete "out.txt"
}

task writefile(type: Exec, dependsOn: deletefiles){
    println "write init"
    commandLine 'cmd', '/C', 'echo', "Hello World"
    doFirst{
        println "write doFirst"
        standardOutput = new MyStream("out.txt")
    }
    doLast{
        println "write doLast"
    }
}

output:输出:

cmd>gradle writeFile

> Configure project :
delete init
write init

> Task :deletefiles
delete doFirst

> Task :writefile
write doFirst
write out.txt stream created
write doLast

BUILD SUCCESSFUL in 3s
2 actionable tasks: 2 executed

to add some clarity :增加一些清晰度

for example the this task definition例如这个任务定义

task writefile(type: Exec, dependsOn: deletefiles){
    println "write init"
    commandLine 'cmd', '/C', 'echo', "Hello World"
    doFirst{
        println "write doFirst"
        standardOutput = new MyStream("out.txt")
    }
    doLast{
        println "write doLast"
    }
}

you could replace with the following groovy code in your gradle:您可以在您的 gradle 中替换为以下 groovy 代码:

def writefile = project.task( [type: Exec, dependsOn: deletefiles], 'writeFile' )

println "write init"
writefile.setCommandLine( ['cmd', '/C', 'echo', "Hello World"] )

writefile.getActions().add( 0, {
    //those commands will be executed later when task `writefile` decided to be executed by gradle
    println "write doFirst"
    writefile.standardOutput = new FileOutputStream("out.txt")
} as Action)

writefile.getActions().add( {
    //those commands will be executed later when task `writefile` decided to be executed by gradle
    println "write doLast" 
} as Action)


links to official documentation that could explain this behavior:可以解释这种行为的官方文档链接:

https://docs.gradle.org/current/userguide/build_lifecycle.html#sec:settings_file https://docs.gradle.org/current/userguide/build_lifecycle.html#sec:settings_file

https://docs.gradle.org/current/userguide/more_about_tasks.html https://docs.gradle.org/current/userguide/more_about_tasks.html

It is possible that something is holding the file open.可能是某些东西使文件保持打开状态。 Sometimes if IO streams are not properly closed this can happen.有时,如果 IO 流没有正确关闭,就会发生这种情况。 Gradle docs say that exec task closes the output stream after the process terminates, so that shouldn't be the problem. Gradle 文档说 exec 任务在进程终止后关闭输出流,所以这应该不是问题。 It could be a known issue with deleting on Windows.在 Windows 上删除可能是一个已知问题。 Eg: https://carlrice.io/blog/gradle-clean-cant-delete-file-on-windows例如: https : //carlrice.io/blog/gradle-clean-cant-delete-file-on-windows

https://github.com/gradle/gradle/issues/9813 (but that one is about folders) https://github.com/gradle/gradle/issues/9813 (但那个是关于文件夹的)

https://www.eknori.de/2020-09-18/gradle-execution-failed-for-task-appclean-unable-to-delete-file/ https://www.eknori.de/2020-09-18/gradle-execution-failed-for-task-appclean-unable-to-delete-file/

I would run the build with --debug to capture more details of the exception.我将使用 --debug 运行构建以捕获异常的更多详细信息。

Are you running with the Gradle daemon?你在运行 Gradle 守护进程吗? Try without it.没有它试试。 Since it is a persistent process, maybe for some reason it has a file handle open to that file.由于它是一个持久进程,可能出于某种原因它有一个打开该文件的文件句柄。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 多项目gradle构建-java.io.IOException:无法删除文件 - Multi project gradle build - java.io.IOException: Unable to delete file java.io.IOException:无法删除原始文件moveFileToDirectory - java.io.IOException: Failed to delete original file moveFileToDirectory 无法启动测试系统'slim':java.io.IOException:无法运行程序“ java”:error = 2,没有这样的文件或目录 - Unable to start test system 'slim': java.io.IOException: Cannot run program “java”: error=2, No such file or directory 无法创建文件日志/connectivityserver.log java.io.IOException:无法创建目录/日志 - Unable to create file logs/connectivityserver.log java.io.IOException: Could not create directory /logs 引起:java.io.IOException:无法锁定使用情况跟踪假脱机文件 - Caused by: java.io.IOException: Unable to lock usage tracking spool file “ java.io.IOException:这可能不是PDF文件” - “java.io.IOException: This may not be a PDF File” Avro - java.io.IOException:不是数据文件 - Avro - java.io.IOException: Not a data file java.io.IOException: error=2, 没有那个文件或目录 - java.io.IOException: error=2, No such file or directory java.io.IOException: 没有那个文件或目录 - java.io.IOException: No such file or directory java.io.IOException:找不到文件 - java.io.IOException: File Not Found
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM