Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Блоги > The way of improve

Буду выкладывать наработки в народ
Оценить эту запись

Поиск файлов в системе.[AIR]

Запись от Genzo размещена 23.12.2011 в 15:15
Обновил(-а) Genzo 23.12.2011 в 17:57

Появилась задача :
Найти все фотографии пользователя на мобильнике
Решение :
Код AS3:
var fileFinder:FileSearcher = new FileSearcher(File.documentsDirectory , ["jpeg","jpg","png"]);
fileFinder.find();
var images:Vector.<File> = fileFinder.result;
Написал класс FileSearcher.
Возможности :
Синхронный и асинхронный поиск
Пока все сыро, приму любые комментарии

Исходный код :
FileSearcher.as
Код AS3:
package ru.air.gmobile.files
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.FileListEvent;
	import flash.filesystem.File;
	/**
	 *  FileSearcher is class to search files in directory and its sub-direcrories;
	 * 	@author Dmitry Petrov
	 *  @download http://www.genzo-dev.ru/as3/FileSearcher.rar
	 *  @langversion 3.0
	 *  @playerversion AIR 1.0
	 *  @version 1.0a
	 **/	
	public class FileSearcher extends EventDispatcher
	{
		public static const MODE_SYNC:String = "modeSync";
		public static const MODE_ASYNC:String = "modeAsync";
 
 
		private var foundedFiles:Vector.<File> = new Vector.<File>;
 
		private var proceedDirs:Array = new Array();
		private var proceedFiles:Array = new Array();
 
		private var _rootDir:File;
		private var _extensions:Object;
		private var _mode:String;
		private var _searchHidden:Boolean;
 
		private var _found:Boolean;
 
		/**
		 * 
		 * @param rootDir:File Root Directory
		 * @param fileTypes:Array Array of file types (File.extension), eg : ["jpg","jpeg","png"]
		 * @param mode:String Serach mode : FileSearcher.MODE_SYNC || FileSearcher.MODE_ASYNC
		 * @param searchHidden:Boolean Look for hidden files or skip them
		 * 
		 */
		public function FileSearcher(rootDir:File , fileTypes:Array , mode:String = MODE_SYNC , searchHidden:Boolean = false)
		{
			this._extensions = new Object();
			for each(var i:String in fileTypes)
			{
				this._extensions[i] = true;
			}
			this._mode = mode;
			this._searchHidden = searchHidden;
			this._rootDir = rootDir;			
		}
		/**
		 * Start searching , don't forget to add listener for FileSearcherEvent.COMPLETE (and optional FileSearcherEvent.PROGRESS) if mode == ASYNC
		 * @throws ArgumentError - unknow mode
		 */		
		public function find():void
		{
			listing(this._rootDir);
		}
 
		private var searching:Boolean = false;
		protected function proceed():void
		{
			if(searching == true) return;
			searching = true;
			while(searching != false)
			{				
				var file:File = this.proceedFiles.pop();
 
				if(file == null) {searching = false;continue;}
 
				if(file.isHidden && this._searchHidden === false || file.isSymbolicLink) continue;
 
				if(file.isDirectory) {
					proceedDirs.push(file);
					listing(file);
				}else if(file.extension != null && this._extensions.hasOwnProperty(file.extension)){
					found(file);
				}
			}
			if(proceedDirs.length == 0)	this.finish();
		}
		protected function found(file:File):void
		{
			switch(this._mode)
			{
				case MODE_SYNC:
					foundedFiles.push(file);
					break;
				case MODE_ASYNC:
					foundedFiles.push(file);
					this.dispatchEvent(new FileSearcherEvent(FileSearcherEvent.PROGRESS , file));
					break;
			}
		}
 
		protected function listing(dir:File):void
		{
			switch(this._mode)
			{
				case MODE_SYNC:
					listingComplete(dir.getDirectoryListing());
					break;
				case MODE_ASYNC:
					dir.addEventListener(FileListEvent.DIRECTORY_LISTING , listingEventComplete);
					dir.getDirectoryListingAsync();
					break;
				default:
					throw new ArgumentError("Unknown search mode '" + this._mode + "'");
					break;
			}
		}
 
		protected function listingEventComplete(e:FileListEvent):void
		{			
			e.currentTarget.removeEventListener(FileListEvent.DIRECTORY_LISTING , listingEventComplete);
			this.proceedFiles = this.proceedFiles.concat(e.files);
			proceedDirs.pop();
			proceed();
		}
		protected function listingComplete(list:Array):void
		{
			this.proceedFiles = this.proceedFiles.concat(list);	
			proceedDirs.pop();
			proceed();
		}
 
		private function finish():void
		{
			this._found = true;
			this.dispatchEvent(new FileSearcherEvent(FileSearcherEvent.COMPLETE));
		}
		/**
		 * Return's founded files
		 * @return Vector.<File> - Founded files
		 */		
		public function get result():Vector.<File>
		{
			if(this._found)
			{
				return this.foundedFiles;
			}else{
				return null;
			}
		}
	}
}
FileSearcherEvent.as
Код AS3:
package ru.air.gmobile.files
{
	import flash.events.Event;
	import flash.filesystem.File;
 
 
	public class FileSearcherEvent extends Event
	{
		private var _file:File;
		private var _type:String;
 
		public static const COMPLETE:String = "complete";
		public static const PROGRESS:String = "progress";
 
		public function FileSearcherEvent(type:String, file:File = null ,bubbles:Boolean=false, cancelable:Boolean=false)
		{
			this._type = type;
			if(this._type === PROGRESS){
				this._file = file;
			}
			super(type, bubbles, cancelable);
		}
 
		public function get file():File
		{
			if(this._type === PROGRESS){
				return _file;
			}else{
				throw new ArgumentError("Can't get file in non - PROGRESS event");
			}
		}
 
	}
}
Скачать можно по : http://www.genzo-dev.ru/as3/FileSearcher.rar
Всего комментариев 14

