Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблемы при работе с org.apache.commons.vfs, Не понимает что такое FTP сервер. 
V
    Опции темы
zone51
  Дата 29.1.2007, 00:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 370
Регистрация: 17.2.2006

Репутация: 1
Всего: 1



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

import org.apache.commons.vfs.*;
import org.apache.commons.logging.*;
import java.io.*;

class test{
public static void main(String[] args){
try{
FileSystemManager man=VFS.getManager();
FileObject f1=man.resolveFile("C:\\Dir2\\Dir");
FileObject f2=man.resolveFile("ftp://root:root@test/test");
f1.copyFrom(f2,Selectors.SELECT_ALL);
}
catch(FileSystemException e){
System.out.println("privet="+e.toString());
}
}
}



Есть сервер Small Http Server на котором по ходу виндовая фс.
Код выдает:
Код

C:\Documents and Settings\admin\My Documents\MyProjects\test>java test
Jan 28, 2007 11:26:18 PM org.apache.commons.vfs.VfsLog info
INFO: Using "C:\DOCUME~1\admin\LOCALS~1\Temp\vfs_cache" as temporary files store.
Exception in thread "main" org.apache.commons.net.ftp.parser.ParserInitializationException: Unknown parser type: WIN32 A N
        at org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory.createFileEntryParser(DefaultFTPFileEntryParserFa
tory.java:118)
        at org.apache.commons.net.ftp.FTPClient.initiateListParsing(FTPClient.java:2358)
        at org.apache.commons.net.ftp.FTPClient.listFiles(FTPClient.java:2141)
        at org.apache.commons.vfs.provider.ftp.FTPClientWrapper.listFiles(FTPClientWrapper.java:112)
        at org.apache.commons.vfs.provider.ftp.FtpFileObject.doGetChildren(FtpFileObject.java:123)
        at org.apache.commons.vfs.provider.ftp.FtpFileObject.getChildFile(FtpFileObject.java:103)
        at org.apache.commons.vfs.provider.ftp.FtpFileObject.getInfo(FtpFileObject.java:181)
        at org.apache.commons.vfs.provider.ftp.FtpFileObject.refresh(FtpFileObject.java:208)
        at org.apache.commons.vfs.provider.AbstractFileSystem.resolveFile(AbstractFileSystem.java:319)
        at org.apache.commons.vfs.provider.AbstractFileSystem.resolveFile(AbstractFileSystem.java:267)
        at org.apache.commons.vfs.provider.AbstractOriginatingFileProvider.findFile(AbstractOriginatingFileProvider.java:88)
        at org.apache.commons.vfs.provider.AbstractOriginatingFileProvider.findFile(AbstractOriginatingFileProvider.java:62)
        at org.apache.commons.vfs.impl.DefaultFileSystemManager.resolveFile(DefaultFileSystemManager.java:641)
        at org.apache.commons.vfs.impl.DefaultFileSystemManager.resolveFile(DefaultFileSystemManager.java:602)
        at org.apache.commons.vfs.impl.DefaultFileSystemManager.resolveFile(DefaultFileSystemManager.java:570)
        at test.main(test.java:13)


То есть не понимает виндовую фс. Тем не менее в FAQ написано:
Цитата

Q: On which server operating systems is FTPClient able to bring back a parsed listing? 

A: Currently parsers have been written for UNIX, Windows, OS/2, Netware, VMS and OS400. These can be autodetected by the code without being specified. Additionally, the code correctly handles cases where NT or OS400 servers have been configured to look like unix servers. There is also a means of specifying a user-written parser by class name. All of these parsers return FTPFile objects with as much information about the file as can be gathered from the listing. 

If none of these is sufficient, FTPClient.listNames() may always be called. This retrieves just the file name without other information.


Я не могу понять в чем косяк. Ну не может же такого быть чтоб не пахало. Значит трабл или с серваком или с самой vfs я имею ввиду билд. Я использую один из ночных билдов может они заточены под линь? Хотя смысла что то не вижу. smile  smile  smile 

зы. Извините за факический дубликат темы, но я близок к отчаянию. 
Спасибо всем кто откликнется. 


--------------------
The truth is out there
PM MAIL   Вверх
w1nd
Дата 29.1.2007, 16:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вертилятор
***


Профиль
Группа: Завсегдатай
Сообщений: 1077
Регистрация: 22.3.2006
Где: Москва

