Pytanie o FilenameFilter.

0

Witam, mam pytanie - trafilem na taki kod:

import java.util.regex.*;
import java.io.*;
import java.util.*;

public class DirList {
	public static void main(String[] args) {
		File path = new File(".");
		String[] list;
		if (args.length == 0)
			list = path.list();
		else
			list = path.list(new DirFilter(args[0]));
		Arrays.sort(list, String.CASE_INSENSETIVE_ORDER);
		for (String dirItem : list)
			System.out.println(dirItem);
	}
}

class DirFilter implements FilenameFilter {
	private Pattern pattern;
	public DirFilter(String regex) {
		pattern = Pattern.compile(regex);
	}
	public boolean accept(File dir, String name) {
		return pattern.matcher(name).matches();
	}
}

Czegos jednak nie rozumiem. Widze, ze wywolywana jest przeladowana metoda list ktorej parametrem jest objekt implementujacy interfejs FilenameFilter. Tworzony jest obiekt typu File ze sciezka ".", czyli biezacy katalog, i gdy nie podam zadnego argumentu, to zostanie wykonane.

Nie rozumiem jednak tego - metoda "accept" nie jest nigdzie wywolywana. Tworzony jest obiekt typu DirFilter, ktorego konstruktor przyjmuje jako argument wyrazenie regularne, np rozszerzenie pliku, czy cokolwiek innego. Metoda "accept" jest wywolywana (wedlug dokumentacji) dla kazdego pliku w danym katalogu, sprawdzane jest czy accept zwraca true czy false, i gdy zwroci true - plik jest dodawany do listy list. Jednak nie jest przekazane metodzie accept nic, ani nie jest wywolana, a w dodatku argument File dir - nie jest nigdzie uzyty.
Ktos moglby wyjasnic jak to dokladnie dziala?

0

o_O w tym przypadku masz jakieś wyrażenie regularne i ten FilenameFilter sprawdza czy nazwy pliku pasują do podanego wyrażenia regularnego. np. jeśli jako argument kontruktora podasz

String reg = "ala.*";

to złapią ci sie tylko pliki których nazwa zaczna sie od "ala"

0

Hej, no tak, tyle mniej wiecej lapie, ale moje pytanie dotyczy bardziej wewnetrznego mechanizmu dzialania - jak to jest, ze metoda accept, ktora - jak napisales i jak zalozylem - porownuje to co wpisalem z lista plikow z zadanej lokacji i odpowiednie wstawia do zmiennej String[] list, nie jest wywolywana w zadnym miejscu, ani jej pierwszy argument nie jest nigdzie uzyty. Czy jest wywolywana jakos automatycznie w momencie utworzenia obiektu?

0

Parametr dir nie jest użyty bo Ty go nie użyłeś. Można np. napisać metodę accept, która akceptuje pliki *.jpg tylko z katalogu, który ma w nazwie fragment "abc". Metodę accept wywołuje metoda list.

0

Nie uzylem ani parametru dir ani niczego innego - proboje zrozumiec mechanizm dzialania na podstawie kodu ktory znalazlem.
Czy mam rozumiec, ze obiekt path, ktory jakby zawiera sciezke podana mu w konstruktorze File path = new File(".") przekazuje w linijce list = path.list(new DirFilter(args[0])); ta podana wczesniej kropke, ktora z kolei jest uzyta w metodzie accept jako argument File dir?

0

Metoda accept jest wywoływana wewnątrz metody list(new DirFilter(args[0])).

Jeżeli wywołasz metodę list(), bez podawania parametrów to zadziała ona w następujący sposób:

  • dla bieżącego obiektu File (zmienna path, czyli katalog bieżący) wybierz wszystkie pliki i katalogi.

Jeżeli wywołasz metodę list(new DirFilter(args[0])) to wywołanie wygląda trochę inaczej:

  • dla bieżącego obiektu File (zmienna path, czyli katalog bieżący) wybierz wszystkie pliki i katalogi.
  • Dla każdego pliku i katalogu na liście przekaż jego nazwę do filtra wywołując filter.accept(fileName)
  • jeżeli filter.accept() zwróci true to dopisz ten plik do listy wynikowej. W przeciwnym wypadku nie rób nic
  • zwróć listę wynikową, czyli listę plików dla których filtr zwrócił true.
0

Ok, dzieki, czyli metoda accept jest wywolywana automatycznie, niejawnie - jesli mozna to tak okreslic. W takim razie czy argument przekazany w list = path.list(new DirFilter(args[0])) jest przekazywany dalej do metody accept(File dir, String name) jako pierwszy parametr? Drugi, jak napisales, to nazwa pliku/katalogu.

