读取以“开始”开头的远程文件;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

您可以:

  • 在操作系统中装入文件夹,并使用常规路径访问它
  • 使用虚拟文件系统库,例如Linux上的GVFS/GIO。也许有一些R包装器可以使用

  • 下面我展示了一种从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

      mount-t cifs-o用户名=,密码=//
      用于SMB

    • 使用本地文件执行此操作

    • 最后,使用此命令卸载:

      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)