#Протокол передачи мультимедиа и › передача файлов размером 4 ГБ

Передача больших файлов по протоколу передачи мультимедиа (MTP) очень загадочна. Наиболее распространенные результаты поиска касаются пользователей Android, испытывающих трудности с передачей больших файлов, и, хотя это не имеет ничего общего с самой спецификацией MTP, а больше связано с в значительной степени несовершенной реализацией Android MTP, MTP обычно вызывает гнев пользователей. Я считаю, что часть стигмы, связанной с MTP, связана с тем, что Microsoft сыграла важную роль в его создании. Есть и другие, например, название могло бы быть и получше! (Человек, по-видимому, эксперт по хранению, на самом деле не знал, что протокол передачи мультимедиа, хотя и ориентирован на медиафайлы, на самом деле может обрабатывать и другие типы файлов!). О том, почему Android решил использовать MTP в качестве файловой системы по умолчанию, мы можем рассказать в другом посте, а пока давайте вернемся к любопытному случаю с большими файлами.

В спецификации MTP не помешало бы внести ясность в раздел, посвященный записи больших файлов. Основная проблема с записью заключается в том, что метаданные объекта MTP используют 32-битное целое число без знака для размера файла, что ограничивает размер файла. В спецификации упоминается, что для размера файла > 4 ГБ размер должен быть установлен равным 0xFFFFFFFF. Однако в нем четко не указано, как управлять самой передачей (когда и как ее остановить!).

Итак, можете ли вы передать файл размером 4 ГБ с помощью MTP? Да, вы можете, и есть два способа реализовать это. Первый — использовать ObjectPropList, в частности, поддерживать SendObjectPropList. Эта операция имеет 8-байтовое поле для размера объекта. Однако многие инициаторы могут не поддерживать ObjectPropLists, и даже если они поддерживаются, инициаторы могут решить не использовать их для поддержки записи.

Второй метод в основном зависит от транспортного механизма, на который в основном полагается MTP, USB. Вероятно, это даже делает поле размера файла в метаданных объекта необязательным элементом. USB гарантирует, что конец фазы данных будет отмечен так называемым коротким пакетом. Короткий пакет — это пакет данных, размер которого меньше, чем wMaxPacketSize, указанный дескриптором конечной точки, т. е. размер буфера данных в конечной точке. Фрагмент для обработки операции записи в ответчике может выглядеть примерно так:

total_size += incoming_datasize; if (incoming_datasize < wMaxPacketSize) { /* This is the last packet in this data phase */ write_buffer_to_file(); free_buffer(); }

Однако здесь есть небольшая заминка. Как правило, контроллеры USB пытаются заполнить свой буфер перед отправкой данных. Таким образом, приведенное выше «условие if» может стать истинным еще до фактического окончания фазы данных и отметить неверный конец фазы данных. Исправить это несложно и зависит от того факта, что размер входящих данных будет кратен 64, если только это не конец фазы данных:

total_size += incoming_datasize; if ((incoming_datasize % 64) != 0) { /* This is the last packet in this data phase */ write_buffer_to_file(); free_buffer(); } #техника #программирование #qemu #mtp