src/asyncftpclient
nimble install asyncftpclient. Этот модуль реализует асинхронный FTP-клиент. Он позволяет подключаться к FTP-серверу и выполнять операции, такие как, например:
- Загрузка новых файлов.
- Удаление существующих файлов.
- Загрузка файлов.
- Изменение разрешений файлов.
- Перемещение по каталогам FTP-сервера.
Подключение к FTP-серверу
Для начала любого обмена файлами необходимо сначала подключиться к FTP-серверу. Это можно сделать с помощью процедуры connect.
import std/asyncdispatch
import pkg/asyncftpclient
proc main() {.async.} =
var ftp = newAsyncFtpClient("example.com", user = "test", pass = "test")
await ftp.connect()
echo("Connected")
waitFor(main()) Необходимо объявить новую асинхронную процедуру main, чтобы разрешить использование ключевого слова await. Подключение будет завершено асинхронно, и клиент будет подключен после вызова await ftp.connect().
Загрузка нового файла
После подключения можно использовать процедуру store для загрузки нового файла на FTP-сервер. Убедитесь, что вы находитесь в правильном рабочем каталоге, перед этим используйте процедуру pwd, вы также можете указать абсолютный путь.
import std/asyncdispatch
import pkg/asyncftpclient
proc main() {.async.} =
var ftp = newAsyncFtpClient("example.com", user = "test", pass = "test")
await ftp.connect()
let currentDir = await ftp.pwd()
assert currentDir == "/home/user/"
await ftp.store("file.txt", "file.txt")
echo("File finished uploading")
waitFor(main()) Проверка прогресса передачи файла
Прогресс загрузки или скачивания файла можно проверить, указав процедуру onProgressChanged для процедур store или retrFile.
Процедуры, принимающие обратный вызов onProgressChanged, будут вызывать его каждые progressInterval миллисекунд.
import std/asyncdispatch
import pkg/asyncftpclient
proc onProgressChanged(total, progress: BiggestInt,
speed: float) {.async.} =
echo("Uploaded ", progress, " of ", total, " bytes")
echo("Current speed: ", speed, " kb/s")
proc main() {.async.} =
var ftp = newAsyncFtpClient("example.com", user = "test", pass = "test", progressInterval = 500)
await ftp.connect()
await ftp.store("file.txt", "/home/user/file.txt", onProgressChanged)
echo("File finished uploading")
waitFor(main()) Типы
AsyncFtpClient = ref object csock*: AsyncSocket dsock*: AsyncSocket user*, pass*: string address*: string port*: Port jobInProgress*: bool job*: FtpJob dsockConnected*: bool when defined(ssl):
FtpEvent = object filename*: string case typ*: FtpEventType of EvLines: lines*: string ## Lines that have been transferred. of EvRetr, EvStore: ## Retr/Store operation finished. nil of EvTransferProgress: bytesTotal*: BiggestInt ## Bytes total. bytesFinished*: BiggestInt ## Bytes transferred. speed*: BiggestInt ## Speed in bytes/s currentJob*: FtpJobType ## The current job being performed.- Событие
FtpEventType = enum EvTransferProgress, EvLines, EvRetr, EvStore
FtpJobType = enum JRetrText, JRetr, JStore
ProgressChangedProc = proc (total, progress: BiggestInt; speed: float): Future[ void] {.closure, ...gcsafe.}ReplyError = object of IOError
Процедуры
proc cd(ftp: AsyncFtpClient; dir: string): owned(Future[void]) {. ...stackTrace: false, raises: [Exception], tags: [RootEffect], forbids: [].}- Изменяет текущий каталог на удалённом FTP-сервере на
dir. proc cdup(ftp: AsyncFtpClient): owned(Future[void]) {....stackTrace: false, raises: [Exception], tags: [RootEffect], forbids: [].}- Изменяет текущий каталог на родительский.
proc chmod(ftp: AsyncFtpClient; path: string; permissions: set[FilePermission]): owned( Future[void]) {....stackTrace: false, raises: [Exception], tags: [RootEffect], forbids: [].}- Изменяет разрешения
pathнаpermissions. proc connect(ftp: AsyncFtpClient): owned(Future[void]) {....stackTrace: false, raises: [Exception], tags: [RootEffect], forbids: [].}- Подключение к FTP-серверу, указанному в
ftp. proc createDir(ftp: AsyncFtpClient; dir: string; recursive = false): owned( Future[void]) {....stackTrace: false, raises: [Exception], tags: [RootEffect], forbids: [].}- Создаёт каталог
dir. Еслиrecursiveимеет значение true, сначала будет создан самый верхний подкаталогdir, затем второй и т.д. Это позволяет указать полный путь какdir, не беспокоясь о том, что подкаталоги не существуют. proc defaultOnProgressChanged(total, progress: BiggestInt; speed: float): Future[ void] {.nimcall, ...gcsafe, raises: [Exception], tags: [RootEffect], forbids: [].}- По умолчанию обработчик прогресса FTP
onProgressChanged. Ничего не делает. proc fileExists(ftp: AsyncFtpClient; file: string): Future[bool] {. ...stackTrace: false, raises: [Exception, ValueError], tags: [RootEffect], forbids: [].}- Определяет, существует ли
file. proc list(ftp: AsyncFtpClient; dir = ""): Future[string] {....stackTrace: false, raises: [Exception, ValueError], tags: [RootEffect], forbids: [].}- Выводит список всех файлов в
dir. Еслиdirравно"", используется текущий рабочий каталог. proc listDirs(ftp: AsyncFtpClient; dir = ""): Future[seq[string]] {. ...stackTrace: false, raises: [Exception, ValueError], tags: [RootEffect], forbids: [].}- Возвращает список имён файлов в заданном каталоге. Если
dirравно "", используется текущий каталог. Еслиasyncимеет значение true, эта функция вернётся немедленно, и вам нужно будет использоватьpollasyncdispatch для продвижения этой операции. proc newAsyncFtpClient(address: string; port = Port(21); user, pass = ""; progressInterval: int = 1000; useTls = false; sslContext: SslContext = nil): AsyncFtpClient {. ...raises: [OSError], tags: [], forbids: [].}- Создаёт новый объект
AsyncFtpClient. proc pwd(ftp: AsyncFtpClient): Future[string] {....stackTrace: false, raises: [Exception, ValueError], tags: [RootEffect], forbids: [].}- Возвращает текущий рабочий каталог.
proc removeDir(ftp: AsyncFtpClient; dir: string): owned(Future[void]) {. ...stackTrace: false, raises: [Exception], tags: [RootEffect], forbids: [].}- Удаляет каталог
dirна удалённом FTP-сервере proc removeFile(ftp: AsyncFtpClient; filename: string): owned(Future[void]) {. ...stackTrace: false, raises: [Exception], tags: [RootEffect], forbids: [].}- Удаляет файл
filenameна удалённом FTP-сервере proc rename(ftp: AsyncFtpClient; nameFrom: string; nameTo: string): owned( Future[void]) {....stackTrace: false, raises: [Exception], tags: [RootEffect], forbids: [].}- Переименовывает файл или каталог на удалённом FTP-сервере из текущего имени
name_fromв новое имяname_to proc retrFile(ftp: AsyncFtpClient; file, dest: string; onProgressChanged: ProgressChangedProc = defaultOnProgressChanged): owned( Future[void]) {....stackTrace: false, raises: [Exception], tags: [RootEffect, TimeEffect, WriteIOEffect], forbids: [].}- Скачивает
fileи сохраняет его вdest. СобытиеEvRetrпередаётся указанной функцииhandleEventпри завершении скачивания. Полеfilenameсобытия будет равноfile. proc retrText(ftp: AsyncFtpClient; file: string): Future[string] {. ...stackTrace: false, raises: [Exception, ValueError], tags: [RootEffect], forbids: [].}- Восстанавливает
file. Файл должен быть текстовым ASCII. proc send(ftp: AsyncFtpClient; m: string): Future[string] {....stackTrace: false, raises: [Exception, ValueError], tags: [RootEffect], forbids: [].}-
Отправляет сообщение на сервер и ждёт первичного ответа.
\c\Lдобавлено для вас.Убедитесь, что сообщение
mне содержит символов новой строки. В противном случае будет выброшено исключениеAssertionDefect.Примечание: Сервер может вернуть несколько строк кодированных ответов.
proc store(ftp: AsyncFtpClient; file, dest: string; onProgressChanged: ProgressChangedProc = defaultOnProgressChanged): owned( Future[void]) {....stackTrace: false, raises: [Exception], tags: [RootEffect, ReadIOEffect, TimeEffect], forbids: [].}- Загружает
fileвdestна удалённый FTP-сервер. Рекомендуется использовать эту функцию асинхронно, чтобы увидеть прогресс загрузки. СобытиеEvStoreпередаётся указанной функцииhandleEventпри завершении загрузки, и полеfilenameбудет равноfile.
© 2006–2024 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/asyncftpclient.html