Doppelte Dateien (inhaltlich) löschen!

JesusFreak777

Erfahrenes Mitglied
Hi Leute,

ich hab mir ein kleines Script gebastelt, das mir doppelte Dateien löschen soll!

Soweit funktioniert das auch, aber es löscht immer nur eine Datei! Warum?

Ich habe so ein kleines Backupsystem gebaut, das mit aus meiner Sidebar das Textfeld in regelmäßigen Abständen sichert! Langsam werden es aber viele Dateien (html) und da die meisten doppelt sind, habe ich mir gedacht, ich suche diese und lösche!

mein Script:
PHP:
//dateien in ein Array einlesen ($key => Dateiname.endung, $value => inhalt [eh nur ein paar notizen])
$bak = array();
$directory = "testdat";
$handle = opendir($directory);
while ($file = readdir ($handle)) {
	if ($file != "." && $file != "..") {
		$line = file($directory.'/'.$file);
		$bak[$file] = $line[0];
	}
} closedir($handle);


removeDuplicates($bak);

//meine dateien
echo "<pre>";
print_r($bak);
echo "</pre>";


//funktion die ich online gefunden habe, sollte doppelte einträge im array löschen, leicht abgeändert
function removeDuplicates($array, $dir) {
    $counts = array_count_values($array);
	//zeigt an wie oft +1 er löschen sollte [DEBUG]
	echo "max ".max($counts);
 
		foreach ($counts as $value => $counter) {
			if ($counter > 1) {
				//daten aus array entfernen
				unset($counts[$value]);
				//daten aus ordner löschen
				unlink($dir.'/'.array_search($value, $array));
			}
		}
 
    return array_keys($counts);
}

Ja ich weiß, es werden von meinen dateien nur die erste Zeile berücksichtigt! das ist auch momentan egal, weil ich den HTML-Code auch nur in eine Zeile packe -> [line0]: viel Text <br> mit Abzätzen...
Trotzdem brauch ich auch irgendwann mal dafür eine Lösung, evtl. hat jemand ne idee wie ich das unkompliziert lösen kann (dachte so an $html_file .= $link[$i].'/n' in ner forschleife, habe es aber noch nicht getestet)!

Vielen Dank
 
Ein Tipp: array_filter()

PHP:
function selectToRemove($count){
    return $count > 1;
}

$filesToDelete = array_keys(array_filter(array_count_values($bak), 'selectToRemove'));
//TODO: Alle Dateien welche in $filesToDelete aufgelistet sind löschen
 
Danke erstmal!

scheint einiges unkomplizierter zu sein!

aber auch da gibt er mir nur eine Datei aus!

HTML:
//meine dateien
Array
(
    [datei1.dat] => asdf
    [datei2.dat] => dfgb
    [datei3.dat] => dsfvyxcvh
    [datei4.dat] => text bla bla bla
    [datei5.dat] => sdfvhxcvjkhlj,k
    [datei6.dat] => asdf
    [datei7.dat] => dsfvbgfgzuju
    [datei8.dat] => asdfvgbttzjhf
    [datei9.dat] => asdf
)

//zu löschen
Array
(
    [0] => asdf
)

Als ergebniss erhalte ich den text der x mal gelöscht werden soll! Aber wie weiß ich jetzt Welche datei, bzw. welche datei nicht?

Macht es sinn $filesToDelete in eine Schleife zu werfen und so lange die Schleife (unlink(array_search($filesToDelete[0], $bak));) laufen lassen bis $filesToDelete 0 ist?

Danke
 
Mööp. Stimmt. Wir verlieren dabei den Dateinamen.

PHP:
//Array initialisiseren. In Desem Array werden alle Dateien gespeichert
$savedFiles = array();
foreach($files as $fileName => $value){
    //Prüfen ob der Value bereits in $savedFiles vorhanden ist
    if(in_array($value, $savedFiles)){
        //Wenn ja, Datei löschen
        //TODO: Datei löschen
        echo "Delete File {$fileName}: '{$value}'<br />";
    }else{
        //Datei behalten
        $savedFiles[$fileName] = $value;
    }
}

Mein Testversuch (löscht datei6 und 9):
PHP:
$files=array(
    'datei1.dat' => 'asdf',
    'datei2.dat' => 'dfgb',
    'datei3.dat' => 'dsfvyxcvh',
    'datei4.dat' => 'text bla bla bla',
    'datei5.dat' => 'sdfvhxcvjkhlj,k',
    'datei6.dat' => 'asdf',
    'datei7.dat' => 'dsfvbgfgzuju',
    'datei8.dat' => 'asdfvgbttzjhf',
    'datei9.dat' => 'asdf'
);

//Array initialisiseren. In Desem Array werden alle Dateien gespeichert
$savedFiles = array();
foreach($files as $fileName => $value){
    //Prüfen ob der Value bereits in $savedFiles vorhanden ist
    if(in_array($value, $savedFiles)){
        //Wenn ja, Datei löschen
        //TODO: Datei löschen
        echo "Delete File {$fileName}: '{$value}'<br />";
    }else{
        //Datei behalten
        $savedFiles[$fileName] = $value;
    }
}


echo '<h1>Dateien die nicht gelöscht werden</h1>';
echo '<pre>';
print_r($savedFiles);
echo '</pre>';

Nachtrag:
Wenn du Grosse und viele Dateien hast und dieses Script regelmässig ausführen willst, empfehle ich dir, nicht den Inhalt der Datei einzulesen und zu vergleichen, sondern lediglich den Hash-wert aus hash_file().
 
Zurück