0

Nie, jako pierwszy parametr do metody accept jest przekazywany katalog, w którym znajduje się plik.

0

W jaki sposob?

0

W taki sam jak nazwa pliku.

0

Staram sie i staram, zadajac to samo pytanie na rozne sposoby, ale odpowiedzi nadal mijaja cel. Skoro metoda list przekazuje nazwy plikow i katalogow do filtra, jak napisal Koziołek, a z kolei lokacja wybrana jest przy uzyciu zmiennej path, na ktorej uzyta jest metoda list, to zgodnie z tym co napisal bogdans - "W taki sam jak nazwa pliku." - metoda list przekazuje argument File dir do metody accept? Czy jeszcze nie tak?

0

Ja rozumiem działanie filtru tak: Metody path.list() i path.list(filtr) zadają pytanie do systemu operacyjnego o zawartość katalogu path. Pierwsza z nich zwraca tablicę złożoną z nazwa wszystkich obiektów w katalogu, druga dodatkowo sprawdza czy nazwa obiektu i zawierający go katalog spełniają warunki metody accept.

boolean accept(File dir, String name)

Tests if a specified file should be included in a file list.

Parameters:
dir - the directory in which the file was found.
name - the name of the file.
Wypróbuj taką modyfikację swojej klasy:

import java.util.regex.*;
import java.io.*;
import java.util.*;
 
public class DirList {
    public static void main(String[] args) {
        File path = new File(System.getProperty("user.dir"));
        String[] list;
        if (args.length == 2)
            list = path.list(new DirFilter(args[0],args[1]));                        
        else
            list = path.list();
        Arrays.sort(list);
        for (String dirItem : list)
            System.out.println(dirItem);
    }
}
 
class DirFilter implements FilenameFilter {
    private Pattern pattern;
    private String wzor;
    public DirFilter(String regex,String wzor) {
        pattern = Pattern.compile(regex);
        this.wzor = wzor;
    }
    public boolean accept(File dir, String name) {
        return (pattern.matcher(name).matches() && dir.getName().contains(wzor));
    }
}
0

Dzieki za kod bogdan. Rozumiem idee dzialania filtru, jak i uzycia go w polaczeniu z wylistowaniem zawartosci danej lokacji. Zapytam jeszcze:
DirFilter jest klasa, accept jest metoda tej klasy. Aby ta metoda mogla zostac wywolana, nalezy jej uzywac zgodnie z definicja - w tym wypadku - podac jej 2 argumenty. Metoda list tworzy liste plikow i jakos pod maska przekazuje ta liste do drugiego argumentu metody accept. Czy metoda list takze przekazuje wartosc do pierwszego argumentu metody accept?
Jesli tak - jak? Jesli nie - jak inaczej?

0

Kod wyciągnięty ze źródeł Javy:

public String[] list(FilenameFilter filter) {
	String names[] = list();
	if ((names == null) || (filter == null)) {
	    return names;
	}
	ArrayList v = new ArrayList();
	for (int i = 0 ; i < names.length ; i++) {
	    if (filter.accept(this, names[i])) {
		v.add(names[i]);
	    }
	}
	return (String[])(v.toArray(new String[v.size()]));
    }

i samo list():

public String[] list() {
	SecurityManager security = System.getSecurityManager();
	if (security != null) {
	    security.checkRead(path);
	}
	return fs.list(this);
    }
0

Ok, chyba wreszcie dotarlismy do sedna ^^ Z tego wynika, ze w list() tworzony jest obiekt typu SecurityManager, uzyty potem do sprawdzenia czy mozna czytac z danej lokacji. Nie bardzo wiem jak rozumiec return fs.list(this);. Z kolei przeladowana wersja list(); sprawdza czy podane sa parametry - jesli nie, dziala jak zwykla list(); filter.accept(this, names[i] - do czego odnosi sie this? To samo pytanie do poprzedniego - return fs.list(this);?
Do tej pory natrafilem na slowo kluczowe this tylko w takim kontekscie:

public class Point {
    public int x = 0;
    public int y = 0;
        
    //constructor
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}
0

this to this. Obiekt przekazuje do metody samego siebie. To tak jak byś sam się zgłaszał do odpowiedzi w szkole.

0

Moglbys to rozwinac, w kontekscie kodu ze zrodel javy?

1 użytkowników online, w tym zalogowanych: 0, gości: 1