Репутация: 2
Всего: 54



Максимум, что сейчас пришло в голову - заменить класс org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory своим и для такого ключа ("WIN32 A N") конструировать org.apache.commons.net.ftp.parser.NTFTPEntryParser.

Вот еще вариант (непроверенный): получить корневой объект ftp-шной файловой системы (если, конечно, vfs сразу не полезет листить файлы), добраться с его помощью до FtpFileSystem, получить у той FTPClient и сказать ему setParserFactory() с нужной вам фабрикой.

Цитата(zone51 @  29.1.2007,  00:31 Найти цитируемый пост)
Я не могу понять в чем косяк.

Для "WIN32 N A" в ftp-клиенте просто нет парсеров. Есть только для "WINDOWS".

Это сообщение отредактировал(а) w1nd - 29.1.2007, 16:06


--------------------
user posted imageuser posted image
PM MAIL ICQ   Вверх
zone51
Дата 29.1.2007, 16:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 370
Регистрация: 17.2.2006

Репутация: 1
Всего: 1



w1nd, 
Цитата

заменить класс org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory своим и для такого ключа ("WIN32 A N") конструировать org.apache.commons.net.ftp.parser.NTFTPEntryParser.

Спасибо что ответили, а можно поподробнее как это сделать? Я имею ввиду
Цитата

и для такого ключа ("WIN32 A N") конструировать org.apache.commons.net.ftp.parser.NTFTPEntryParser.

Спасибо.


--------------------
The truth is out there
PM MAIL   Вверх
LSD
Дата 29.1.2007, 18:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 19
Всего: 538



Попробуй так:
Код
FileSystemManager systemManager = VFS.getManager();
FileSystemOptions fileSystemOptions = new FileSystemOptions();
FtpFileProvider ftpFileProvider = new FtpFileProvider();
FtpFileSystemConfigBuilder ftpFileSystemConfigBuilder = (FtpFileSystemConfigBuilder) ftpFileProvider.getConfigBuilder();
FTPFileEntryParserFactory parserFactory = new FTPFileEntryParserFactory()
{
  public FTPFileEntryParser createFileEntryParser(String key) throws ParserInitializationException
  {
    return new NTFTPEntryParser();
  }

  public FTPFileEntryParser createFileEntryParser(FTPClientConfig config) throws ParserInitializationException
  {
    return new NTFTPEntryParser();
  }
};
ftpFileSystemConfigBuilder.setEntryParserFactory(fileSystemOptions, parserFactory);



--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
w1nd
Дата 29.1.2007, 18:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вертилятор
***


Профиль
Группа: Завсегдатай
Сообщений: 1077
Регистрация: 22.3.2006
Где: Москва

Репутация: 2
Всего: 54



..

Это сообщение отредактировал(а) w1nd - 29.1.2007, 18:35


--------------------
user posted imageuser posted image
PM MAIL ICQ   Вверх
zone51
  Дата 29.1.2007, 18:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 370
Регистрация: 17.2.2006

Репутация: 1
Всего: 1



LSD, 
Код

try{

FileSystemManager man=VFS.getManager();
FileSystemManager systemManager = VFS.getManager();
FileSystemOptions fileSystemOptions = new FileSystemOptions();
FtpFileProvider ftpFileProvider = new FtpFileProvider();
FtpFileSystemConfigBuilder ftpFileSystemConfigBuilder = (FtpFileSystemConfigBuilder) ftpFileProvider.getConfigBuilder();
org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory parserFactory = new org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory()
{
  public FTPFileEntryParser createFileEntryParser(String key) throws org.apache.commons.net.ftp.parser.ParserInitializationException
  {
    return new org.apache.commons.net.ftp.parser.NTFTPEntryParser();
  }

  public FTPFileEntryParser createFileEntryParser(FTPClientConfig config) throws org.apache.commons.net.ftp.parser.ParserInitializationException
  {
    return new org.apache.commons.net.ftp.parser.NTFTPEntryParser();
  }
};
ftpFileSystemConfigBuilder.setEntryParserFactory(fileSystemOptions, parserFactory);
FileObject f1=man.resolveFile("C:\\Dir2\\Dir");
FileObject f2=man.resolveFile("ftp://root:root@test/test");
f1.copyFrom(f2,Selectors.SELECT_ALL);

}
catch(FileSystemException e){

System.out.println("privet="+e.toString());

}


