Spec-Zone.ru › Tcl/Tk

fcopy

Имя

fcopy — Копирование данных с одного канала на другой

Синтаксис

fcopy inchan outchan ?-size size? ?-command callback?

Описание

Команда fcopy копирует данные с одного канала ввода/вывода, inchan, на другой канал ввода/вывода, outchan. Команда fcopy использует буферизацию в системе ввода/вывода Tcl, чтобы избежать дополнительных копий и избыточного буферизации данных в оперативной памяти при копировании больших файлов на медленные устройства, такие как сетевые сокеты.

Команда fcopy передает данные из inchan до конца файла или пока не будет передано size байт или символов; size измеряется в байтах, если оба канала используют одно кодирование, и в символах в противном случае. Если аргумент -size не указан, копирование продолжается до конца файла. Все данные, прочитанные из inchan, копируются в outchan. Без опции -command, fcopy блокируется до завершения копирования и возвращает количество байт или символов (используя те же правила, что и для опции -size), записанных в outchan.

Аргумент -command заставляет fcopy работать в фоновом режиме. В этом случае он возвращается немедленно, и callback вызывается позже, когда копирование завершается. Callback вызывается с одним или двумя дополнительными аргументами, которые указывают, сколько байт было записано в outchan. Если во время фоновой копии произошла ошибка, второй аргумент — строка ошибки, связанная с ошибкой. При фоновой копии нет необходимости устанавливать inchan или outchan в режим без блокировки; команда fcopy позаботится об этом автоматически. Однако необходимо войти в цикл обработки событий с помощью команды vwait или с помощью Tk.

Во время фоновой fcopy запрещается выполнять другие операции ввода с inchan или операции вывода с outchan. Обратное вполне допустимо, как показано в примере двунаправленной fcopy ниже.

Если inchan или outchan закрываются во время копирования, текущее копирование останавливается, и обратный вызов команды не выполняется. Если inchan закрывается, все данные, уже помещенные в очередь для outchan, выписываются.

Обратите внимание, что inchan может стать читаемым во время фоновой копии. Вы должны отключить все обработчики fileevent во время фоновой копии, чтобы эти обработчики не мешали процессу копирования. Любые неправильные операции ввода-вывода (попытка обработчика fileevent или иным образом) приведут к ошибке «занятый канал».

Fcopy преобразует последовательности символов конца строки в inchan и outchan в соответствии с опцией -translation для этих каналов. См. справочную статью по fconfigure для получения подробной информации об опции -translation. Эти преобразования означают, что количество байт, прочитанных из inchan, может отличаться от количества байт, записанных в outchan. Сообщается только количество байт, записанных в outchan, как значение возврата синхронной fcopy или как аргумент обратного вызова для асинхронной fcopy.

Fcopy подчиняется кодировкам и преобразованиям символов, настроенным для каналов. Это означает, что входящие символы сначала преобразуются во внутренний UTF-8, а затем в кодировку канала, в который fcopy записывает. См. справочную статью по fconfigure для получения подробной информации об опциях -encoding и -translation. Преобразование не выполняется, если оба канала установлены в кодировку «двоичный» и имеют соответствующие преобразования. Если только выходной канал установлен в кодировку «двоичный», система запишет внутреннее представление входящих символов в UTF-8. Если только входной канал установлен в кодировку «двоичный», система предположит, что входящие байты являются допустимыми символами UTF-8 и преобразует их в соответствии с кодировкой вывода. Поведение системы для байтов, которые не являются допустимыми символами UTF-8, в этом случае не определено.

Примеры

Первый пример точно передает содержимое одного канала в другой. Обратите внимание, что при копировании одного файла в другой лучше использовать команду file copy, которая также копирует метаданные файла (например, разрешения доступа к файлу), где это возможно.
fconfigure $in -translation binary
fconfigure $out -translation binary
fcopy $in $out

Этот второй пример показывает, как обратный вызов получает количество переданных байт. Он также использует vwait, чтобы поместить приложение в цикл обработки событий. Конечно, этот упрощенный пример можно выполнить без обратного вызова команды.

proc Cleanup {in out bytes {error {}}} {
    global total
    set total $bytes
    close $in
    close $out
    if {[string length $error] != 0} {
        # error occurred during the copy
    }
}
set in [open $file1]
set out [socket $server $port]
fcopy $in $out -command [list Cleanup $in $out]
vwait total

Третий пример копирует данными по частям и проверяет конец файла в обратном вызове команды.

proc CopyMore {in out chunk bytes {error {}}} {
    global total done
    incr total $bytes
    if {([string length $error] != 0) || [eof $in]} {
        set done $total
        close $in
        close $out
    } else {
        fcopy $in $out -size $chunk \
                -command [list CopyMore $in $out $chunk]
    }
}
set in [open $file1]
set out [socket $server $port]
set chunk 1024
set total 0
fcopy $in $out -size $chunk \
        -command [list CopyMore $in $out $chunk]
vwait done

Четвертый пример запускает асинхронное двунаправленное копирование fcopy между двумя сокетами. Их также можно использовать как трубы из двух [open "|hal 9000" r+] (хотя их разговор останется секретным для скрипта, так как все четыре слота fileevent заняты).

set flows 2
proc Done {dir args} {
     global flows done
     puts "$dir is over."
     incr flows -1
     if {$flows<=0} {set done 1}
}
fcopy $sok1 $sok2 -command [list Done UP]
fcopy $sok2 $sok1 -command [list Done DOWN]
vwait done

См. также

eof, fblocked, fconfigure, file

Licensed under Tcl/Tk terms
https://www.tcl.tk/man/tcl/TclCmd/fcopy.htm

Licensed under Tcl/Tk terms
https://www.tcl.tk/man/tcl/TclCmd/fcopy.htm

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API