R:从 GitHub 读取 UCS-2 LE bom 文件

R: Reading a UCS-2 LE bom file from GitHub

我有一个程序可以在 GitHub 上自动创建和存储文件。一个例子是 https://raw.githubusercontent.com/VIC-Laboratory-ExperimentalData/test/master/test-999-666.txt

但是,这些文件是在 Dos/Windows 机器上用 UCS-2 LE BOM 编码的(根据记事本++)。

我正在尝试将此文本文件读入 R 但无济于事:

repo <- "https://raw.githubusercontent.com/VIC-Laboratory-ExperimentalData/test/master"
file <- "test-999-666.txt"
myurl  <- paste(repo, file, sep="/")
library(RCurl)
cnt <- getURL(myurl)

我收到一个错误

Error in curlPerform(curl = curl, .opts = opts, .encoding = .encoding) : 
 caractère nul au milieu de la chaîne : '<ff><fe>*'

如何配置 getURL 来读取此文件?我也试过 httr::GET (但收到的内容是空的)。

在处理由 Windows 生成的文件时,这似乎是一个相对常见的痛点。老实说,我提出的解决方案似乎不是最好的,因为它主要绕过了将所有内容都放入正确的编码中,而是直接转到二进制文件。

使用与您相同的变量:

cnt <- getURLContent(myurl, binary = T)
cnt <- rawToChar(cnt[cnt != 00])

应该生成可解析的字符串。

我们的想法是,与其尝试让 curl 读取文件,不如让它像对待二进制文件一样对待它,然后再处理编码。这给了我们一个 raw 类型的向量。然后,由于主要问题似乎是空字符(即 [=14=])导致了问题,我们只是将它们从 cnt 中排除,然后将 cntraw 强制转换为 char

最后,从你的例子中,我得到

"ÿþ*** Header Start ***\r\nVersionPersist: 1\r\nLevelName: Session\r\nLevelName: Block\r\nLevelName: Trial\r\nLevelName: SubTrial\r\nLevelName: LogLevel5\r\nLevelName: LogLevel6\r\nLevelName: LogLevel7\r\nLevelName: LogLevel8\r\nLevelName: LogLevel9\r\nLevelName: LogLevel10\r\nExperiment: test\r\nSessionDate: 07-04-2019\r\nSessionTime: 12:35:06\r\nSessionStartDateTimeUtc: 2019-07-04 16:35:06\r\nSubject: 999\r\nSession: 666\r\nDataFile.Basename: test-999-666\r\nRandomSeed: -1018314635\r\nGroup: 1\r\nDisplay.RefreshRate: 60.005\r\n*** Header End ***\r\nLevel: 1\r\n*** LogFrame Start ***\r\nExperiment: test\r\nSessionDate: 07-04-2019\r\nSessionTime: 12:35:06\r\nSessionStartDateTimeUtc: 2019-07-04 16:35:06\r\nSubject: 999\r\nSession: 666\r\nDataFile.Basename: test-999-666\r\nRandomSeed: -1018314635\r\nGroup: 1\r\nDisplay.RefreshRate: 60.005\r\nClock.Information: <?xml version=\"1.0\"?>\n<Clock xmlns:dt=\"urn:schemas-microsoft-com:datatypes\"><Description dt:dt=\"string\">E-Prime Primary Realtime Clock</Description><StartTime><Timestamp dt:dt=\"int\">0</Timestamp><DateUtc dt:dt=\"string\">2019-07-04T16:35:05Z</DateUtc></StartTime><FrequencyChanges><FrequencyChange><Frequency dt:dt=\"r8\">2742255</Frequency><Timestamp dt:dt=\"r8\">492902384024</Timestamp><Current dt:dt=\"r8\">0</Current><DateUtc dt:dt=\"string\">2019-07-04T16:35:05Z</DateUtc></FrequencyChange></FrequencyChanges></Clock>\n\r\nStudioVersion: 2.0.10.252\r\nRuntimeVersion: 2.0.10.356\r\nRuntimeVersionExpected: 2.0.10.356\r\nRuntimeCapabilities: Professional\r\nExperimentVersion: 1.0.0.543\r\nExperimentStuff.RT: 2555\r\n*** LogFrame End ***\r\n"

似乎包含所有正确的内容。

如果你愿意,可以尝试在这段代码之前添加 options(encoding = "UCS-2LE-BOM"),我不知道它是否改变了什么,但它似乎影响了 rawToChar