Скачать каталог через HTTP в Java

У меня есть несколько файлов в дереве каталогов, которые обслуживаются через HTTP. Учитывая некоторый подкаталог A, в этом дереве каталогов я хочу иметь возможность загружать каталог A и все содержащие подкаталоги и файлы.

Кажется вероятным, что простое/прямое/атомарное решение существует в каком-то темном уголке Java. Кто-нибудь знает как это сделать?

Веб-краулер не решит мою проблему, поскольку файлы в подкаталогах могут ссылаться на каталоги, которые не являются подкаталогами.

==Обновление==

Каталоги и файлы должны размещаться статически.

Сервер статически размещает файлы в дереве каталогов, клиент запускает Java и пытается скопировать некоторую ветвь дерева каталогов с помощью HTTP.

VFS является ответом на этот вопрос, к сожалению, я сам ответил на вопрос и поэтому могу' я не выберу его в качестве ответа до истечения двух дней. Если кто-то напишет мой ответ, я буду рад отметить его запись как ответ.

== Дальнейшее обновление ==

VFS на самом деле не является ответом. VFS не будет отображать каталоги через HTTP, как указано здесь. Кажется, есть несколько человек, которые заинтересованы в этой функции.


person Ethan Heilman    schedule 12.11.2009    source источник


Ответы (7)


Предполагая, что у вас есть контроль как над сервером, так и над клиентом, я бы написал страницу (в вашей любимой технологии по вашему выбору: ASP, JSP, PHP и т. д.), которая читает структуру каталогов сервера и динамически возвращает страницу, состоящую из группы ссылок на каждый файл для скачивания.

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

Что такое клиентская технология? дело в загрузке какого-то приложения или веб-браузера? Должен ли он иметь клиентский интерфейс?


Если это какая-то внутренняя служебная программа, может быть, вместо этого вы можете использовать FTP? Открыть FTP-доступ на сервере и загрузить каталог было бы легко...


Добавление другого возможного ответа:

Если на сервере не включены списки каталогов, то вам в основном нужно внести изменения на стороне сервера. Проще всего было бы просто создать страницу, которая возвращает структуру dir клиенту в известном формате (см. мой 1-й ответ выше).

Если вы управляете сервером и у вас включены списки каталогов, и вы всегда используете одну и ту же серверную программу (IIS, Tomcat, JBoss и т. д.), вы можете просто заставить клиент сканировать списки каталогов . Например, в списке каталогов из IIS вы можете определить, какие ссылки являются каталогами, а какие файлами, потому что он всегда ставит «/» в конце ссылки на каталог и показывает «каталог» вместо размера файла:

 Friday, October 16, 2009 03:55 PM        &lt;dir&gt; <A href="Unity/">Unity</A>
 Thursday, July 02, 2009 10:42 AM           95 <A href="Global.asax">Global.asax</A>

Здесь вы можете сказать, что 1-я ссылка — это каталог, а 2-я — фактический файл.

Поэтому, если вы используете согласованное серверное приложение, просто посмотрите, как возвращается список каталогов. Может быть, вам повезет.

person CodingWithSpike    schedule 12.11.2009
comment
Ftp решил бы проблему, но, к сожалению, многие корпоративные файловые стены блокируют ftp. - person Ethan Heilman; 12.11.2009
comment
что-то не так с моим 1-м предложением? или вы просто пытаетесь избежать написания кода? Создание страницы ASP, JSP или PHP, которая возвращает структуру файловой системы в известном формате, вероятно, займет меньше времени, чем на размещение этого вопроса и мониторинг ответов... Что такое веб-сервер? это ВСЕГДА одно и то же? или вы пытаетесь просто подключиться к любому случайному серверу, который может быть там, что бы это ни было? (вы контролируете сервер) - person CodingWithSpike; 13.11.2009
comment
Конечно, если изменить параметры вопроса, вопрос становится очень простым, но вопрос предполагает, что на сервере не выполняется код. Я управляю сервером в том смысле, что могу загружать и скачивать, но я пытаюсь делать все на клиенте. Я надеялся, что эта проблема в целом решена. - person Ethan Heilman; 13.11.2009

Моим первым предложением было бы создать сервлет/jsp, который рекурсивно считывает структуру каталогов (используя java.io.File), читает все файлы, помещает их в один zip (java.util.zip) и отправляет их в браузеры для скачать.

person Bozho    schedule 12.11.2009
comment
Файлы слишком велики, чтобы заархивировать их для каждого запроса. Мы хотим размещать файлы статически. - person Ethan Heilman; 12.11.2009
comment
Затем вы можете создать .jsp, представляющий структуру каталогов, и предлагать файлы для загрузки один за другим. снова используя java.io.File рекурсивно - person Bozho; 12.11.2009
comment
Вы по-прежнему предполагаете, что на сервере работает java, эти файлы размещаются полностью статически. - person Ethan Heilman; 12.11.2009
comment
ну, на сервере работает Java, потому что вы сказали это в своем вопросе. Это можно сделать с помощью любой серверной технологии. Вы можете прочитать ЛЮБУЮ директорию на сервере из Java-сервлета. Просто передайте путь как параметр post/get или используйте / по умолчанию. затем новый файл (путь) и рекурсия. - person Bozho; 12.11.2009
comment
где в вопросе я сказал, что на сервере работает Java? Клиент запускает Java, но не сервер. - person Ethan Heilman; 12.11.2009
comment
ну так и предполагалось. В любом случае, в этом случае вы можете использовать apache-commons HttpClient и просмотреть список файлов Apache. (Я думаю, сервер по крайней мере использует Apache?) - person Bozho; 12.11.2009
comment
@Bozho apache-commons не означает, что его нужно запускать против apache. Например, iis также поддерживает это. - person Ethan Heilman; 12.11.2009
comment
ха, да, тут совпадение. Подойдет любой http-сервер, предоставляющий листинг. - person Bozho; 12.11.2009