Комментарии

Старый 23.12.2011 16:30 iNils вне форума
iNils
 
Аватар для iNils
Для начала надо название темы сменить, а то "Поиск файлов AIR" говорит о том, что речь пойдет о поиске файлов *.air
Старый 23.12.2011 18:17 in4core вне форума
in4core
 
Аватар для in4core
FileSearcher is a class for
По коду, наличие protected методов в пользу private имеет смысловую нагрузку в вашем коде?
Старый 23.12.2011 18:23 gloomyBrain вне форума
gloomyBrain
 
Аватар для gloomyBrain
Меня удивляет выбрасывание ошибки в геттере. Ну и вообще напрягают -
1) вызов super после каких-то действий
2) присваивание файла, переданного в конструктор по условию (хотя можно ничего не проверять там)
3) сохраниение типа события, несмотря на то что он и так сохраняется в классе-родителе
Старый 23.12.2011 18:43 Genzo вне форума
Genzo
 
Аватар для Genzo
in4core
Потом можно наследовать от него другие классы вроде ImageFileSearcher
gloomyBrain
0 - Просто лень было 2 класса писать на комплит и прогресс
1 - Просто позиция в коде, от перемены мест слагаемых сумма не меняется=)
2 - Присвоение?
3 - Забыл, исправлю.
Старый 23.12.2011 18:47 Genzo вне форума
Genzo
 
Аватар для Genzo
Вообще поспешил я в народ выкладывать, написал то за 30 минут и 10 минут ASDoc'и писал =) Жду дальнейших комментариев, нужно само-совершенствоваться.
Старый 23.12.2011 19:25 gloomyBrain вне форума
gloomyBrain
 
Аватар для gloomyBrain
Ну я к тому что вот это
Код AS3:
this._type = type;
if(this._type === PROGRESS){
	this._file = file;
}
super(type, bubbles, cancelable);
Можно заменить на
Код AS3:
super(type, bubbles, cancelable);
_file = file;
Ну а на счет комментов - если ты это за 30 минут написал - то и комментить, сам понимаешь, особо нечего =)
Так - штука интересная и полезная.
Старый 23.12.2011 21:12 Genzo вне форума
Genzo
 
Аватар для Genzo
Цитата:
Можно заменить на
Код AS3:
super(type, bubbles, cancelable);
_file = file;
Обычно так и пишу, щас почему-то захотелось по корявому написать
Старый 24.12.2011 01:06 alatar вне форума
alatar
 
Аватар для alatar
А чем при поиске фотографий не устраивает CameraRoll?
Старый 24.12.2011 23:57 dimarik вне форума
dimarik
 
Аватар для dimarik
Можно ли в статье в двух словах указать каким способом решается поставленная задача? Код обычно служит для иллюстрации работы заявленного алгоритма.
Старый 25.12.2011 00:29 Inet_PC вне форума
Inet_PC
 
Аватар для Inet_PC
Одноразовый класс получается, на каждый чих (читай смену директории или расширений или режима поиска) придется новый экземпляр создавать? От предыдущего отписываться и к новому подписываться. Скрытые файлы пропускаются или нет параметр есть, а для папок нету. И не понимаю зачем массив fileTypes перегонять в объект ? Чем массив расширений Вас не устроил? Ох и я наверное бы callback добавил, люблю я их. Много ли таких ситуаций когда много кто хочет узнать о том, что найдены файлы?
Старый 26.12.2011 11:07 Genzo вне форума
Genzo
 
Аватар для Genzo
alatar
Это без участия пользователя.
dimarik
Синхронно или асинхронно пробегаемся по всем файлам в рут папке (getDirectoryListing). Если нужный файл записываем, если папка вскрываем ее и т.д., не смотрим ссылки т.к. можно попасть в замкнутый цикл, если папка имеет ссылку на себя или папку выше нее, и так пока не пробемися по всем папкам выше рут директории.
Inet_PC
Цитата:
Одноразовый класс получается, на каждый чих
Есть такое, но уж больно хотелось проверить скорость в асинхронном режиме.
Цитата:
Скрытые файлы пропускаются или нет параметр есть, а для папок нету.
А зачем искать папки?
Цитата:
. Много ли таких ситуаций когда много кто хочет узнать о том, что найдены файлы?
Это лично предпочтение мне кажется, но тогда нужно типизировать передачу параметров в callBak, а это не гибко, события здесь уместнее, имхо
Старый 26.12.2011 19:08 Inet_PC вне форума
Inet_PC
 
Аватар для Inet_PC
Цитата:
А зачем искать папки?
Не папки искать, а в скрытых папках.
Старый 26.12.2011 19:11 Genzo вне форума
Genzo
 
Аватар для Genzo
Цитата:
Не папки искать, а в скрытых папках.
Есть true в searchHidden передать, будет искать в скрытых папках
Старый 26.12.2011 23:19 Inet_PC вне форума
Inet_PC
 
Аватар для Inet_PC
а нуда
 

 


Часовой пояс GMT +4, время: 00:04.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.