问题描述
我正在尝试将命令的输出放到某些文件中.在写入文件之前,我要删除文件,然后执行写入操作.这是我的gradle脚本
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
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")
}
但是当我运行writefile任务时,出现错误
But when i run writefile tasks , I get below error
Execution failed for task ':deletefiles'.
> java.io.IOException: Unable to delete file 'D:\workspace\code\repo\sample-gradle-mono\somefile.txt'
你知道怎么了吗?
我想的一件事是gradle在 deletefiles 任务开始之前就以某种方式获得了文件锁定.如果是这样,我们如何实现呢?
One thing i guess is that gradle is somehow acquiring lock on file before deletefiles tasks could start. If that is the case, How can we achieve this?
环境信息-
------------------------------------------------------------
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
standardOutput = new FileOutputStream("$projectDir/somefile.txt")
这意味着即使没有启动任何gradle任务,流也已创建并锁定了文件.
it means that stream is created and file locked even before any gradle task was started..
尝试使用这种常规配置来查看问题:
try this groovy configuration to see the issue:
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'
要对其进行修复-在"Exec"命令之前定义standardOutput
任务已执行:
To fix it - define the standardOutput
just before the "Exec" task is executed:
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"
}
}
输出:
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
添加一些明晰性:
例如此任务定义
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"
}
}
您可以在gradle中替换为以下常规代码:
you could replace with the following groovy code in your gradle:
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/more_about_tasks.html
这篇关于Gradle无法将sysout写入文件-java.io.IOException:无法删除文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!