web-dev-qa-db-ja.com

Rを使用して「smb://」で始まるリモートファイルを読み取る

Rのファイルを読み取るには、通常、次のようなことをします。

read.csv('/Users/myusername/myfilename.csv')

しかし、MacでFinderGo→-を介してアクセスするリモートサーバー(Windows SMB/CIFS共有)にあるファイルを読み取ろうとしています。 サーバーに接続メニュー項目。

that fileのプロパティを表示すると、ファイルパスは以前とは異なります。で始まる代わりに:/Users/myusername/...、それはsmb://server.msu.edu/.../myfilename.csv

ファイルを読み取ろうとして、次のことを試しました。

read.csv('smb://server.msu.edu/.../myfilename.csv')

しかし、これはうまくいきませんでした。

通常の"No such file or directory"エラーの代わりに、これは以下を返しました:

smb://server.msu.edu/.../myfilename.csvは現在の作業ディレクトリに存在しません

ファイルパスには別の形式が必要だと思いますが、何がわかるかわかりません。

Rでこのタイプのファイルを読み取るにはどうすればよいですか?

20

説明

_smb://educ-srvmedia1.campusad.msu.edu/..._は、実際にはファイルパスではなくURLです。

これを分解しましょう

_smb://_は、 サーバーメッセージブロックプロトコル (ファイル共有)を使用することを意味します

_educ-srvmedia1.campusad.msu.edu_はサーバーの名前です

_/.../myfilename.csv_は、リモートサーバー上のファイル共有/パスです。

SMBプロトコル。FinderはURLを使用してリモートサービスに接続し、ファイルを参照できるようにします。OSXのFinderを使用してこのディレクトリに移動できます。

ただし、RはSMBプロトコルを理解していないため、ファイルパスを正しく解釈できません。

R関数read.csv()は内部でfile()を使用します。 https://stat.ethz.ch/R-manual/R-devel/library/を参照してくださいbase/html/connections.html

urlおよびfileサポートURLスキームfile://、http://、https://、ftp://

プロトコルがサポートされていないためファイルが見つからないため、Rは「ファイルを見つけることができません」というメッセージを返します。はい、少しわかりにくいです。

修正する

ローカルファイルシステムにファイル共有をマウントする必要があります。

つまり、SMBプロトコルの詳細は、OSによってバックグラウンドで処理され、ファイル共有はローカルディレクトリとして表示されます。

これにより、R(および他のプログラム)は、他のローカルファイルと同様に、すべての意図と目的のためにリモートファイルを処理できます。 この説明 は、そうするためのいくつかのオプションを示しています。

例えば.

_# need to create /LocalFolder first
mount -t cifs //username:password@hostname/sharename /LocalFolder
_

その後、R:

_read.csv('/LocalFolder/myfilename.csv')
_

追加

Windowsユーザーは、UNCパスを使用してこれを簡単に実現できます。
RのUNC指定ディレクトリからファイルを読み取る方法

18
stacksonstacks

TL; DR

CURLを使用し、リモートファイルシステムのマウントを必要としない移植可能なアプローチを次に示します。

> install.packages("curl")
> require("curl")
> handle <- new_handle()
> handle_setopt(handle, username = "domain\\username")
> handle_setopt(handle, password = "secret") # If needed
> request <- curl_fetch_memory("smb://Host.example.com/share/file.txt", handle = handle)
> contents <- rawToChar(request$content)

質問のように、コンテンツをCSVとして読み取る必要がある場合は、別の関数を使用してファイルをストリーミングできます。

> stream <- curl("smb://Host.example.com/share/file.txt", handle = handle)
> contents <- read.csv(stream)

リモートファイルシステムをマウントする他の回答で説明されているアプローチに加えて、smb:// URLを介してリモートファイルにアクセスするより堅牢な方法を見てみましょう。残念ながら、私はこれに少し遅れていますが、これが将来の読者に役立つことを願っています。

場合によっては、ファイルシステムをマウントするのに必要な権限がない場合があります(これには多くのシステムで管理者またはルートアクセスが必要です)、または単にwantファイル。代わりに cURLライブラリ を使用してファイルを読み取ります。この方法は、外部にマウントされたファイルシステムの存在に依存する必要がないため、プログラムの柔軟性と移植性を向上させます。 system()呼び出しを使用する方法と、cURL APIを提供するパッケージを使用する方法の2つの方法を検討します。

ある程度の背景:cURLには、さまざまなプロトコルでデータを転送するためのツールが用意されています。 version 7.40以降、cURLはWindowsファイル共有サービスで通常使用されるSMB/CIFSプロトコルをサポートします。 cURLには コマンドラインツール が含まれており、これを使用してファイルの内容を取得できます。

$ curl -u 'domain\username' 'smb://Host.example.com/share/file.txt'

上記のコマンドは、次の内容を読み取り(STDOUTに)出力します。 file.txt リモートサーバーから Host.example.com ドメイン上の指定されたユーザーとして認証する。このコマンドは、必要に応じてパスワードを要求します。ネットワークがドメインを使用しない場合、ユーザー名からドメイン部分を削除できます。

システムコール

system()関数 を使用して、Rで同じ機能を実現できます。

system("curl -u 'domain\\username' 'smb://Host.example.com/share/file.txt'")

domain\\usernameの二重バックスラッシュに注意してください。これにより、バックスラッシュ文字がエスケープされるため、Rは文字列内のエスケープ文字として解釈しません。 system()関数のinternパラメーターをTRUEに設定することにより、コマンド出力からファイルの内容を変数にキャプチャできます。

contents <- system("curl -u 'domain\\username' 'smb://Host.example.com/share/file.txt'", intern = TRUE)