Спасибо.
Ошибка совершенно та же самая.  smile  smile  smile

Добавлено @ 18:52 
Кстати хочу заметить
код
Код

FTPClient ftp=new FTPClient();
ftp.connect(host);
ftp.login(login,pwd);
//some code   
engine = ftp.initiateListParsing("org.apache.commons.net.ftp.parser.UnixFTPEntryParser",".");


Работает нормально
а вот без строчки
Код

engine = ftp.initiateListParsing("org.apache.commons.net.ftp.parser.UnixFTPEntryParser",".");


Выдает аналогичную ошибку. Это я еще когда делал на commons.net 
Может это вам как то поможет. Спасибо.
 smile  smile  smile 

Это сообщение отредактировал(а) zone51 - 29.1.2007, 18:57


--------------------
The truth is out there
PM MAIL   Вверх
w1nd
Дата 29.1.2007, 22:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вертилятор
***


Профиль
Группа: Завсегдатай
Сообщений: 1077
Регистрация: 22.3.2006
Где: Москва

Репутация: 2
Всего: 54



В принципе, есть вполне "законный" способ указать EntryParser или EntryParserFactory:
Код
FileSystemOptions opts = new FileSystemOptions();
...
FtpFileSystemConfigBuilder.getInstance().setEntryParser(opts, ...)
или
Код
FileSystemOptions opts = new FileSystemOptions();
...
FtpFileSystemConfigBuilder.getInstance().setEntryParserFactory(opts, ...)

И всё было бы хорошо, если бы ftp-шный провайдер эти установки не игнорировал smile 

Опять же, вполне "законным" способом можно подменить FtpFileProvider, но для этого придется делать свои версии практически половины его классов.

Это сообщение отредактировал(а) w1nd - 29.1.2007, 23:59


--------------------
user posted imageuser posted image
PM MAIL ICQ   Вверх
zone51
Дата 29.1.2007, 23:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 370
Регистрация: 17.2.2006

Репутация: 1
Всего: 1



w1nd, 
Спасибо, попробовал-та же ботва  smile  smile  smile 


--------------------
The truth is out there
PM MAIL   Вверх
zone51
  Дата 30.1.2007, 02:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 370
Регистрация: 17.2.2006

Репутация: 1
Всего: 1



Взаимодействие org.apache.commons.vfs и некоторых FTP серверов
Внимание! В данной заметке приведено решение наболевшей  одно время проблемы.
Все FTP сервера, функционирующие в сетях или Интернет делятся на несколько типов в зависимости от типа файловой системы их жестких дисков. Такое разделение связано с типом операционной системы которая установлена на сервере. У операционных систем разных семейств  разные подходы к представлению данных на диске. Например в операционных системах семейства Unix разделительной чертой(сепаратором), с помощью которой формируются пути к файлам на диске является символ "/",
в Windows наоборот - "\". Поэтому клиент который обращается к фтп серверу должен знать какого типа  ФС сервера чтобы знать как правильно искать файлы, и передавать из пользователю.  Большинство серверов имеют тип файловой системы  Unix, многие сервера имеют тип файловой системы Windows есть также сервера со специфическими свойствами, касающимися взаимодействий с различными FTP клиентами. Чтобы клиент мог понять с каким сервером он имеет дело, сервер дает клиенту некоторые сведения о себе. Среди прочей информации сервер передает клиенту описание своей файловой системы. Если это Unix ФС то этим описанием будет что то вроде "UnixFS" или еще что то. Для серверов с ФС Windows этим описанием будет строка "WINDOWS" или что то в этом роде.
Чтобы правильно распознавать ФС и работать с файлами на ней существуют специальные средства-парсеры (англ. parse-анализ, разбор). Они отвечают за "понимание" файловой системы сервера и работу с ней. В пакете org.apache.commons.net, без которого не может работать org.apache.commons.vfs, и который отвечает за работу с сетевыми ресурсами, запрограммированы парсеры под самые распространенные типы файловых систем. Но как оказалось не под все.  
Файловая система с опианием Win32 A N оказалась "непонятной"  для пакета. А следовательно для этой ФС неприменим ни org.apache.commons.vfs. ни org.apache.commons.net. Что делать?
Рассмотрим пример.

