Подтвердить что ты не робот

Прочитайте удаленный файл, начинающийся с "smb://", используя R

Чтобы прочитать файл в R, я обычно делал бы что-то вроде следующего:

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

Но я пытаюсь прочитать файл, расположенный на удаленном сервере (общий ресурс Windows SMB/CIFS), доступ к которому я могу получить на своем Mac через Finder → Go → Подключитесь к пункту меню "Сервер".

Когда я просматриваю эти свойства файла, путь к файлу отличается от того, к которому я привык. Вместо того, чтобы начинать с: /Users/myusername/..., это smb://server.msu.edu/.../myfilename.csv.

Пытаясь прочитать файл, я попробовал следующее:

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

Но это не сработало.

Вместо обычной ошибки "Нет такого файла или каталога" это возвращалось:

smb://server.msu.edu/.../myfilename.csv не существует в текущем рабочем каталоге

Я предполагаю, что путь к файлу нужен в другом формате, но я не могу понять, что.

Как вы можете прочитать этот тип файла в R?

4b9b3361

Ответ 1

Объяснение

smb://educ-srvmedia1.campusad.msu.edu/... на самом деле URL не путь к файлу.

Позвольте сломать это вниз

smb:// означает использование протокола протокола сообщений сервера (совместное использование файлов)

educ-srvmedia1.campusad.msu.edu - это имя сервера

/.../myfilename.csv - общий ресурс/путь к файлу на удаленном сервере

Вы можете перейти в этот каталог с помощью Finder на OSX, поскольку он поддерживает поддержку протокола SMB. Finder подключается к удаленной службе с помощью URL-адреса и позволяет просматривать файлы.

Однако R не понимает протокол SMB, поэтому не может правильно интерпретировать путь к файлу.

Функция R read.csv() использует file() внутренне, см. https://stat.ethz.ch/R-manual/R-devel/library/base/html/connections.html

URL-адреса URL-адресов и файлов://, http://, https://и ftp://

Итак, R возвращает сообщение "не удалось найти файл", потому что файл не может быть найден, потому что протокол не поддерживается. да, немного запутанный.

Fix

Вам нужно установить общий ресурс файла в локальную файловую систему.

Все это означает, что детали протокола SMB будут обрабатываться операционной системой за кулисами, а файл файл будет представлен как локальный каталог.

Это позволит R (и другим программам) обрабатывать удаленные файлы для всех целей и задач, как и любые другие локальные файлы. В этом обсуждении показаны некоторые варианты для этого.

например.

# need to create /LocalFolder first
mount -t cifs //username:[email protected]/sharename /LocalFolder

то в R:

read.csv('/LocalFolder/myfilename.csv')

Extra

Пользователи Windows могут сделать это проще с помощью UNC-путей
Как читать файлы из указанного UNC-каталога в R?

Ответ 2

Ниже я показал способ, который я использовал время от времени для чтения данных с сетевого диска 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)

Ответ 3

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)

Позвольте взглянуть на более надежный способ доступа к удаленным файлам через URL-адреса smb://, кроме подхода, описанного в других ответах, которые монтируют удалённую файловую систему. К сожалению, я немного опаздываю к этому, но надеюсь, что это поможет будущим читателям.

В некоторых случаях у нас могут не быть привилегии, необходимые для монтирования файловой системы (для этого требуется доступ администратора или root на многих системах), или просто не нужно монтировать всю файловую систему только для чтения одного файла. Мы будем использовать библиотеку cURL, чтобы вместо этого прочитать файл. Такой подход повышает гибкость и переносимость наших программ, поскольку нам не нужно зависеть от наличия файловой системы, смонтированной извне. Мы рассмотрим два разных способа: через вызов system() и с помощью пакета, предоставляющего API cURL.

Некоторая предыстория: для тех, кто не знаком с ней, cURL предоставляет инструменты, используемые для передачи данных по различным протоколам. Поскольку версия 7.40, cURL поддерживает протокол SMB/CIFS, обычно используемый для служб обмена файлами Windows. cURL включает инструмент командной строки, который мы можем использовать для извлечения содержимого файла:

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

Приведенная выше команда считывает и выводит (в STDOUT) содержимое file.txt с удаленного сервера host.example.com, аутентифицируя в качестве указанного пользователя в домене, При необходимости команда предложит ввести пароль. Мы можем удалить часть домена из имени пользователя, если наша сеть не использует домен.

Системный вызов

Мы можем достичь той же функциональности в R, используя system() function:

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

Обратите внимание на двойную обратную косую черту в domain\\username. Это ускользает от символа обратной косой черты, так что R не интерпретирует его как escape-символ в строке. Мы можем записать содержимое файла из выходного файла команды в переменную, установив параметр intern функции system() в 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 по-прежнему запрашивает у нас пароль, если это требуется удаленному серверу. Хотя мы можем указать пароль с помощью -u 'domain\\username:password', чтобы избежать приглашения, он предоставляет открытый текст в командной строке. Для более безопасного подхода прочтите раздел ниже, описывающий использование пакета.

Мы также можем добавить флаг -s или --silent в команду curl, чтобы подавить вывод состояния прогресса. Обратите внимание, что при этом также будут скрыты сообщения об ошибках, поэтому мы также можем добавить -s (--show-error). Переменная contents будет содержать вектор строк файла — аналогично значению, возвращаемому readLines("file.txt") — мы можем скворовать обратно вместе с помощью paste(contents, collapse = "\n").

API cURL

Хотя все это прекрасно работает, мы можем улучшить этот подход, используя специальную библиотеку cURL. Этот curl package обеспечивает привязки R к libcurl так что мы можем напрямую использовать API cURL в нашей программе. Сначала нам нужно установить пакет:

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)

Конечно, концепции, описанные выше, относятся к извлечению содержимого или тела ответа по любому протоколу, поддерживаемому cURL, а не только SMB/CIFS. При необходимости мы также можем использовать эти инструменты для загрузки файлов в файловую систему, а не просто чтения содержимого в память.

Ответ 4

SMB - это протокол сетевых каталогов Windows.

Аналогичные случаи включают, например, URL sftp://.

Вы можете:

  • смонтировать папку в вашей операционной системе и получить доступ к ней с помощью обычного пути,
  • используйте библиотеку виртуальной файловой системы, такую ​​как GVFS/GIO в Linux. Может быть, существует какая-то обертка R вокруг этого, которую вы можете использовать.

Ответ 5

По моему мнению, есть два пути для достижения вашей цели.

  • Первым из них является использование fstab для добавление определенно удаленной папки в качестве локального диска.

  • Вторая - временная установка удаленной папки в качестве папки, когда это необходимо


Bellow, я объясню, как можно реализовать второй метод

  • Создайте локальный каталог:

    mkdir <mountdirectory>

  • Подключите свой удаленный каталог к ​​локальному с помощью этой командной строки:

    sshfs <remoteserverip>:<remotedirpath> <mountdirectory> для SSH

    ИЛИ (сначала установите cifs util: sudo apt-get install cifs-utils)

    mount -t cifs -o username=<USERNAME>,password=<PASSWD> //<remoteserverip>/<remotedirpath> <mountdirectory> для SMB

  • Выполнение задания с локальным файлом!

  • В конце используйте эту команду, чтобы отключить:

    fusermount -u <mountdirectory>