Rのdevtools::check_win_devel
で発生したerror reading from connection
はmode="wb"
オプションで解決
CRANパッケージ作成に向けて、パッケージの事前テストをしたらWinsowsのテスト環境だけで発生するエラーにハマった話。
原因はダウンロードする際のファイル形式にあることがわかった。
事象
- ある開発中のRパッケージに対して、
devtools::check_win_devel()
を実行 - 実行結果を確認すると、unix系のテスト環境では発生しなかったエラーが発生していた
起きたエラー
Error in load("ファイルパス") : error reading from connection
Calls: "実行したコマンドが書かれている"
Execution halted
エラーを見て考えたこと
-
load()
だしファイルパスのミスでしょ -
tempdir()
(Rのセッションごとに一時的に作成されるディレクトリ)にdownload.file()
したファイルをload()
してるので、ファイルパスの問題ではないか - windowsテスト環境におけるRコマンドの実行なので、パスの表記の問題ではないか。スラッシュ、バックスラッシュが適切でないとか?
調査結果
-
load
関数でなく、その1ステップ前のdownload.file
関数に原因があった。 - このERRORに至るまでのステップを整理すると
download.file("https://以下略、に置いている.RDataファイルのURL", "ダウンロード先のファイルパス")
load("ダウンロード先のファイルパス")
# これ以降ERRORでストップ
- このERROR、修正対象は
download.file()
なのにERRORが生じるタイミングがload()
なのがいやらしかった - 調べていくと、Windows環境においては
download.file
関数にはmode="wb"
のオプションを付けて、バイナリファイルの転送に対応しないといけないらしい- (参考)R Documentation Download File from the Internet
- (引用)
Windowsでは、Unix系と異なり、テキストファイルとバイナリファイルを区別し、テキスト転送の場合は \n の行末を \rn (別名 'CRLF') に変更するので、バイナリ転送の選択 (mode = "wb" or "ab") は重要である。
- (引用)
- (参考)R Documentation Download File from the Internet
- 以下の人もWindows環境では
download.file(temp.doc.name, temp.destfile.name, mode = "wb")
にしろって言ってる
修正結果
- コードを下記の形式に書き換えて
if(.Platform$OS.type == "windows") {
# download for windows
download.file("https://においてるファイルのURL",
"ダウンロード先のファイルパス",
mode="wb")
} else {
# download for unix
download.file("https://においてるファイルのURL",,
"ダウンロード先のファイルパス")
}
load("ダウンロード先のファイルパス")
- 再度
devtools::check_win_devel
でテストするとエラーが発生しなくなった - ちなみにmode="w"がデフォルト値らしいので
else
ではmode="w"
の設定になっているはず。
メモ
download.file()
がWindows環境でうんともすんともいわなくなるなら、WindowsOSの場合はmode="wb"
をデフォルト値にするようにしてくれたらいいのではないかと思った。各自が上記のような修正を加えるのではなく、download.file
側で修正したほうが全体でみたときにかかるコストが少ないのではないだろうか。←自分のパッケージ設計に実は何か原因があるとかのオチだったらすみません。反省して窓拭き掃除してゴミ除きます。