package renamedirectory_10;
/*
P R O G R A M M B E S C H R E I B U N G
Windows läßt zu, dass ein Anwender zwar eine Verzeichnistiefe
anlegen kann, so dass der Verzeichnispfad über 255 Zeichen groß wird.
Allerdings kann mam dieses Verzeichnis dann nicht mehr mit dem
Explorer löschen.
Deshalb benennt dieses Programm alle Unterverzeichnisse in
Verezeichnisse mit möglichst Namenslänge um.
I)
Das explizite Vergeben von Schreibrechten bei der Umbennenung funktioniert nicht.
Trotzdem soll dies nicht zum Programmabbruch führen:
Es wird nur eine entsprechende Meldung erscheinen.
Trotzdem klappt die Umbennenung in den meisten Fällen.
Komischerweise gibt es keinen Fehler wenn die Umbennenung nicht klappt.
Warum ?
Bemerkung:
Mit setWriteable(...) kann man theoretisch Berechtigungen für Schreibzugriffe
vergeben. Dies funktioniert leider aber nicht in der Praxis.
Man muß die Eigenschaft "schreibgeschützt" in Win 10 auf den obersten Ordner
zurücksetzen, nachdem dieses Programm gestartet wurde.
Dann kann der ganze Verzeichnisbaum im Explorer von Win 10 gelöscht werden.
Wie entfernt man einen Verzeichnisbaums ?
- Dieses Programm starten
- Eigenschaft "schreibgeschützt" im Explorer auf den obersten Ordner entfernen.
- Löschen des obersten Knotens des Verzeichnisbaums.
Was fehlt noch:
- Bitte warten soll gleich erscheinen, nicht erst amEnde des Programms
II)
1)
In
renameMenue(ae,myMeldung)
muss auf das JTextArea-Feld zugegriffen werden.
Deswegen wird dieses JTextArea-Feld als Parameter myMeldung übergeben.
Wenn man dies nicht machen würde und den Aufruf
renameMenue(ae)
so konstruieren würde, müßte man aus dem Ereignis ae die Information
entnehmen, wo sich die Stelle befindet, wo die Zeichenfläche JPanel
angebracht wurde:
Container con = ((JButton) (ae.getSource())).getParent();
*/
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import javax.swing.*;
public class Startklasse {
public static void main(String[] args) {
MyFenster myF = new MyFenster();
// Programm wird beendet (aus dem Arbeitsspeicher entfernt), wenn Fenster weggeklickt
// wird. Nachprüfen mit Task-Manager
myF.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
// Konstruktor
class MyFenster extends JFrame {
// Stelle in MyFenster deklarieren, an die montiert wird.
private Container myCont;
// Eine Zeichenfläche deklarieren
private JPanel myPan;
private JButton myRenameButton;
private JTextArea myMeldung;
private JScrollPane sp;
private JLabel myMeldungenLabel;
// Eine Wanze deklarieren
private MyWanze myWanze;
private GridBagLayout myGBL_10_1;
// Konstruktor
public MyFenster() {
String meldung;
// Liefert die Stelle in MyFenster, an die montiert wird.
myCont = getContentPane();
// Erzeugt eine Zeichenfläche
myPan = new JPanel();
// Erzeugt Buttons
myRenameButton = new JButton("Start");
meldung="Umbenennen eines ganzen Verzeichnisbaums einschließlich der Dateien\n";
meldung = meldung+"Dieses Umbenennungsprogramm ist rekursiv und hat deshalb eine schlechetere Performance.";
myMeldungenLabel = new JLabel("Meldungen des Programms:");
myMeldung = new JTextArea(meldung);
// JTextArea scrollbar machen. Wichtig bei vielen Fehlermeldungen
sp = new JScrollPane(myMeldung);
// Alternative Möglichkeit myMeldung anzufügen
// sp.setViewportView(myMeldung);
// vertikaler Scrollbalken wird immer angezeigt, auch
// wenn sich wenig Meldungen in der JTextArea befinden.
sp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
// Erzeugt ein GridBagLayout
myGBL_10_1 = new GridBagLayout();
//myGL21 = new GridLayout(3, 1);
addiereKopmonente(myGBL_10_1, myRenameButton, 0, 0, 1, 1, 1, 1);
// weightx = 3 bedeutet, dass Buttom myb1 dreimal so breit ist
// wie myb1
addiereKopmonente(myGBL_10_1, myMeldungenLabel, 0, 1, 1, 1, 1, 1);
addiereKopmonente(myGBL_10_1, sp, 0, 2, 1, 8, 1, 20);
myPan.setLayout(myGBL_10_1);
//myWanze = new MyWanze();
myWanze = new MyWanze(myMeldung);
// Montiert die Wanze an den Button
myRenameButton.addActionListener(myWanze);
// Montiert die Buttons an die Zeichenfläche
myPan.add(myRenameButton);
myPan.add(myMeldungenLabel);
myPan.add(sp);
// Montiert die Zeichenfläche in das Fenster MyFenster
myCont.add(myPan);
// Fensterüberschrift festlegen
setTitle("Ein Umbenennungsprogramm");
// Koordinaten des linken, oberen Ecks des Fensters festlegen
// Koordinate x = 100, Koordinate y = 200.
setLocation(10, 200);
// Die Breite des Fensters in x-Richtung
// Die Breite des Fensters in y-Richtung
setSize(800, 400);
// Macht das Fenster sichtbar
setVisible(true);
}
public void addiereKopmonente(GridBagLayout gbl, Component c, int x, int y, int width, int height, double weightx, double weighty){
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = width;
gbc.gridheight = height;
gbc.weightx = weightx;
gbc.weighty = weighty;
// Beschränkung für Komponente c (z.B. Button)am Layout-Manager anmelden.
gbl.setConstraints(c, gbc);
add(c);
}
}
class MyWanze implements ActionListener{
public JTextArea myMeldung;
//public MyWanze() {
public MyWanze(JTextArea myMeldung) {
this.myMeldung=myMeldung;
}
public void actionPerformed(ActionEvent ae) {
FileOderDirectoryRename myF = new FileOderDirectoryRename();
myF.renameMenue(ae,myMeldung);
}
}
class FileOderDirectoryRename {
public JTextArea myMeldung;
public int zaehler = 0;
public int merke=0;
public Component comp[];
public void renameMenue(ActionEvent ae, JTextArea myMeldung){
int j = 0;
int option = 0;
this.myMeldung=myMeldung;
/* Sonderbar:
Wenn folgendes gemacht wird, reagiert das Programm anders:
Container con;
con = ((JButton) (ae.getSource())).getParent();
*/
// Ein Dialogfenster (eine Art Explorer) erzeugen.
// In diesem können Dateien und Verzeichnisse ausgewählt werden.
// Ohne solch einen Dialog kommt fast kaum eine Anwendung aus.
// Für diesen Zweck gibt es in Java die Klasse:
// javax.swing.JFileChooser
JFileChooser chooser = new JFileChooser();
// Es werden Directorys und Files angezeigt
chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
// Es können mehrere Directorys/Files markiert werden
chooser.setMultiSelectionEnabled(true);
// Button auf dem JFileChooser mit Aufschrift "Umbenennung starten"
// erzeugen
chooser.setApproveButtonText("Umbenennung starten");
// Dialogmenü anzeigen
option = chooser.showDialog(null, null);
if (option == JFileChooser.APPROVE_OPTION) {
// markierte Directorys bzw. Files in dirFiles abspeichern
File[] dirFiles = chooser.getSelectedFiles();
myMeldung.append("\nBitte warten ...");
// Alle markierten Directorys bzw. Files umbenennen
for (int i = 0; i < dirFiles.length; i++) {
try{
renameTree(dirFiles[i]);
}
catch(Throwable t){
if(t instanceof MyException){
myMeldung.append("\n"+((MyException) t).throwMeldung);
System.out.println("\n"+((MyException) t).throwMeldung);
}
else{
System.out.println("Meldung in renameMenue(): "+t.getMessage()+"\n");
myMeldung.append("\n"+t.getMessage());
t.printStackTrace();
}
}
}
myMeldung.append("\nEnde des Umbenennungsvorgangs");
System.out.println("\nEnde des Umbenennungsvorgangs");
} else {
myMeldung.append("\nAbbruch");
}
}
/*
public void deleteFileOderDirectory(File dir){
File[] files=dir.listFiles();
if(files !=null){
for(int i=0; i < files.length; i++){
if(files[i].isDirectory()){
//System.out.println("files["+i+"]"+files[i].getName());
deleteFileOderDirectory(files[i]);
}
else{
//System.out.println("files["+i+"]"+files[i].getName());
files[i].delete();
}
}
}
// System.out.println("dir"+dir.getName());
dir.delete();
}
*/
/*
public void fehlermeldung(String s){
myMeldung.append(s);
}
*/
// Prüft, ob ein Knoten eines Verzeichnisbaums ein Blatt ist
public boolean isLeaf(File node) throws Throwable{
boolean blatt=false;
File[] files;
String throwString;
// Throwable myt;
MyException myEx;
try{
if(node.isFile()){
blatt=true;
}
}
catch(Throwable t){
throwString = "\nF E H L E R - M E L D U N G : Lesebzugriff zur Datei nicht erlaubt:\n"+node;
System.out.println(throwString);
myEx = new MyException(throwString, true);
throw myEx;
}
try{
if(node.isDirectory()){
files = node.listFiles();
if(files.length==0){
blatt=true;
}
else{
blatt=false;
}
}
}
catch(Throwable t){
throwString = "\nF E H L E R - M E L D U N G : Lesebzugriff zum Verzeichniss nicht erlaubt:\n"+node;
System.out.println(throwString);
myEx = new MyException(throwString, true);
throw myEx;
}
return blatt;
}
// Umbenennen eines Knotens eines Verzeichnisbaums
public boolean renameNode(File dir) throws Throwable{
boolean merke=false;
boolean namensVergleich;
boolean erg=true;
int i;
String umbenennungString;
String temp;
String[] strings=null;
File parent;
ArrayList checkliste;
MyException myEx=new MyException("\n", true);
File f=null;
File parentFile;
String throwString="";
// bei getParentFile() gibt es keine Exception
parent = dir.getParentFile();
if (parent == null) {
throwString = "\nF E H L E R - M E L D U N G : Es gibt kein Parent-Verzeichnis von:\n"+dir;
System.out.println(throwString);
myEx = new MyException(throwString, true);
throw myEx;
}
try{
// Liste des Oberverzeichnisses
strings = parent.list();
}
catch (Throwable t){
throwString = "\nF E H L E R - M E L D U N G : Lesebzugriff zum nicht erlaubt von Verzeichnis:\n"+parent;
System.out.println(throwString);
myEx = new MyException(throwString, true);
throw myEx;
}
checkliste = new ArrayList();
for (i = 0; i < strings.length; i++) {
// bei add gibt es keine Exception
checkliste.add(strings[i]);
}
// bei getName gibt es keine Exception
temp = dir.getName();
// bei remove gibt es keine Exception
checkliste.remove(temp);
Liste mylist = new Liste();
// bei ersetzenVorschlag gibt es keine Exception
umbenennungString = mylist.ersetzenVorschlag(checkliste);
// bei dir.getParentFile() gibt es keine Exception
parentFile=dir.getParentFile();
try{
f = new File(parentFile, umbenennungString);
}
catch (Throwable t){
throwString="\nF E H L E R - M E L D U N G umbenennungString ist null von:\n";
System.out.println(throwString);
myEx = new MyException(throwString, true);
throw myEx;
}
// bei getName() und equals() gibt es keine Exception
namensVergleich=f.getName().equals(dir.getName());
try{
// Wenn neuer Pfadname == altem Pfadname, dann gibt es beim
// Umbennenen einen Fehler --> siehe Java-API
//
if(namensVergleich==false){
erg=dir.setWritable(true, false);
if(erg==false){
throwString = "\nF E H L E R - M E L D U N G beim Vergeben von Schreibrechten bei\n"+f;
System.out.println(throwString);
// merke=true;
myEx = new MyException(throwString, true);
throw myEx;
}
}
}
catch (Throwable t){
// Bei praktischen Tests klappt die Vergabe von Schreibrechten nicht.
// Deswegen soll das Programm weitermachen, aber den Fehler ausgeben.
throwString += "\nF E H L E R - M E L D U N G beim Vergeben von Schreibrechten bei\n"+f;
System.out.println(throwString);
//merke = true;
myEx = new MyException(throwString, false);
}
try{
if(namensVergleich==false){
erg=dir.renameTo(f);
if(erg==false){
throwString += "\nF E H L E R - M E L D U N G beim Umbenennen von\n" +dir+ "\n nach \n"+f;
System.out.println(throwString);
myEx = new MyException(throwString, false);
}
}
}
catch (Throwable t){
throwString +="\nF E H L E R - M E L D U N G Schreibzugriff beim Umbenennen (auf alten oder neuen Pfadnamen) von:\n"+dir+"\n nach \n"+f;
throwString=throwString+"\n oder Parameter " + "ist null";
System.out.println(throwString);
myEx = new MyException(throwString, false);
}
if(myEx.sofortAbbruch==false){
throw myEx;
}
return erg;
}
// Jeder Knoten (eauch Files) Verzeichnisbaums wird umbenannt.
public void renameTree(File node) throws Throwable{
int i;
boolean erg;
String umbenennungString;
File[] files=null;
String throwString;
MyException myEx;
try{
// Achtung: wenn node kein Directory dann null als Ergebnis
files = node.listFiles();
if(files==null){
System.out.println("Hallo");
}
}
catch (Throwable t){
//melde ="\nF E H L E R - M E L D U N G : Lesebzugriff nicht erlaubt von:\n"+node;
throwString="\nF E H L E R - M E L D U N G : Lesebzugriff nicht erlaubt von:\n"+node;
System.out.println("\n"+throwString);
throw t;
}
try{
if (isLeaf(node)) {
//System.out.println("rename "+node.getName());
renameNode(node);
return;
}
else{
for (i = 0; i < files.length; i++) {
//System.out.println("rename "+files[i].getName());
renameTree(files[i]);
}
//System.out.println("rename "+node.getName());
renameNode(node);
}
}
catch (Throwable t){
if(t instanceof MyException){
if ( ((MyException) t).sofortAbbruch == false){
myMeldung.append(((MyException) t).throwMeldung);
}
}
else{
System.out.println("Meldung in renameMenue(): "+t.getMessage()+"\n");
myMeldung.append("\n"+t.getMessage());
t.printStackTrace();
throw t;
}
}
}
}
class MyException extends Throwable{
public boolean sofortAbbruch;
public String throwMeldung;
public MyException(String throwMeldung, boolean sofortAbbruch) {
this.throwMeldung = throwMeldung;
this.sofortAbbruch = sofortAbbruch;
}
public boolean getSofortAbbruch() {
return sofortAbbruch;
}
public void setSofortAbbruch(boolean sofortAbbruch) {
this.sofortAbbruch = sofortAbbruch;
}
}
class Liste {
private ArrayList moeglicheNamen;
public Liste() {
moeglicheNamen = erzeugenamensliste();
}
/*
public ArrayList entferne(ArrayList pl, int i) {
ArrayList temp;
temp = new ArrayList(pl);
temp.remove(i);
return temp;
}
*/
public ArrayList erzeugeArrayList(File[] files) {
int i;
ArrayList temp;
temp = new ArrayList();
for (i = 0; i < files.length; i++) {
temp.add(files[i]);
}
return temp;
}
public String ersetzenVorschlag(ArrayList checkliste) {
ArrayList temp;
String vorschlagStr;
String ergStr = null;
Boolean b;
int i;
i = 0;
while (i < moeglicheNamen.size()) {
vorschlagStr = (String) moeglicheNamen.get(i);
// bei contains gibt es keine Exception
b = checkliste.contains(vorschlagStr);
if (b == false) {
ergStr = vorschlagStr;
return ergStr;
}
i++;
}
return ergStr;
}
/*
Die Liste der möglichen Namen aller Knoten des Verzeichnisbaums:
a,b,...,z,0,...,9,
aa ... a9, ba .... b9, ... 9a, ..., 99
aaa, ..., 999
Mit duesen Namen werden alle Knoten des Verzeichnisbaums ersetzt,
wobei möglichst einstellige Namen (also, a,b, ... 9) bevorzugt werden.
*/
ArrayList erzeugenamensliste() {
int i, j, k;
ArrayList basisliste;
ArrayList namensliste;
ArrayList ziffernliste;
ArrayList buchstabenliste;
basisliste = new ArrayList<String>();
ziffernliste = new ArrayList<String>();
buchstabenliste = new ArrayList<String>();
namensliste = new ArrayList<String>();
// Ascii-Wert von a = 97
// Ascii-Wert von z = 122
// Ascii-Wert von 0 = 48
// Ascii-Wert von 9 = 57
for (i = 97; i <= 122; i++) {
buchstabenliste.add(String.valueOf((char) i));
}
for (i = 48; i <= 57; i++) {
ziffernliste.add(String.valueOf((char) i));
}
basisliste.addAll(buchstabenliste);
basisliste.addAll(ziffernliste);
namensliste.addAll(basisliste);
for (i = 0; i < basisliste.size(); i++) {
for (j = 0; j < basisliste.size(); j++) {
String str1;
String str2;
str1 = (String) basisliste.get(i);
str2 = (String) basisliste.get(j);
String str = str1 + str2;
namensliste.add(str);
}
}
for (i = 0; i < basisliste.size(); i++) {
for (j = 0; j < basisliste.size(); j++) {
for (k = 0; k < basisliste.size(); k++) {
String str1;
String str2;
String str3;
str1 = (String) basisliste.get(i);
str2 = (String) basisliste.get(j);
str3 = (String) basisliste.get(k);
String str = str1 + str2 + str3;
namensliste.add(str);
}
}
}
return namensliste;
}
}