Как сделать прогресс загрузки файла

Обновлено: 08.07.2024

PHP может отслеживать прогресс загрузки отдельных файлов при включенной опции session.upload_progress.enabled. Данная информация не особенно полезна для запроса, непосредственно закачивающего файл, однако, в течение данной загрузки приложение может посылать POST-запросы на отдельную страницу (например, с помощью XHR ) для проверки статуса.

Прогресс закачки будет доступен в суперглобальной переменной $_SESSION в процессе закачки, а также при отправке POST-запросом переменной с именем равным значению опции session.upload_progress.name. Как только PHP обнаружит такой POST-запрос, он создаст массив в $_SESSION , ключом которого будет конкатенация значений опций session.upload_progress.prefix и session.upload_progress.name. Ключ обычно можно получить прочитав эти опции, т.е.:

= ini_get ( "session.upload_progress.prefix" ) . $_POST [ ini_get ( "session.upload_progress.name" )];
var_dump ( $_SESSION [ $key ]);
?>

Также возможно отменить загружаемый в данный момент файл, установив ключ $_SESSION[$key]["cancel_upload"] в значение TRUE . При загрузке нескольких файлов за один раз, это действие отменит только текущий загружаемый файл и все следующие за ним, но не удалит уже успешно загруженные к этому времени файлы. Если закачка была отменена этим способом, то элемент с ключом error в массиве $_FILES будет установлен в UPLOAD_ERR_EXTENSION .

Опции session.upload_progress.freq и session.upload_progress.min_freq контролируют частоту обновления информации о прогрессе загрузки. При разумных значениях этих двух настроек, накладные расходы данной функции практически неощутимы.

Пример структуры массива прогресса загрузки.

Данные в сессии будут выглядеть примерно так:

[ "upload_progress_123" ] = array(
"start_time" => 1234567890 , // Время начала запроса
"content_length" => 57343257 , // Длина содержимого POST
"bytes_processed" => 453489 , // Количество полученных и обработанных байт
"done" => false , // true при завершении обработки POST, успешно или нет
"files" => array(
0 => array(
"field_name" => "file1" , // Имя поля
// Следующие 3 элемента аналогичны соответствующим элементам массива $_FILES
"name" => "foo.avi" ,
"tmp_name" => "/tmp/phpxxxxxx" ,
"error" => 0 ,
"done" => true , // True, если обработчик POST закончил обработку данного файла
"start_time" => 1234567890 , // Время начала обработки этого файла
"bytes_processed" => 57343250 , // Число полученных и обработанных байт этого файла
),
// И еще один файл, загрузка которого еще не закончена в том же запросе
1 => array(
"field_name" => "file2" ,
"name" => "bar.avi" ,
"tmp_name" => NULL ,
"error" => 0 ,
"done" => false ,
"start_time" => 1234567899 ,
"bytes_processed" => 54554 ,
),
)
);

Для успешной работы данной функции необходимо отключить буферизацию запроса web-сервером. Иначе PHP увидит загрузку файла только когда загрузка полностью завершится. Серверы, такие как например Nginx, буферизуют большие запросы.

В этой статье мы рассмотрим решение одной из самых распространенных задач – асинхронная загрузка файла на сервер и отображение процесса выполнения. Наш сценарий будет загружать картинки на сервер, показывать индикатор выполнения и затем отображать загруженную картинку. В некоторых случаях вам может потребоваться вернуть идентификатор загруженного вами файла или сделать что-то еще с файлом на бэкенде, например сохранить в базу данных и т.п. В этой статье основной упор сделаем на фронтенд – т.е. реализацию асинхронной загрузки на клиенте.

Добавьте в папку Controllers класс контроллера HomeController.cs со следующим содержимым (напомню, контроллер Home используется по умолчанию в настройках маршрутизации проекта – файл /App_Start/RouteConfig.cs):

