Jos*_*erg 20 smb r remote-access
要读入文件R
,我通常会执行以下操作:
read.csv('/Users/myusername/myfilename.csv')
Run Code Online (Sandbox Code Playgroud)
但是,我正在尝试读取位于远程服务器上的文件(Windows SMB/CIFS共享),我通过Finder → Go → Connect to Server菜单项在我的Mac上访问该文件.
当我查看该文件的属性时,文件路径与我习惯的不同.不是以:开头/Users/myusername/...
,而是smb://server.msu.edu/.../myfilename.csv
.
尝试阅读该文件,我尝试了以下内容:
read.csv('smb://server.msu.edu/.../myfilename.csv')
Run Code Online (Sandbox Code Playgroud)
但是,这没有用.
而不是通常的"没有这样的文件或目录"错误,这返回:
smb://server.msu.edu /.../ myfilename.csv在当前工作目录中不存在
我想文件路径需要不同的格式,但我无法弄清楚是什么.
你怎么能读到这种类型的文件R
?
sta*_*cks 18
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()
,请参阅https://stat.ethz.ch/R-manual/R-devel/library/base/html/connections.html
url和文件支持URL方案file://,http://,https://和ftp://
因此,R返回"无法找到文件"消息,因为无法找到该文件,因为协议不受支持.是的,有点混乱.
您需要在本地文件系统上挂载文件共享.
所有这些意味着SMB协议的细节将由OS在幕后处理,文件共享将显示为本地目录.
这将允许R(和其他程序)处理远程文件的所有意图和目的,就像任何其他本地文件一样. 此讨论显示了这样做的一些选项.
例如
# need to create /LocalFolder first
mount -t cifs //username:password@hostname/sharename /LocalFolder
Run Code Online (Sandbox Code Playgroud)
然后在R:
read.csv('/LocalFolder/myfilename.csv')
Run Code Online (Sandbox Code Playgroud)
Windows用户可以使用UNC路径更轻松地完成此操作
如何从R中的UNC指定目录中读取文件?
Cy *_*nol 10
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)
Run Code Online (Sandbox Code Playgroud)
如果我们需要将内容读取为CSV,就像在问题中一样,我们可以通过另一个函数来传输文件:
> stream <- curl("smb://host.example.com/share/file.txt", handle = handle)
> contents <- read.csv(stream)
Run Code Online (Sandbox Code Playgroud)
让我们看一下通过smb:// URL 访问远程文件的更健壮的方法,除了安装远程文件系统的其他答案中描述的方法.不幸的是,我对这个有点晚了,但我希望这有助于未来的读者.
在某些情况下,我们可能没有安装文件系统所需的权限(这需要在许多系统上进行管理或root访问),或者我们可能根本不想仅仅为了读取单个文件而安装整个文件系统.我们将使用cURL库来读取文件.这种方法提高了程序的灵活性和可移植性,因为我们不需要依赖外部安装的文件系统的存在.我们将研究两种不同的方式:通过system()
调用,以及使用提供cURL API的包.
一些背景:对于那些不熟悉它的人,cURL提供了用于通过各种协议传输数据的工具.从版本7.40开始,cURL支持通常用于Windows文件共享服务的SMB/CIFS协议.cURL包含一个命令行工具,我们可以使用它来获取文件的内容:
$ curl -u 'domain\username' 'smb://host.example.com/share/file.txt'
Run Code Online (Sandbox Code Playgroud)
上面的命令从远程服务器host.example.com读取并输出(到STDOUT)file.txt的内容,该文件作为域上的指定用户进行身份验证.如果需要,该命令将提示我们输入密码.如果我们的网络不使用域,我们可以从用户名中删除域部分.
系统调用
我们可以使用以下system()
函数在R中实现相同的功能:
system("curl -u 'domain\\username' 'smb://host.example.com/share/file.txt'")
Run Code Online (Sandbox Code Playgroud)
请注意双反斜杠domain\\username
.这会转义反斜杠字符,以便R不会将其解释为字符串中的转义字符.我们可以通过将函数的intern
参数设置system()
为TRUE
:将命令输出中的文件内容捕获到变量中:
contents <- system("curl -u 'domain\\username' 'smb://host.example.com/share/file.txt'", intern = TRUE)
Run Code Online (Sandbox Code Playgroud)
...或者通过调用system2()
来引用命令参数以获得安全性并更好地处理平台之间的进程重定向:
contents <- system2('curl', c("-u", "domain\\\\username", "smb://host.example.com/share/file.txt"), stdout = TRUE)
Run Code Online (Sandbox Code Playgroud)
该卷曲如果需要远程服务器的命令仍然会提示我们输入密码.虽然我们可以使用指定密码-u 'domain\\username:password'
来避免提示,但这样做会在命令字符串中公开明文密码.有关更安全的方法,请阅读下面介绍软件包使用情况的部分.
我们还可以在curl命令中添加-s
或--silent
标记以禁止进度状态输出.请注意,这样做也会隐藏错误消息,因此我们也可能还想添加().该变量将包含文件行的向量 - 类似于我们可以使用返回的值返回的值.-S
--show-error
contents
readLines("file.txt")
paste(contents, collapse = "\n")
cURL API
虽然这一切都很好,但我们可以通过使用专用的cURL库来改进这种方法.这个curl包提供了与libcurl的 R绑定,因此我们可以直接在程序中使用cURL API.首先我们需要安装包:
install.packages("curl")
require("curl")
Run Code Online (Sandbox Code Playgroud)
(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)
Run Code Online (Sandbox Code Playgroud)
首先,我们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)
Run Code Online (Sandbox Code Playgroud)
当然,上述概念适用于通过cURL支持的任何协议获取内容或响应主体,而不仅仅是SMB/CIFS.如果需要,我们也可以使用这些工具将文件下载到文件系统,而不是仅仅将内容读入内存.
下面我展示了一种我不时用来从SMB网络驱动器读取数据的方法.在下面的代码中,我使用R system
函数从R内部执行所有操作,但您也可以从OSX命令行或使用Command-K(连接到服务器)从Finder中安装驱动器:
如果您还没有,请在本地驱动器上创建共享所在的目录(这不是必需的,因为您可以将驱动器安装在现有位置):
system("mkdir /Users/eipi10/temp_share/")
Run Code Online (Sandbox Code Playgroud)
要么
dir.create("/Users/eipi10/temp_share/")
Run Code Online (Sandbox Code Playgroud)
将网络驱动器安装到刚刚创建的文件夹中.在下面的代码中,//username@domain.address.edu/home/u/eipi10
是您的用户名和SMB共享的地址.
system("mount_smbfs //username@domain.address.edu/home/u/eipi10 /Users/eipi10/temp_share")
Run Code Online (Sandbox Code Playgroud)
如果有密码验证,那么也可以包含密码:
system("mount_smbfs //username:password@domain.address.edu/home/u/eipi10 /Users/eipi10/temp_share")
Run Code Online (Sandbox Code Playgroud)
阅读数据:
dat = read.csv("/Users/eipi10/temp_share/fileToRead.csv")
Run Code Online (Sandbox Code Playgroud)
在R中,您还可以以编程方式选择要读取的文件:
data.list = lapply(list.files(pattern="csv$", "/Users/eipi10/temp_share/", full.names=TRUE), read.csv)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
8574 次 |
最近记录: |