Wie kann man mehrere Dateien gleichzeitig umbenennen?
Es wird ausdrücklich darauf hingewiesen, dass bei unsachgemäßer oder unbedachter Anwendung des hier dargestellten Verfahrens zum Umbenennen und/oder Löschen von Dateien Datenverlust drohen kann. Der Autor lehnt jegliche Verantwortung ab.
Das Beispiel weist neben main()
zwei weitere Methoden
auf: renameFile()
enthält die wesentlichen
Aktionen, um innerhalb eines Dateibaumes alle Dateien nach einem
festgelegten Schema umzubenennen und die Methode copyFile()
,
die als Hilfsmethode Dateien kopieren kann. Letzte entstammt dem
Artikel zum Kopieren
von Dateien. Ihre Funktion kann dort nachgeschlagen werden.
In renameFile()
kann durch den Parameter deepness
festgelegt werden, in welcher Rekursionstiefe die Umbenennung
stattfinden soll. Wird hier ein Wert kleiner 1
angegeben, so werden alle Dateinamen unverändert belassen. 1
ändert nur die Dateinamen innerhalb des Verzeichnisses pfad
,
2
benennt zusätzlich Dateien eine Ebene tiefer um,
3
noch eine zweite Ebene tiefer, etc.
Der Parameter pfad
muss den absoluten Pfad zur
umzubenennenden Datei enthalten oder zu einem Verzeichnis, dessen
Inhalt umbenannt werden soll. Hierbei muss beachtet werden, dass die
Umbenennung wesentlich auf die Trennung von Dateibezeichner und
Dateierweiterung durch einen Punkt zurückgreift (s.u.). Dateien
ohne Extension können auf die hier gezeigte Weise nicht
umbenannt werden.
Durch den String
-Parameter postfix
kann ein Namensanteil eingegeben werden, der bei der Umbenennung vor
dem letzten Punkt im Dateinamen eingefügt werden soll. Bsp.:
Wird eine Datei mit dem Bezeichner xxx.yyy
durch das
Postfix _new
erweitert, so resultiert der Dateiname xxx_new.yyy
.
Der Parameter extension
übergibt eine neue
Dateinamenserweiterung, die bei der Umbenennung statt der alten
verwendet werden kann. Wird er mit null
belegt, so wird
die bisherige Dateiendung beibehalten. Der Parameter delete
wird dann selbstständig auf false
gesetzt, um ein
eventuelles Löschen der Dateien zu verhindern, falls
gleichzeitig kein Postfix angegeben wurde. Durch Übergabe von true
an den Parameter delete
können ansonsten die alten
Dateien gelöscht werden.
ACHTUNG DATENVERLUST! Hier muss große Sorgfalt geleistet werden! Eine Löschung ist unwiederbringlich und kann nicht rückgängig gemacht werden!
Der boolsche Parameter ask
bestimmt, ob vor der
Umbenennung jeder Datei eine Sicherheitsabfrage erfolgen soll. Wird
hier false
übergeben, so wird diese
übersprungen.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import javax.swing.JOptionPane;
public class MehrereDateienUmbenennen {
private void renameFile(String pfad, String postfix, String extension,
boolean ask, boolean delete, int deepness) {
if (postfix == null) {
postfix = "";
}
File file = new File(pfad);
if (file.isDirectory()) {
if (--deepness > -1) {
File[] files = file.listFiles();
for (File f : files) {
renameFile(f.getAbsolutePath(), postfix, extension, ask,
delete, deepness);
}
}
} else if (file.canWrite()) {
String extOld = pfad.substring(pfad.lastIndexOf(".") + 1,
pfad.length());
if (extension == null) {
extension = extOld;
delete = false;
}
pfad = pfad.substring(0, pfad.lastIndexOf(".")) + postfix + "."
+ extension;
int conf = -1;
if (ask) {
conf = JOptionPane.showConfirmDialog(null, "Soll die Datei "
+ file.getName() + " umbenannt werden?",
"Best\u00E4tigung", JOptionPane.YES_NO_OPTION);
}
if (conf == JOptionPane.YES_OPTION || !ask) {
copyFile(file, new File(pfad));
if (delete) {
file.delete();
}
}
} else {
if (file.setWritable(true)) {
renameFile(file.getAbsolutePath(), postfix, extension, ask,
delete, deepness);
} else {
System.err.println("Anpassung der Schreibberechtigungen von "
+ file.getName() + "nicht m\u00F6glich!");
return;
}
}
}
public static void copyFile(File in, File out) {
FileChannel inChannel = null;
FileChannel outChannel = null;
try {
inChannel = new FileInputStream(in).getChannel();
outChannel = new FileOutputStream(out).getChannel();
inChannel.transferTo(0, inChannel.size(), outChannel);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (inChannel != null)
inChannel.close();
if (outChannel != null)
outChannel.close();
} catch (IOException e) {
}
}
}
public static void main(String[] args) {
String pfad = "/Users/joecze/test/";
MehrereDateienUmbenennen mdu = new MehrereDateienUmbenennen();
mdu.renameFile(pfad, null, "html", false, false, 2);
}
}
Zu Beginn der Methode renameFile
werden zunächst
ein mit null
übergebener Parameter postfix
in einen Leerstring gewandelt und anschließend ein File
-Objekt
mit dem übergebenen Pfad neu gebildet.
Es wird geprüft, ob hierbei ein Verzeichnis vorliegt. Ist dies
der Fall, wird es ausgelesen und sein Inhalt in ein File
-Array
geladen, sowie der Parameter deepness
dekrementiert. Er
bestimmt die Rekursionstiefe und darf minimal bei 0
liegen (s.o.). Für jedes im Array enthaltene File-Objekt wird
dann renameFile()
mit den ansonsten gleichen Parametern
rekursiv erneut aufgerufen.
Liegt kein Verzeichnis, sondern eine Datei vor, so werden zwei
Fälle unterschieden: Kann die Datei nicht beschrieben werden,
so wird versucht, deren Rechte entsprechend zu ändern und
anschließend renameFile()
erneut aufzurufen.
Gelingt dies nicht, so terminiert die Methode mit einer
Fehlermeldung.
Sind Schreibrechte gegeben, so wird zunächst die Dateiendung
ermittelt. Sie wird verwendet, wenn der Parameter extension
mit null
belegt ist, sodass die ursprüngliche
Erweiterung in diesem Fall an diesen Parameter übergeben werden
kann, sodass beim folgenden Vorgang des Extensions-Tauschs somit die
ursprüngliche Erweiterung wiederverwendet wird. Aus
Sicherheitsgründen wird in diesem Fall zudem das Löschen
der alten Datei verhindert, indem der Parameter delete
auf false
gesetzt wird.
Der Pfad des neuen File
-Objektes
wird dann aus dem Dateinamen bis zum letzten Punkt, dem
übergebenen Postfix, dem Punkt und der evtl. neuen Dateiendung
zusammengesetzt.
Wurde der Parameter ask
auf true
gesetzt, um bei der Umbenennung nachzufragen, so wird ein
entsprechender Dialog erzeugt, der, abhängig von der
angeklickten Option, einen int
-Wert zurückgibt.
Wurde hier OK
gewählt oder wurde auf eine
Nachfrage verzichtet, wird für den vorliegenden Pfad die
Methode File#copyFile()
aufgerufen. Sie kopiert das
'alte' File
-Objekt in das 'neue'. Abhängig vom
Parameter delete
wird ggf. die alte Datei
schließlich gelöscht.
Wenn Ihnen javabeginners.de gefällt, freue ich mich über eine Spende an diese gemeinnützigen Organisationen.