我实现了以下过程,旨在写入一些文件并在写入完成后在每个文件的末尾打印一条消息:
# Print one file per piaf
output_dir_piafs <- "OUTPUT_dataset_piafs"
unlink(output_dir_piafs, recursive = TRUE, force = TRUE)
dir.create(output_dir_piafs)
for (i in 1:length(lst_sorted)) {
sink() # Generates warnings...
filename <- paste(output_dir_piafs, "/piaf_", i, ".txt", sep="")
sink(file = filename, append = TRUE)
sink(type = "message")
cat(" ", colnames(file1), "n")
for (j in 1:length(lst_sorted[[i]])) {
cat(j, " ")
lapply( lst_sorted[[i]][[j]],
function(x) {
cat(as.character(x), " ")
}
)
cat("n")
}
## back to the console
sink()
cat(paste(filename, "done !n"))
#flush(stdout()) # Tested, no particular effect
}
我的问题是,如果我不在循环的最开始时添加sink()
,则标准输出(cat(paste(filename, "done !n"))
)上的最终写入将不起作用。另一方面,添加此早期sink()
会产生我想避免的警告:
There were 50 or more warnings (use warnings() to see the first 50)
> warnings()
Warning messages:
1: In sink() : no sink to remove
2: In sink() : no sink to remove
3: In sink() : no sink to remove
有没有人知道sink()的行为方式,和/或如何摆脱这些警告?
注意:我也尝试了try(sink(), silent=TRUE)
,但silent
选项只能防止错误...
你不必用sink
,看看?cat
,可以直接写入文件。
以下代码应该有效:
output_dir_piafs <- "OUTPUT_dataset_piafs"
unlink(output_dir_piafs, recursive = TRUE, force = TRUE)
dir.create(output_dir_piafs)
lst_sorted <- c(1,2,3)
file1 <- c(a=1, b=2, c=3)
for (i in 1:length(lst_sorted)) {
filename <- paste(output_dir_piafs, "/piaf_", i, ".txt", sep="")
cat(" ", colnames(file1), "n", file=filename, append=T)
for (j in 1:length(lst_sorted[[i]])) {
cat(j, " ", file=filename, append=T)
lapply( lst_sorted[[i]][[j]],
function(x) {
cat(as.character(x), " ", file=filename, append=T)
}
)
cat("n", file=filename, append=T)
}
cat(paste(filename, "done !n"))
}
请注意,我将变量设置为 lst_sorted
和 file1
以使代码可重现。
cat
解决方案是否适合您?
我最终通过在捕获中断时添加一个sink(type="output")
来解决此问题 - Ctrl-C
- (这使得标准输出的后续使用是正确的 - 否则将保持锁定/转移):
tryCatch({
# Print one file per piaf
output_dir_piafs <- "OUTPUT_dataset_piafs"
unlink(output_dir_piafs, recursive = TRUE, force = TRUE)
dir.create(output_dir_piafs)
for (i in 1:length(lst_sorted)) {
filename <- paste(output_dir_piafs, "/piaf_", i, ".txt", sep="")
sink(file = filename, append = TRUE)
sink(type = "message")
cat(" ", colnames(file1), "n")
for (j in 1:length(lst_sorted[[i]])) {
cat(j, " ")
lapply( lst_sorted[[i]][[j]],
function(x) {
cat(as.character(x), " ")
}
)
cat("n")
}
## back to the console
sink(type="output")
cat(paste(filename, "done !n"))
}
}, interrupt = function(ex) {
##cat("An interrupt was detected.n")
sink(type="output") # Restore the standard output !
##print(ex)
}) # tryCatch()
另一种方法(基于 user1981275 和 Karl Forner 的帮助)是:
tryCatch({
# Print one file per piaf
output_dir_piafs <- "OUTPUT_dataset_piafs_2"
unlink(output_dir_piafs, recursive = TRUE, force = TRUE)
dir.create(output_dir_piafs)
for (i in 1:length(lst_sorted)) {
filename <- paste(output_dir_piafs, "/piaf_", i, ".txt", sep="")
f <- file(filename, 'w')
cat(" ", colnames(file1), "n", file=f)
for (j in 1:length(lst_sorted[[i]])) {
cat(j, " ", file=f)
lapply( lst_sorted[[i]][[j]],
function(x) {
cat(as.character(x), " ", file=f)
}
)
cat("n", file=f)
}
flush(f)
close(f)
## back to the console
cat(paste(filename, "done !n"))
}
}, interrupt = function(ex) {
closeAllConnections()
}) # tryCatch()
该解决方案具有很大的优势,即不会转移标准输出,这意味着即使没有捕获中断,标准输出仍保持活动状态。
请注意,键盘中断处理仍然是必要的,以避免出现以下警告:
> warnings()
Warning message:
closing unused connection 3 (OUTPUT_dataset_piafs_2/piaf_16.txt)
根据?closeAllConnections
:
"closeAllConnections"关闭(并销毁)所有用户连接, 恢复所有"水槽"改道。
最后注意:这两种方法之间的文件写入没有真正的速度差异。