Задача: скопировать папку с FTP сервера на локальный диск но с помощью org.apache.commons.vfs так как на мой взгляд это элегантное и функциональное решение.
FTP Сервер: Small HTTP Server. Я использую его для тестирования многие годы. Ничего лучше я пока не видел.
FTP Клиент: Простое консольное Java приложение. Его исходный код:
Код

import org.apache.commons.vfs.*;
import org.apache.commons.logging.*;
import java.io.*;
class test{
public static void main(String[] args){
try{
FileSystemManager man=VFS.getManager();
FileObject f1=man.resolveFile("C:\\Dir2\\Dir");
FileObject f2=man.resolveFile("ftp://root:root@test/test");
f1.copyFrom(f2,Selectors.SELECT_ALL);
}
catch(FileSystemException e){
System.out.println("privet="+e.toString());
}
}
}

При попытке запустить этот код возникает ошибка:
Код

Exception in thread "main" org.apache.commons.net.ftp.parser.ParserInitializationException: Unknown parser type: WIN32 A N
        at org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory.createFileEntryParser(DefaultFTPFileEntryParserFa
tory.java:118)
        at org.apache.commons.net.ftp.FTPClient.initiateListParsing(FTPClient.java:2358)
        at org.apache.commons.net.ftp.FTPClient.listFiles(FTPClient.java:2141)
        at org.apache.commons.vfs.provider.ftp.FTPClientWrapper.listFiles(FTPClientWrapper.java:112)
        at org.apache.commons.vfs.provider.ftp.FtpFileObject.doGetChildren(FtpFileObject.java:123)
        at org.apache.commons.vfs.provider.ftp.FtpFileObject.getChildFile(FtpFileObject.java:103)
        at org.apache.commons.vfs.provider.ftp.FtpFileObject.getInfo(FtpFileObject.java:181)
        at org.apache.commons.vfs.provider.ftp.FtpFileObject.refresh(FtpFileObject.java:208)
        at org.apache.commons.vfs.provider.AbstractFileSystem.resolveFile(AbstractFileSystem.java:319)
        at org.apache.commons.vfs.provider.AbstractFileSystem.resolveFile(AbstractFileSystem.java:267)
        at org.apache.commons.vfs.provider.AbstractOriginatingFileProvider.findFile(AbstractOriginatingFileProvider.java:88)
        at org.apache.commons.vfs.provider.AbstractOriginatingFileProvider.findFile(AbstractOriginatingFileProvider.java:62)
        at org.apache.commons.vfs.impl.DefaultFileSystemManager.resolveFile(DefaultFileSystemManager.java:641)
        at org.apache.commons.vfs.impl.DefaultFileSystemManager.resolveFile(DefaultFileSystemManager.java:602)
        at org.apache.commons.vfs.impl.DefaultFileSystemManager.resolveFile(DefaultFileSystemManager.java:570)
        at test.main(test.java:13)


Ключевая фраза в последнем фрагменте:
Цитата

Unknown parser type: WIN32 A N


Решение:

1) У нас есть сырцы org.apache.commons.net
2)Скачиваем распаковываем, берем оттуда файл DefaultFTPFileEntryParserFactory.java
3)Открываем и правим: находим строку 
Код

else if (ukey.indexOf(FTPClientConfig.SYST_NT) >= 0)

меняем ее на
Код

else if (ukey.indexOf(FTPClientConfig.SYST_NT) >= 0 || ukey.indexOf("WIN32 A N") >= 0) 

4)Компилируем класс 
5)У нас есть бинарник org.apache.commons.net, распаковываем, заходим в jar архив, и соответственно меняем класс DefaultFTPFileEntryParserFactory.class на аналогичный только что скомпиленный. 
6) Выходим из jar архива, кидаем его в  CLASSPATH, все как обычно.
Готово. Теперь наш пакет понимает сервера с файловой системой обозначаемой WIN32 A N и код прекрасно работает с прекрасным Small Http Server `ом. Это было описание того что проделано для понимания. Если же кто то не хочет возиться с переделыванием, можно взять готовый  jar архив Здесь

Автор статьи: ZONE51

Благодарности: W1nd, который собственно и является автором идеи.

зы. Прошу модератора поместить статью в раздел FAQ и перезалить с рапиды на форум модифицированный архив 




--------------------
The truth is out there
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Работа с сетью | Следующая тема »


 




[ Время генерации скрипта: 0.0556 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.