FTP: ftp_size($connection_id, $file) - работа с большими файлами

maxru

МИФИст
FTP: ftp_size($connection_id, $file) - работа с большими файлами

Написал несложный скрипт, который обходит локальный ФТП сервер и составляет список фильмов (для тренировки).
Вот фрагмент, получаемого в результате работы списка:

Гардемарины, вперед 4 серия ч1.avi 532.36 MB
Гардемарины, вперед 4 серия ч2.avi 154.95 MB
Гарпастум.VOB 815.61 MB
Гарри Поттер 1_3.ratDVD -1709400371 B
Гарри Поттер 2.ratDVD 928.53 MB
Гарфилд 2 (Garfield A Tail of Two Kitties).avi 701.22 MB

Как вы видите, при попытке получить размер файла >2.5 Гб я получаю отрицательные числа.
(Реальный размер "Гарри Поттер 1_3.ratDVD"=2465.7Мб)
Возникают аналогии с "нехваткой разрядов". (Пример: прибавьте 129 к short int в C).

Вопрос, как всегда: "Кто виноват и что делать".
 

Фанат

oncle terrible
Команда форума
1. запрашивать rawlist и парсить ручками.
или скачать готовое решение.

2. поставить самую последнюю версию, протестировать, и если да, то написать багрепорт
 

maxru

МИФИст
Второе мне понравилось больше. Проверю - отпишусь.
Спасибо за советы.

-~{}~ 25.02.07 18:07:

Поставил 5.2.1/
Результаты:
Гарпастум.VOB 815.61 MB
Гарри Поттер 1_3.ratDVD -1709400371 B

Как писать багрепорт? ;)
 

phprus

Moderator
Команда форума
maxru
Возникают аналогии с "нехваткой разрядов".
Нехватка разрядов будет после того, как размер перевалит за 4 гигабайта, а сейчас просто большие положительные числа превращаются в отрицательные из-за особенностей хранения знаковых целых.
А так как в php все зелые знаковые, то тут можно использоватьб sprintf("%u", $size); тогда число будет превращаться в положительное, но при работе с ним как с числом оно будет иметь вещественный тип.
 

maxru

МИФИст
Получилось примерно то, что надо, но все равно это косяк ;)
Байки из склепа (10 томов) 4GB
 

hermit_refined

Отшельник
багрепорт не поможет, разработчики не могут быть не в курсе.
хотя бы потому, что в php отдается int (ну и внутри используется он же).
в шестерке, может быть, подкорректируют.

но смущает, что вы получаете отрицательное число - в unix, по крайней мере, atoi должно возвращать LONG_MAX.
спросите напрямую у ftp-сервера размер файла (SIZE) - интересно, что вам ответят.
 

hermit_refined

Отшельник
какой где ftp-сервер для php все равно.
важно, что он отвечает.
и м.б. - ось, на которой скрипт исполняете.
 

SiMM

Новичок
> но смущает, что вы получаете отрицательное число - в unix, по крайней мере, atoi должно возвращать LONG_MAX.
ИМХО, всё правильно. Дабы нормальное значение всё же можно было получить.
PHP:
<?=sprintf('%u',-1709400371) // 2585566925 ?>
 

hermit_refined

Отшельник
ИМХО, всё правильно. Дабы нормальное значение всё же можно было получить.
ну, это с точки зрения - коли так выходит, то иногда можно с помощью хака что-то правильное получить.

я же про другое - смотрю в исходники, и вижу, что посылается запрос SIZE file, и atoi преобразовывает ответ в int.
значит, похоже на то, что отрицательное число отдается уже ftp-сервером, и php тут вообще не при делах.
 

maxru

МИФИст
какой где ftp-сервер для php все равно.
Да ну... а я-то, дурак, не знал :D
похоже на то, что отрицательное число отдается уже ftp-сервером, и php тут вообще не при делах.
Похоже, действительно такое возможно. Вопрос только в том, где бы найти сервак с файлами >2.5Гб под Linux?
 

vovanium

Новичок
преобразовывает ответ в int.
В php int знаковый, вот и получается то что больше двух гиг будет отрицательным, так юзай как посоветовали выше sprintf либо, как посоветовал Фанат, сам обрабатывай то что вернул сервер.
 

LAV ©

Новичок
Столкнулся с похожей проблемой. Есть индексатор фильмов в сети. В его задачу входит скачать у файла последние 64 килобайта и вычислить их MD5 значение. Сейчас размер файлов фильмов стал и 4 и 5 и даже 10 ГБ - формат HDTV. На файлах больше 2 ГБ индексатор "глючит". Начинает скачивать "последние" 64 килобайта с момента 2ГБ-64кБ и до самого конца файла, т.е. может скачать и 8 ГБ.
Возник вопрос. Как сохранить и обработать правильный размер файла? Переменная в PHP, к сожалению, имеет недостаточный размер.
 

SiMM

Новичок
> Как сохранить и обработать правильный размер файла?
Писать свой FTP-клиент, например, через [m]fsockopen[/m], с использованием, к примеру, [m]bc[/m]
 

AndreyUgnich

Новичок
на 64-битной системе:
PHP:
<?=sprintf('%u',-1709400371) // 118446744072000151245 ?>
Неужели нет другого варианта, кроме как парсить результат ftp_rawlist?
 

AndreyUgnich

Новичок
Сам отвечаю на свой вопрос.
Даже на 64-битной Cent OS с vsFTP сервером, при запросе размера большого файла посредством ftp_size размер приходит отрицательный. Возможно, это проблема FTP сервера.
Я решил свои задачи при помощи функции, написанной на основе кода из комментариев мануала по ftp_size (функция не идеальна, т.к. нет проверок на ошибки):
PHP:
function ftp_sizebig($ftpConnection,$filename){
	$response =  ftp_raw($ftpConnection, "SIZE $filename"); 
	$filesize = floatval(str_replace('213 ', '', $response[0]));
	return $filesize;
}
Таким образом, ответ: "да, парсить".
 

Вурдалак

Продвинутый новичок
Судя по всему, это проблема ftp_size() и по-хорошему неплохо было бы сообщить в багрепорт, если такая проблема наблюдается на 64-битной версии.
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Судя по всему, это проблема ftp_size() и по-хорошему неплохо было бы сообщить в багрепорт, если такая проблема наблюдается на 64-битной версии.
Тони же сказал, это документированная фича ;)
 
Сверху