读取以“开始”开头的远程文件;smb:/“;使用R
要在读取以“开始”开头的远程文件;smb:/“;使用R,r,remote-access,smb,R,Remote Access,Smb,要在R中读取文件,我通常会执行以下操作: read.csv('/Users/myusername/myfilename.csv') read.csv('smb://server.msu.edu/.../myfilename.csv') 但是,我正在尝试读取位于远程服务器(Windows SMB/CIFS共享)上的文件,我可以通过Finder在Mac上访问该文件→ 去→ “连接到服务器”菜单项 当我查看该文件的属性时,文件路径与我以前使用的不同。它不是以:/Users/myusername/…
R
中读取文件,我通常会执行以下操作:
read.csv('/Users/myusername/myfilename.csv')
read.csv('smb://server.msu.edu/.../myfilename.csv')
但是,我正在尝试读取位于远程服务器(Windows SMB/CIFS共享)上的文件,我可以通过Finder在Mac上访问该文件→ 去→ “连接到服务器”菜单项
当我查看该文件的属性时,文件路径与我以前使用的不同。它不是以:/Users/myusername/…
开头,而是smb://server.msu.edu/.../myfilename.csv
尝试读取文件时,我尝试了以下操作:
read.csv('/Users/myusername/myfilename.csv')
read.csv('smb://server.msu.edu/.../myfilename.csv')
但是,这不起作用
返回的不是通常的“无此类文件或目录”错误,而是:
smb://server.msu.edu/.../myfilename.csv 当前工作目录中不存在
我想象文件路径需要不同的格式,但我不知道是什么
如何在
R
中读取此类文件?SMB是Windows网络文件夹协议
类似的例子包括sftp://
url
您可以:
下面我展示了一种从SMB网络驱动器读取数据的方法。在下面的代码中,我使用了R
system
功能从R中执行所有操作,但您也可以从OSX命令行或使用command-K(连接到服务器)从Finder中装载驱动器:
如果您还没有,请在本地驱动器上创建共享所在的目录(这不是必需的,因为您可以在现有位置装载驱动器):
或
将网络驱动器装入刚刚创建的文件夹。在下面的代码中,//username@domain.address.edu/home/u/eipi10
是您的用户名和SMB共享的地址
system("mount_smbfs //username@domain.address.edu/home/u/eipi10 /Users/eipi10/temp_share")
如果有密码验证,则还可以包括密码:
system("mount_smbfs //username:password@domain.address.edu/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)
解释
smb://educ-srvmedia1.campusad.msu.edu/...
实际上是一个URL而不是文件路径
我们来分析一下
smb://
表示使用(文件共享)
educ-srvmedia1.campusad.msu.edu
是服务器的名称
/…/myfilename.csv
是远程服务器上的文件共享/路径
您可以使用OSX上的Finder导航到此目录,因为它内置了对SMB协议的支持。Finder使用URL连接到远程服务,并允许您浏览文件
但是R
不了解SMB协议,因此无法正确解释文件路径
R
函数read.csv()
在内部使用file()
,请参阅
url和文件支持url方案文件://、http://、https://和ftp://
因此R返回“找不到文件”消息,因为该协议不受支持,所以找不到该文件。是的,有点混乱
修理
您需要在本地文件系统上装载文件共享
所有这一切意味着SMB协议的细节将由操作系统在幕后处理,文件共享将显示为本地目录
这将允许R(和其他程序)像处理任何其他本地文件一样,出于所有目的处理远程文件。
显示了执行此操作的一些选项
e、 g
然后在R中:
read.csv('/LocalFolder/myfilename.csv')
额外的
Windows用户可以通过UNC路径更轻松地完成此任务在我看来,有两种方法可以实现你的目标
- 第一种方法是使用fstab将远程文件夹添加为本地磁盘
- 第二种方法是在需要时将远程文件夹临时挂载为文件夹
下面,我将解释如何实现第二种方法
- 创建本地目录:
mkdir
- 使用以下命令行将远程目录装载到本地目录:
sshfs:SSH的
或(首先安装cifs util:
)sudo apt get安装cifs util
用于SMBmount-t cifs-o用户名=,密码=//
- 使用本地文件执行此操作
- 最后,使用此命令卸载:
fusermount-u
- 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)
上面的命令从远程服务器host.example.com读取并输出(到STDOUT)file.txt的内容,并作为域上的指定用户进行身份验证。如果需要,该命令将提示我们输入密码。如果我们的网络不使用域,我们可以从用户名中删除域部分
系统调用
我们可以通过以下方式在R中实现相同的功能:
注意domain\\username
中的双反斜杠。这将转义反斜杠字符,以便R不会将其解释为字符串中的转义字符。通过将system()
函数的intern
参数设置为TRUE
,我们可以将命令输出中的文件内容捕获到变量中:
contents <- system("curl -u 'domain\\username' 'smb://host.example.com/share/file.txt'", intern = TRUE)
如果远程服务器需要,curl命令仍然会提示我们输入密码。虽然我们可以使用-u'domain\\username:password'
指定密码以避免出现提示,但这样做会在命令字符串中公开纯文本密码。要获得更安全的方法,请阅读下面描述包用法的部分
我们还可以将-s
或--silent
标志添加到curl命令以支持
> stream <- curl("smb://host.example.com/share/file.txt", handle = handle)
> contents <- read.csv(stream)
$ curl -u 'domain\username' 'smb://host.example.com/share/file.txt'
system("curl -u 'domain\\username' 'smb://host.example.com/share/file.txt'")
contents <- system("curl -u 'domain\\username' 'smb://host.example.com/share/file.txt'", intern = TRUE)
contents <- system2('curl', c("-u", "domain\\\\username", "smb://host.example.com/share/file.txt"), stdout = TRUE)
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)
content <- rawToChar(request$content)
handle = new_handle()
...
stream <- curl("smb://host.example.com/share/file.txt", handle = handle)
contents <- read.csv(stream)