Щелкните правой кнопкой мыши по методу Index и выберите в контекстном меню команду Add View. Visual Studio создаст файл представления /Views/Home/index.cshtml, а также компоновку по умолчанию /Views/Shared/_Layout.cshtml. Давайте подключим библиотеку jQuery в файле компоновки:

Здесь мы также добавили сброс стилей CSS для браузера и подключили таблицу стилей /Content/Site.css. Добавьте также файл script.js в папку scripts. Давайте теперь добавим форму для загрузки файлов в проект. Для этого откройте представление Index.cshtml и используйте следующую разметку:

В элементе section находится форма со вставкой загружаемых файлов. Файлы можно поместить в этот контейнер путем перетаскивания (drag-and-drop), либо через диалоговое окно после щелчка по элементу section. Элемент progress будет содержать индикатор загрузки файлов, в элементе error будут отображаться ошибки, а контейнер images нужен для отображения сохраненных на сервере картинок.

Теперь нам нужно добавить CSS-стили для страницы. Для этого отредактируйте файл /Content/Site.css следующим образом:

На данный момент форма выглядит следующим образом:

Тестовая форма для асинхронной загрузки файлов

Теперь нам нужно добавить скрипт, который должен обеспечивать следующий функционал:

При клике по элементу section должно открываться модальное окно с выбором файла.

При перетаскивании файлов из проводника в окно браузера, элемент section должен подсвечиваться как при наведении курсора мыши (для этого мы добавили CSS-класс «dd&raqio;). При отпускании файлов (как и при выборе файла из диалогового окна) должна происходить загрузка картинок на сервер.

При загрузке файлов необходимо добавить индикатор и отобразить процент выполнения загрузки.

В случае ошибки на сервере, необходимо отобразить ошибки и скрыть индикатор.

В случае успешной загрузки картинок на сервер, необходимо отобразить их в контейнере images.

Следующий скрипт (файл script.js) решает все вышеуказанные вопросы:

Для сохранения списка файлов и передачи его на сервер через Ajax используется объект FormData.

Обратите внимание, что за отслеживание процесса загрузки отвечает свойство xhrFields объекта, передаваемого методу $.ajax. В этом свойстве хранится объект с функцией обработки события onprogress. Этому событию передается объект со свойствами loaded – объем уже загруженных данных, и total – общий размер данных. Благодаря этим двум параметрам мы можем отображать процесс выполнения загрузки на индикаторе.

В методе $.ajax() мы ссылаемся на метод действия Upload контроллера HomeController, который еще не был добавлен. Давайте исправим это и отредактируем файл HomeController.cs:

Перед тестированием данного примера не забудьте добавить в корень проекта папку uploads.

Я пытаюсь написать простое приложение, которое обновляется. Для этого мне нужна простая функция, которая может загрузить файл и показать текущий на ProgressDialog . Я знаю, как сделать ProgressDialog , но я не уверен, как отображать текущий прогресс и как загрузить файл в первую очередь.

существует много способов загрузки файлов. После я опубликую наиболее распространенные способы; вам решать, какой метод лучше для вашего приложения.

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

это пример кода:

на AsyncTask будет выглядеть это:

метод выше ( doInBackground ) всегда выполняется в фоновом потоке. Вы не должны делать никаких задач UI там. С другой стороны, onProgressUpdate и onPreExecute запустите в потоке пользовательского интерфейса, чтобы вы могли изменить индикатор выполнения:

для этого, чтобы запустить, вам нужно разрешение WAKE_LOCK.

большой вопрос здесь: как обновить свою деятельность с обслуживания?. В в следующем примере мы будем использовать два класса, о которых вы можете не знать: ResultReceiver и IntentService . ResultReceiver это тот, который позволит нам обновить наш поток из службы; IntentService является наследником Service который порождает поток, чтобы сделать фоновую работу оттуда (вы должны знать, что Service работает фактически в том же потоке вашего приложения; когда вы расширяете Service , вы должны вручную создавать новые потоки для запуска операций блокировки процессора).