Я не знаю атомарного решения, но самым простым из них было бы использование URLConnection для извлечения подкаталога (при условии, что сервер перечисляет каталог), а затем анализировать ответ, искать содержимое этого каталога и снова использовать URLConnection чтобы получить каждый из файлов под ним.

Основываясь на этих ответах, теперь мне интересно, имели ли вы в виду, что Java находится на стороне клиента или на стороне сервера!

person Murali VP    schedule 12.11.2009
comment
+1, вы правильно понимаете мой вопрос. Ваш ответ - это то, чего я пытаюсь избежать, поскольку я предполагаю, что для этого уже существуют некоторые библиотеки. - person Ethan Heilman; 12.11.2009
comment
спасибо за уточнение, я сомневаюсь, что он существует, поскольку это не похоже на очень распространенную потребность, но, конечно, я могу ошибаться - person Murali VP; 12.11.2009

Итак, вы хотите со стороны клиента получить список всех файлов и каталогов для определенного URL-адреса на стороне сервера, как если бы это была папка файловой системы локального диска? Обычно это невозможно, если на сервере не включено индексирование каталогов. И даже в этом случае вам все равно нужно проанализировать HTML-страницу, которая представляет индекс каталога, и самостоятельно проанализировать все элементы <a>, представляющие файлы и папки. Для этого нет нормального java.io.File подхода. Это было бы огромной дырой в безопасности. Например, можно загрузить все исходные файлы с http://gmail.com. HTTP не предназначен для протокола передачи файлов. Используйте FTP. Вот где это означает.

person BalusC    schedule 12.11.2009
comment
+1 за указание на то, что индексирование должно быть включено. Мы отключаем их здесь, за очень немногими исключениями. - person Andy Gherna; 12.11.2009
comment
Зачем разрешать подход java.io.File, связанный с наличием дыры в безопасности? - person Ethan Heilman; 12.11.2009
comment
Многие люди используют http для обслуживания файлов, поскольку многие компании блокируют как входящие, так и исходящие ftp-соединения. Можно подумать, что я не первый, кто с этим столкнулся. - person Ethan Heilman; 12.11.2009
comment
@ e5: если бы это было возможно, вы могли бы запросить все из веб-контента, включая защищенные файлы, файлы в WEB-INF и так далее. В любом случае лучшим способом для этого будет FTP, а не HTTP. - person BalusC; 12.11.2009

Если я не ошибаюсь, HTTP ничего не говорит вам о «структуре» серверной части — если такая вещь вообще существует.

Подумайте о REST, где URI на самом деле не говорит вам, где найти файл на сервере, а может просто вызвать какое-то действие, получить данные или тому подобное.

Поэтому я не думаю, что то, чего вы пытаетесь достичь, можно сделать надежно, будь то Java или любой другой язык. Или, может быть, я неправильно понимаю вас здесь?

person Daniel Schneller    schedule 12.11.2009
comment
Большинство веб-серверов сообщат вам структуру каталогов. Они создают простую html-страницу, содержащую файлы и каталоги, если для этого каталога не существует index.html. - person Ethan Heilman; 12.11.2009

Разговор о низко висящих фруктах ;-) Спасибо за предложение, e5!

Commons VFS предоставляет единый API для доступа к различным файловым системам. Он представляет собой единый вид файлов из разных источников, таких как файлы на локальном диске, на HTTP-сервере или внутри Zip-архива.

http://commons.apache.org/vfs/

person Benjamin Cox    schedule 12.11.2009

Впервые за долгое время Google превзошел stackoverflow, Apache commons VFS делает именно то, что мне нужно.

Commons VFS предоставляет единый API для доступа к различным файловым системам. Он представляет собой единый вид файлов из разных источников, таких как файлы на локальном диске, на HTTP-сервере или внутри Zip-архива.

http://commons.apache.org/vfs/

==Обновление==

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

person Ethan Heilman    schedule 12.11.2009
comment
Ну, на мой взгляд, последовательность должна быть такой - 1. попробуйте погуглить 10 минут, 2. попросите помощи у других. Наоборот, немного эгоистично :) - person Bozho; 12.11.2009
comment
@Божо Я какое-то время гуглил, ничего не нашел, потом вспомнил, что apache-commons всегда является ответом. Погуглил мои предыдущие запросы с добавленным словом apache-commons и нашел VFS. - person Ethan Heilman; 12.11.2009