【问题标题】:Read in non ascii file path on Windows在 Windows 上读取非 ascii 文件路径
【发布时间】:2018-07-13 15:04:52
【问题描述】:

我有一堆文件名包含非 ASCII 字符的文本文件。例如这是一个标题:

readLines('bbb/ović, Melika_ Omeragić, Ismir_ Bata.txt')

## Error in file(con, "r") : cannot open the connection
## In addition: Warning message:
## In file(con, "r") :
##   cannot open file 'bbb/ovi?, Melika_ Omeragi?, Ismir_ Bata.txt': Invalid argument

我试试:

dir('bbb')
## [1] "ovic, Melika_ Omeragic, Ismir_ Bata.txt"

所以我尝试了:

readLines(list.files('bbb', full.names = TRUE))

## Error in file(con, "r") : cannot open the connection
## In addition: Warning message:
## In file(con, "r") :
##   cannot open file 'bbb/ovic, Melika_ Omeragic, Ismir_ Bata.txt': No such file or directory

如何以编程方式读取这些文件?文件的内容与这个问题无关,只是文件名中的特殊字符和读取的文件。

如果需要,如果有办法更改文件名以便读取它们,我也愿意。

我意识到我没有 MWE,但无法为这个问题创建一个。只需生成一个文本文件并将其命名为:ović, Melika_ Omeragić, Ismir_ Bata.txt 并使用我上面的代码读取它即可说明问题。

【问题讨论】:

  • 您可以使用system() 命令将文件重命名为有效名称吗?
  • 什么操作系统?它适用于我在 Mac 上。
  • @alistaire Windows
  • 嗯...我在看fs,他的path_sanitize 可能有用,发现this description of restrictions。我不认为这是一个答案,但至少它可能指向一个有用的方向。

标签: r


【解决方案1】:

您可以使用一行代码将所有文件从非 ascii 重命名为更简单的名称:

file.rename(Sys.glob("*"),list.files())

确实,Sys.glob 函数与list.files 类似,但支持更好的非 ascii 字符。

如果您想在多个子文件夹中递归重命名,我建议使用 fs 包(函数 file_movedir_ls)。如需更多信息,请查看我的其他答案:Reading accented filenames in R using list.files

然后readLines 应该可以正常工作,但没有特殊字符:-)

【讨论】:

  • 破坏你的文件系统似乎不是一个很好的解决方案
  • @HongOoi 是的,我可以理解,这取决于您的最终目标。对于我的项目,我必须重命名所有文件,并且在问题 OP 中说“如果需要,是否有办法更改文件名以便在其中读取它们,我也对此持开放态度。”,这就是为什么我建议这个。
【解决方案2】:

Windows 中的事情非常棘手,但我能够使用以下帖子找到解决方法:

equivalent of (dir/b > files.txt) in PowerShell

R: can't read unicode text files even when specifying the encoding

我用来读取文件的想法是将其名称写入文件中,然后使用适当的编码从那里读取它。

我的解决方案如下(我使用here 库仅出于可重复性的原因):

libarary(here)

obtain.files <- function(folder){
  # Obtain all files in folder and write output into file
  system(paste0("cmd /K ",'cd /d "',folder,'/" &  cmd /u /c "dir /b > filestmp.txt"'))
  tmpfilepath <- paste0(folder,"/filestmp.txt")
  # Read temporal file 
  # Not sure it will work in all windows versions
  RL<-readLines(con <- file(tmpfilepath,encoding="UCS-2LE"))

  # Remove file
  file.remove(tmpfilepath)
  # Keep only valid files
  RL <- RL[RL!="filestmp.txt"]
  return(RL)
}

folder <- here::here("bbb")
# There is only one file in the folder
files <- obtain.files(folder)

readLines(here::here("bbb",files))

我使用了第一篇文章中的cmd 命令,输出在UCS-2LE 中。它可能不是独立于平台的。对于powershellfiletmp.txtUTF-16 中,可能是一个更普遍的例子。

【讨论】:

    【解决方案3】:

    我可以使用readrread_lines_raw 读取名称为ović、Melika_ Omeragić、Ismir_ Bata.txt 的文件。字节序列甚至似乎和里面的文字相匹配,这是一件好事。

    #file on my desktop
    path <- '~/Desktop/ović, Melika_ Omeragić, Ismir_ Bata.txt'
    ##Assumming the file contains the word 'foobar'
    x <- charToRaw('foobar')
    
    
    #Using readr
    n <- readr::read_lines_raw(path)
    print(n)
    [[1]]
    [1] 66 6f 6f 62 61 72
    
    print(x)
    [1] 66 6f 6f 62 61 72
    

    希望这会有所帮助。

    【讨论】:

    • 看来这个问题是Windows问题...你用的是Linux、Mac还是Windows?
    • 我在 Mac OS X 上。也许尝试使用 docker 容器?
    猜你喜欢
    • 2020-10-03
    • 1970-01-01
    • 1970-01-01
    • 2015-05-07
    • 2016-07-09
    • 1970-01-01
    • 1970-01-01
    • 2020-06-06
    • 1970-01-01
    相关资源
    最近更新 更多