сервис загрузки может выглядеть это:

добавьте службу в свой манифест:

и активность будет выглядеть так:

здесь были ResultReceiver доходит до игры:

2.1 используйте библиотеку Groundy

Groundy - это библиотека, которая в основном помогает вам запускать фрагменты кода в фоновой службе, и она основана на ResultReceiver концепция, показанная выше. Эта библиотека устаревший на данный момент. Вот как весь код будет выглядеть так:

действие, в котором отображается диалоговое окно.

A GroundyTask реализации используется Groundy загрузить файл и показать прогресс:

и просто добавьте это в манифест:

это не может быть проще, я думаю. Просто возьмите последнюю банку из Github и вы готовы идти. Имейте в виду, что Groundyосновная цель состоит в том, чтобы совершать вызовы внешних REST API в фоновой службе и легко отправлять результаты в пользовательский интерфейс. Если вы делаете что-то подобное в вашем приложении, это может быть очень полезно.

пряники принесли новую функцию, DownloadManager , что позволяет скачать файлы легко и делегировать тяжелую работу обрабатывать потоки, ручьи и т. д. к системе.

во-первых, давайте посмотрим служебный метод:

имя метода объясняет все это. После того, как вы уверены DownloadManager есть в наличии, вы можете сделать что-то вроде этого:

прогресс загрузки будет отображаться на панели уведомлений.

первый и второй методы - это только верхушка айсберга. Есть много вещи, которые вы должны иметь в виду, если вы хотите, чтобы ваше приложение было надежным. Вот краткий список:

  • вы должны проверить, есть ли у пользователя подключение к интернету
  • убедитесь, что у вас есть права доступа ( INTERNET и WRITE_EXTERNAL_STORAGE ); и ACCESS_NETWORK_STATE если вы хотите проверить наличие интернета.
  • убедитесь, что каталог, в котором вы собираетесь загружать файлы, существует и имеет разрешения на запись.
  • если загрузка слишком велика, вы можете хотите реализовать способ возобновления загрузки, Если предыдущие попытки не удались.
  • пользователи будут благодарны, если вы позволите им прервать загрузку.

Если вам не нужен подробный контроль над процессом загрузки, то рассмотрите возможность использования DownloadManager (3), потому что он уже обрабатывает большинство пунктов, перечисленных выше.

этот класс устарел на уровне API 26. ProgressDialog является модальным диалог, который запрещает пользователю взаимодействовать с приложением. Вместо для использования этого класса необходимо использовать progress индикатор типа ProgressBar, который может быть встроен в пользовательский интерфейс вашего приложения. Альтернативно, уведомление можно использовать для информирования пользователя о ходе выполнения задачи. Для более подробной информации ссылке

Не забудьте добавить разрешения в файл манифеста, если вы будете скачивать материал из интернета!

Важное заявление: Поскольку класс, предоставленный версией QT5.4, очень велик, обратитесь к читателю этой статьи, чтобы обеспечитьВаша собственная версия Qt> = 5.4Отказ Класс, который мы в основном использовалиQNetWorkAccessManagerОт версии 5.4.

  • Отличается от FTP.
  • 2. Интерфейс UI
  • 3. Изменить файл .pro
  • 4. Код файла головки
  • 5. Исходный код файла (загрузка, загрузка, панель прогресса)
  • 6. Код сценария PHP

Отличается от FTP.

Нет проблем с интрасети и внешней сетью, но код немного сложно, чем FTP.


2. Интерфейс UI

Интерфейс UI этой программы выглядит следующим образом:


3. Изменить файл .pro

Во-первых, для того, чтобы использовать класс по отношению к сети, мы должны сначала присоединиться к строке в файле .pro:QT += network:

4. Код файла головки

4. Исходный код файла

6. Код сценария PHP

  • 2) сценарии PHP, написанные в этом каталоге на сервер

Читайте также: