Tcl двоичного сканирования

#binary #tcl #eof

#двоичный #tcl #eof

Вопрос:

У меня проблема с моим кодом из-за того, что сканируются не все строки из файла.

Оно остановилось после 1000 попыток. Я пытаюсь отсканировать все двоичные строки из wav-файла. Когда двоичное сканирование начинает возвращать важное для меня значение, я не знаю, почему возникает eof (осталось прочитать много байт).

     set fh [open $file r]
    binary scan [read $fh 12] A4iA4 sig1 len sig2
    if {$sig1 != "RIFF" || $sig2 != "WAVE"} { 
        close $fh; 
        return -code error "Not a WAV file" 
    }
    binary scan [read $fh 24] A4issiiss id size format channels samplerate byterate align bitrate
    binary scan [read $fh 8] A4i data sampletoread
    set len [expr {[file size $file] - [tell $fh] - 8 - ($size - 16)}]
    set str [ list ]
    while {1} {
        if {[eof $fh]} break
        binary scan [read $fh 1000] c* str
        puts "$str"
    } 
}
  

Ответ №1:

Проблема в том, что вы открыли файл в текстовом режиме, а не в двоичном режиме, поэтому ввод останавливается на первом ^Z символе (который является официальным символом EOF текста ASCII; на самом деле это полезно в некоторых вариантах использования, но не в вашем). Поскольку вы считываете двоичные данные, вы должны открыть их как таковые, передав b флаг открытого режима:

 set fh [open $file rb]
  

Если вы используете более старую версию Tcl, вы вместо этого (и эквивалентно) делаете:

 set fh [open $file r]
fconfigure $fh -translation binary
  

b Флаг — это просто (очень) удобный ярлык. (Второй способ работает на всех версиях Tcl вплоть до 8.0; до этого вы вообще не хотели обрабатывать двоичные данные непосредственно в Tcl.)