Thread Ordnerstruktur in DB abbilden - evt. eigene DB (File) schreiben? (34 answers)
Opened by lousek at 2011-02-24 00:10

topeg
 2011-02-28 21:02
#146117 #146117
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
Ich habe mich vor kurzem mit so einem Problem beschäftigt.

Dazu habe ich ein Modul geschrieben, dass eine BerkeleyDB transparent im Hintergrund nutzt um einen Verzeichnisbaum als Hash-Tree zu verwalten. Das Modul ist aber kaum dokumentiert. Nur das nötigste habe ich dazu geschrieben. Wenn du dennoch Interesse hast, kann ich es dir mal zusenden.

Aber hier ein minimales Beispiel wie man so was handhaben kann:


more (16.4kb):
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;

my @path_in=qw(
  /data/bla1/ha1/hi1/he1
  /data/bla1/ha1/hi1/he2
  /data/bla1/ha1/hi2/he1
  /data/bla1/ha1/hi2/he2
  /data/bla1/ha2/hi1/he1
  /data/bla1/ha2/hi1/he2
  /data/bla1/ha2/hi2/he1
  /data/bla1/ha2/hi2/he2
  /data/bla2/ha1/hi1/he1
  /data/bla2/ha1/hi1/he2
  /data/bla2/ha1/hi2/he1
  /data/bla2/ha1/hi2/he2
  /data/bla2/ha2/hi1/he1
  /data/bla2/ha2/hi1/he2
  /data/bla2/ha2/hi2/he1
  /data/bla2/ha2/hi2/he2
);
print Dumper(\@path_in);

my $tree=make_tree(\@path_in);
print Dumper($tree);

my $path_out=join_tree($tree);
print Dumper($path_out);

########################################################################

sub make_tree
{
  my $tree={};

  add_to_tree($tree,$_) for(@{$_[0]});

  return $tree;
}

sub add_to_tree
{
  my $tree=shift;
  my $path=shift;
  my @elms=split('/',$path);

  # entferne am Anfang '/' wenn vorhanden
  shift(@elms) unless($elms[0]);

  # falls das letzte zeichen ein '/'
  # ist handelt es sich um ein verzeichnis
  my $file=1;
  unless($elms[-1])
  {
    $file=0;
    pop(@elms);
  }

  # Baum Eintrag erzeugen
  # vorsicht wenn verscht wird eine "Datei"
  # mit einem Ordner zu überschreiben kommt die Warnung
  # dass ein Scalar kein Hash ist.
  # umgehekhrt kann eine "Datei" aber einen ordner überschreiben.
  # wenn du das Abfangen willst/musst,
  # musst du das vor dem setzten prüfen
  my $ref=\$tree;
  $ref=\$$ref->{$_} for(@elms);

  # wert setzen
  # hier den übergeben pfad
  # kann aber jeder beliebige Wert sein
  $$ref=$path if($file);
}

sub join_tree
{
  my $tree=shift;
  my $path=shift // '';
  my @list;
  # alle namen der Ebenen durchgehen
  # sortiert zur hübscheren Darstellung
  for my $name (sort(keys(%$tree)))
  {
    my $elm=$tree->{$name};

    # wenn Hash, dann ist es ein Verzeichnis
    if($elm && ref($elm) eq 'HASH')
    {
      # rekursiver Aufruf
      # kann eine "deep Recursion" Warnung ausgeben
      # passiert bei tiefen wie man sie von Dateisystemen her kennt eher selten
      # je nach dem wie der Interpreter kompiliert wurde
      # kommt die Meldung nach 1.000 oder auch erst nach 1.000.000 Rekursionen
      # Dateisysteme haben aber selten mehr als 20 Ebenen.
      my $lst=join_tree($elm,"$path/$name");
      push(@list,@$lst);
    }
    else
    { push(@list,"$path/$name"); }
  }

  return \@list;
}

Ausgabe:
more (5.7kb):
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
$VAR1 = [
'/data/bla1/ha1/hi1/he1',
'/data/bla1/ha1/hi1/he2',
'/data/bla1/ha1/hi2/he1',
'/data/bla1/ha1/hi2/he2',
'/data/bla1/ha2/hi1/he1',
'/data/bla1/ha2/hi1/he2',
'/data/bla1/ha2/hi2/he1',
'/data/bla1/ha2/hi2/he2',
'/data/bla2/ha1/hi1/he1',
'/data/bla2/ha1/hi1/he2',
'/data/bla2/ha1/hi2/he1',
'/data/bla2/ha1/hi2/he2',
'/data/bla2/ha2/hi1/he1',
'/data/bla2/ha2/hi1/he2',
'/data/bla2/ha2/hi2/he1',
'/data/bla2/ha2/hi2/he2'
];
$VAR1 = {
'data' => {
'bla1' => {
'ha1' => {
'hi2' => {
'he2' => '/data/bla1/ha1/hi2/he2',
'he1' => '/data/bla1/ha1/hi2/he1'
},
'hi1' => {
'he2' => '/data/bla1/ha1/hi1/he2',
'he1' => '/data/bla1/ha1/hi1/he1'
}
},
'ha2' => {
'hi2' => {
'he2' => '/data/bla1/ha2/hi2/he2',
'he1' => '/data/bla1/ha2/hi2/he1'
},
'hi1' => {
'he2' => '/data/bla1/ha2/hi1/he2',
'he1' => '/data/bla1/ha2/hi1/he1'
}
}
},
'bla2' => {
'ha1' => {
'hi2' => {
'he2' => '/data/bla2/ha1/hi2/he2',
'he1' => '/data/bla2/ha1/hi2/he1'
},
'hi1' => {
'he2' => '/data/bla2/ha1/hi1/he2',
'he1' => '/data/bla2/ha1/hi1/he1'
}
},
'ha2' => {
'hi2' => {
'he2' => '/data/bla2/ha2/hi2/he2',
'he1' => '/data/bla2/ha2/hi2/he1'
},
'hi1' => {
'he2' => '/data/bla2/ha2/hi1/he2',
'he1' => '/data/bla2/ha2/hi1/he1'
}
}
}
}
};
$VAR1 = [
'/data/bla1/ha1/hi1/he1',
'/data/bla1/ha1/hi1/he2',
'/data/bla1/ha1/hi2/he1',
'/data/bla1/ha1/hi2/he2',
'/data/bla1/ha2/hi1/he1',
'/data/bla1/ha2/hi1/he2',
'/data/bla1/ha2/hi2/he1',
'/data/bla1/ha2/hi2/he2',
'/data/bla2/ha1/hi1/he1',
'/data/bla2/ha1/hi1/he2',
'/data/bla2/ha1/hi2/he1',
'/data/bla2/ha1/hi2/he2',
'/data/bla2/ha2/hi1/he1',
'/data/bla2/ha2/hi1/he2',
'/data/bla2/ha2/hi2/he1',
'/data/bla2/ha2/hi2/he2'
];

View full thread Ordnerstruktur in DB abbilden - evt. eigene DB (File) schreiben?