2012-05-04 2 views
0

У меня возникла проблема в одном из моих сценариев Tcl, где я загружаю файл с компьютера Windows на Unix-сервер. Я хотел бы получить только оригинальное имя файла из файла Windows и сохранить новый файл с тем же именем. Проблема в том, что [файл tail windows_file_name] не работает, он возвращает целое имя файла, например «c: \ temp \ dog.jpg», а не просто «dog.jpg». Файловый хвост работает правильно над именем файла Unix «/usr/tmp/dog.jpg», поэтому по какой-то причине он не обнаруживает, что файл находится в формате Windows. Однако Tcl на моем компьютере Windows работает правильно для любого формата имени. Я использую Tcl 8.4.18, так, может быть, он слишком стар? Есть ли еще один трюк, чтобы заставить его правильно разбить?Tcl определить имя файла из загрузки браузера

Благодаря

ответ

1

Проблема здесь состоит в том, что в Windows, как \ и / действительны разделителей до тех пор, Windows API обеспокоен (даже если только \ считается " официальный "в Windows). С другой стороны, в POSIX единственным допустимым разделителем пути является /, и только два байта, которые не могут отображаться в компоненте пути, равны / и \0 (байт со значением 0).

Таким образом, в системе POSIX, "C: \ Foo \ bar.baz" является вполне допустимо короткое имя файла, и работает

file normalize {C:\foo\bar.baz} 

даст /path/to/current/dir/C:\foo\bar.baz. По той же логике [file tail $short_filename] совпадает с $short_filename.

Решение заключается в том, чтобы сделать то, что предложил Гленн Джекман или каким-то образом передать короткое имя в браузере с помощью других средств (некоторые JS связаны с соответствующей записью файла?). Также вы можете попытаться обнаружить ОС пользователя из заголовка User-Agent.

Для того, чтобы идея Гленна более независимой от платформы пользователя, вы могли бы пойти как это:

  1. Сканирование имя файла «/».
    • Если ничего не найдено, сделайте set fname [string map {\\ /} $fname], затем перейдите к следующему шагу.
  2. Используйте [file tail $fn], чтобы извлечь название хвоста.

Это не очень пуленепробиваемый, но, мол, лучше ничего.

+0

Спасибо, я думаю, что строковая карта - это самый чистый подход. – Matt

0

Вы всегда можете сделать [lindex [split $windows_file_name \\] end]