...または代わりに system2() を呼び出すことにより、安全のためにコマンド引数を引用し、プラットフォーム間のプロセスのリダイレクトをより適切に処理します。

contents <- system2('curl', c("-u", "domain\\\\username", "smb://Host.example.com/share/file.txt"), stdout = TRUE)

の curl コマンドは、リモートサーバーで必要な場合、パスワードの入力を求めます。 canプロンプトを回避するために-u 'domain\\username:password'を使用してパスワードを指定しますが、そうするとコマンド文字列にプレーンテキストのパスワードが表示されます。より安全なアプローチについては、パッケージの使用法を説明する以下のセクションをお読みください。

-sまたは--silentフラグを追加することもできます curl 進行状況の出力を抑制するコマンド。これを行うとエラーメッセージも非表示になるため、-S--show-error)を追加することもできます。 contents変数には、readLines("file.txt")によって返される値と同様に、ファイルの行のベクトルが含まれます。これは、paste(contents, collapse = "\n")を使用して一緒に押し戻すことができます。

cURL API

これはすべて正常に機能しますが、専用のcURLライブラリを使用することでこのアプローチを改善できます。これは curlパッケージ がRバインディングを libcurl に提供するため、プログラムでcURL APIを直接使用できます。まず、パッケージをインストールする必要があります。

install.packages("curl")
require("curl")

(Linuxユーザーは libcurl開発ファイルをインストール する必要があります。)

次に、curl_fetch_memory()関数を使用して、リモートファイルを変数に読み込むことができます。

handle <- new_handle()
handle_setopt(handle, username = "domain\\username")
handle_setopt(handle, password = "secret") # If needed
request <- curl_fetch_memory("smb://Host.example.com/share/file.txt", handle = handle)
content <- rawToChar(request$content)

まず、必要な認証オプションを設定して、リクエストを設定するためのhandleを作成します。次に、リクエストを実行し、ファイルの内容を変数に割り当てます。示されているように、必要に応じてpassword CURLOPTを設定します。

read.csv()のようにリモートファイルを処理するには、ストリーミング接続を作成する必要があります。 curl()関数は、標準のurl()関数によって返される引数をサポートする任意の関数を介してファイルコンテンツをストリーミングするために使用できる接続オブジェクトを作成します。たとえば、質問のように、リモートファイルをCSVとして読み取る方法は次のとおりです。

handle = new_handle()
...
stream <- curl("smb://Host.example.com/share/file.txt", handle = handle)
contents <- read.csv(stream)

もちろん、上記の概念は、SMB/CIFSだけでなく、cURLによってサポートされるany protocolを介してコンテンツまたは応答本文を取得することに適用されます。必要に応じて、これらのツールを使用して、コンテンツをメモリに読み込むだけでなく、ファイルシステムにファイルをダウンロードすることもできます。

10
Cy Rossignol

以下では、SMBネットワークドライブからデータを読み取るために時々使用する方法を示しました。以下のコードでは、R system関数を使用してすべてを実行しましたR内から、ただしOSXコマンドラインから、またはFinder内からCommand-K(サーバーに接続)でドライブをマウントすることもできます。

まだ持っていない場合は、共有を配置するローカルドライブにディレクトリを作成します(ドライブは既存の場所にマウントできるため、必要ありません)。

_system("mkdir /Users/eipi10/temp_share/")
_

または

_dir.create("/Users/eipi10/temp_share/")
_

作成したフォルダーにネットワークドライブをマウントします。以下のコードでは、_//[email protected]/home/u/eipi10_はユーザー名とSMB=共有)のアドレスです。

_system("mount_smbfs //[email protected]/home/u/eipi10 /Users/eipi10/temp_share")
_

パスワード認証がある場合、パスワードも含めることができます。

_system("mount_smbfs //username:[email protected]/home/u/eipi10 /Users/eipi10/temp_share")
_

データを読む:

_dat = read.csv("/Users/eipi10/temp_share/fileToRead.csv")
_

R内から、読み取るファイルをプログラムで選択することもできます。

_data.list = lapply(list.files(pattern="csv$", "/Users/eipi10/temp_share/", full.names=TRUE), read.csv)
_
5
eipi10

SMBは、Windowsネットワークフォルダープロトコルです。

同様のケースにはsftp:// URLなど。

次のいずれかを実行できます。

  1. オペレーティングシステムでフォルダをマウントし、通常のパスを使用してアクセスします。
  2. linuxのGVFS/GIOなどの仮想ファイルシステムライブラリを使用します。たぶん、あなたが使用できるこれの周りのいくつかのRラッパーが存在します。
1
Anony-Mousse

私の意見では、あなたの目標を達成する2つの方法があります。

  • 最初の方法は、fstabを使用してリモートフォルダを確実に追加をローカルディスクとして使用することです。

  • 2番目の方法は、リモートフォルダーを一時的にマウントする必要なときにフォルダーとして


以下、2番目の方法を実装する方法を説明します

  • ローカルディレクトリを作成します。

    mkdir <mountdirectory>

  • このコマンドラインを使用して、リモートディレクトリをローカルにマウントします。

    sshfs <remoteserverip>:<remotedirpath> <mountdirectory>SSHの場合

    [〜#〜] or [〜#〜](cifs utilの最初のインストール:Sudo apt-get install cifs-utils

    mount -t cifs -o username=<USERNAME>,password=<PASSWD> //<remoteserverip>/<remotedirpath> <mountdirectory>SMBの場合

  • ローカルファイルでジョブを実行する

  • 最後に、このコマンドを使用してアンマウントします。

    fusermount -u <mountdirectory>

0
A STEFANI