解决R语言运行中临时文件目录的问题(tempdir、tempfile)——2024-09-05

先来说说为什么会涉及到这块,再分享一下这个心路历程啊,最后才是解决方法(赶时间就直奔第三部分吧)

一、为什么会涉及到这块?

在运行BSgenomeForge包中forgeBSgenomeDataPkgFromNCBI函数的时候,一直报错啊,如下:

cannot rename file '/tmp/Rtmprdm2xy/single_sequences.2bit' to './BSgenome.Vcholerae.NCBI.ASM836960v1/inst/extdata/single_sequences.2bit', reason 'Invalid cross-device link'

大概意思就是目录A有个文件a,现在要把它移到目录B,但是呢就是'Invalid cross-device link'。
可是在命令行试了试,这两个目录都有读写权限,这是为什么呢?
ok,下面就是心路历程了

二、debug心路历程

小心思又来了,机脑现在不用何时用?把上面这段报错输进去,问它是什么原因以及如何解决,AI是这么回答的:

在 R 语言中,file.rename() 函数可能会因为尝试在不同的文件系统或者分区上移动文件而报错 "Invalid cross-device link"。这是因为 rename 系统调用不允许跨文件系统移动文件。以下是一些可能的解决方案:

  1. 使用 file.copy()file.remove() 组合:可以先复制文件到目标位置,然后删除原始文件。这种方法可以避免跨文件系统移动文件的问题。例如:
  > if (file.exists(target_file)) {
  +    file.remove(target_file)
  +  }
  +  file.copy(source_file, target_file)
  +  file.remove(source_file)

这种方法在某些情况下被用作 file.rename() 的替代方案 。

  1. 检查文件系统:确保源文件和目标路径位于同一个文件系统上。如果它们位于不同的分区,你可能需要调整你的文件系统设置或选择不同的路径。

  2. 使用系统命令:在 R 脚本中使用系统命令 mv 来移动文件。例如:

    system(paste("mv", shQuote(source_file), shQuote(target_file)))
    

    这种方法可以利用系统级的文件移动命令,它通常会处理跨文件系统的情况。

  3. 避免在脚本中硬编码路径:如果可能,避免在脚本中硬编码文件路径,而是使用相对路径或让用户提供路径,这样可以减少跨文件系统操作的可能性。

  4. 检查 R 版本和操作系统:有时候,特定版本的 R 或操作系统可能会有已知的 bug 或限制。确保你的 R 是最新版本,并且查看相关的 R 社区或论坛是否有相关的讨论或修复。

  5. 使用其他 R 包:有些 R 包可能提供了更健壮的文件操作功能,可以处理跨文件系统的问题。例如,fs 包提供了跨平台的文件系统操作功能。

AI就是系统啊,一个一个来吧,简单看了一下前三个,1和3差不多,都需要去找到函数的源代码,去把rename改成copy或者mv,好,应该不太难,一行一行运行就行了呗,走起:

> pkg_maintainer="pglaser@pasteur.fr"
> pkg_author = NA
> check_pkg_maintainer(pkg_maintainer)
Error in check_pkg_maintainer(pkg_maintainer) : 
  could not find function "check_pkg_maintainer"

第一步就给我整懵了,这个check_pkg_maintainer函数不存在,它是个啥玩意儿呢,去安装包源代码里边找吧,好了,作者给封上了,啥也看不见,这咋整?
又回头看了看AI给的第2个方案,注意到“分区”两个字,难道不能rename是因为目录A和B在不同的分区?看了一下,果真是,那,解决分区问题就是了。

三、解决方法

  1. 要么在A下面运行这个函数,很好办,但需要注意A盘的内存啊,我们的/tmp内存很小,所以放弃这个方法
  2. 要么就把临时文件改到和B同区的路径,这碗饭合胃口,那就改临时文件路径吧,走起(在R环境运行啊朋友们)
#change the tempdir() location
> tempdir <- function() "/home/x/tmp/data"  # 这里引号里就写自己想要放临时文件的目录就好了
> unlockBinding("tempdir", baseenv())
> utils::assignInNamespace("tempdir", tempdir, ns="base", envir=baseenv())
> assign("tempdir", tempdir, baseenv())
> lockBinding("tempdir", baseenv())

一行一行跟着来就对了,最后再检查一下:

> tempdir ()
[1] "/home/x/tmp/data"
> tempfile()
[1] "/home/x/tmp/data/file4a111ff7ff02"
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容