Frage

    

Diese Frage bereits eine Antwort hier:

         

In meiner Java-Anwendung Ich bin das Umbenennen von Dateien auf einen Dateinamen in einem String-Parametern zur Verfügung gestellt. Es gibt ein Verfahren

boolean OKtoRename(String oldName, String newName)

, die im Grunde überprüft, ob der newName nicht bereits durch eine andere Datei genommen, da ich nicht bestehende begraben möchte.

Es kam mir jetzt, dass vielleicht das newName String keinen gültigen Dateinamen bezeichnen. Also dachte ich, diese Überprüfung der Methode hinzuzufügen:

if (new File(newName).isFile()) { 
    return false; 
}

, die offensichtlich nicht der richtige Weg ist, es zu tun, da in den meisten Fällen die newFile noch nicht existiert und daher, obwohl es ist OKtoRename, die Funktion false zurück.

Ich habe mich gefragt, gibt es ein Verfahren (Ich weiß, es ist nicht für die java.io.File Objekte) wie canExist()? Oder hätte ich greifen, um regex das newFile String um sicherzustellen, dass keine ungültigen Zeichen enthält (zB?, *,“:)? Ich frage mich, ob es vielleicht eine Funktion irgendwo im JDK versteckt, dass mir sagen würde, wenn ein String möglicherweise einen gültigen Dateinamen bezeichnen könnte.

War es hilfreich?

Lösung

Verwenden Sie createNewFile() , die atomar die Datei erstellen wird nur, wenn es noch nicht existiert.

Wenn die Datei erstellt wird, ist der Name gültig und es ist nicht eine vorhandene Datei clobbering. Anschließend können Sie die Dateien öffnen und Daten effizient kopieren von einem zum anderen mit FileChannel.transferXXX Operationen.

Eine wichtige Sache im Auge zu behalten, dass im Allgemeinen die Überprüfung und die Schaffung Atom sein sollten. Wenn Sie zunächst prüfen, ob eine Operation sicher ist, dann führen Sie den Vorgang als separater Schritt haben sich die Bedingungen in der Zwischenzeit verändert haben, so dass der Betrieb unsicher.

Weitere Denkanstösse sind in diesem Zusammenhang Post zur Verfügung: "Move / Copy-Operationen in Java. "


Update:

Da diese Antwort haben die NIO.2 APIs eingeführt, die mehr Interaktion mit dem Dateisystem hinzufügen.

Angenommen, Sie ein interaktives Programm haben, und wollen überprüfen nach jedem Tastendruck, ob die Datei möglicherweise gültig ist. Zum Beispiel können Sie eine Schaltfläche „Speichern“ nur aktivieren, wenn der Eintrag gültig ist, anstatt einen Fehlerdialog Aufspringen nach „Speichern“ drücken. Erstellen und das Löschen einer Menge unnötiger Dateien zu gewährleisten, der über meinen Vorschlag wäre scheint wie ein Chaos erfordern.

Mit NIO.2, können Sie keine Path Instanz enthält Zeichen erstellen, die für das Dateisystem illegal sind. Ein InvalidPathException wird so schnell angehoben, wie Sie versuchen, den Path zu erstellen.

bestehend aus gültigen Zeichen, wie „PRN“ unter Windows

Allerdings ist es nicht ein API illegale Namen zu bestätigen. Zur Umgehung des Problems zeigte Experimente, dass eine illegale Dateinamen verwenden würde eine deutliche Ausnahme auslösen, wenn sie Zugang Attribute (mit Files.getLastModifiedTime(), zum Beispiel) zu versuchen.

Wenn Sie einen Rechtsnamen für eine Datei angeben, die nicht vorhanden ist, erhalten Sie keine Ausnahme.

Wenn Sie einen Rechtsnamen für eine Datei angeben, die nicht vorhanden ist, wirft es NoSuchFileException.

Wenn Sie einen unzulässigen Namen angeben, wird FileSystemException angehoben.

Dies scheint jedoch sehr kludgey und möglicherweise nicht auf anderen Betriebssystemen zuverlässig sein.

Andere Tipps

zusammengebaut ich eine Liste von illegalen Dateinamen Zeichen (unter Berücksichtigung UNIX, Mac OS X und Windows-Systeme), basierend auf einigen Online-Forschung vor ein paar Monaten. Wenn der neue Dateiname eines dieser enthält, besteht die Gefahr, dass es nicht auf allen Plattformen gültig sein könnte.

private static final char[] ILLEGAL_CHARACTERS = { '/', '\n', '\r', '\t', '\0', '\f', '`', '?', '*', '\\', '<', '>', '|', '\"', ':' };

EDIT: Ich möchte betonen,, dass dies keine vollständige Lösung : als Kommentator wies darauf hin, auch wenn er diesen Test besteht Ihre Dateinamen noch ein Windows-spezifische Schlüsselwörter wie COM, PRN sein könnte, usw. Allerdings, wenn Ihr Dateinamen eines dieser Zeichen enthält, wird es sicherlich Probleme in einer Cross-Plattform-Umgebung führen.

Hier systemspezifische Art und Weise vorgeschlagen wird.

public static boolean isFilenameValid(String file) {
  File f = new File(file);
  try {
    f.getCanonicalPath();
    return true;
  } catch (IOException e) {
    return false;
  }
}

Wenn für Eclipse entwickeln Besuche org.eclipse.core.internal.resources.OS

public abstract class OS {
   private static final String INSTALLED_PLATFORM;

   public static final char[] INVALID_RESOURCE_CHARACTERS;
   private static final String[] INVALID_RESOURCE_BASENAMES;
   private static final String[] INVALID_RESOURCE_FULLNAMES;

   static {
      //find out the OS being used
      //setup the invalid names
      INSTALLED_PLATFORM = Platform.getOS();
      if (INSTALLED_PLATFORM.equals(Platform.OS_WIN32)) {
         //valid names and characters taken from http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/naming_a_file.asp
         INVALID_RESOURCE_CHARACTERS = new char[] {'\\', '/', ':', '*', '?', '"', '<', '>', '|'};
         INVALID_RESOURCE_BASENAMES = new String[] {"aux", "com1", "com2", "com3", "com4", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ 
               "com5", "com6", "com7", "com8", "com9", "con", "lpt1", "lpt2", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$
               "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9", "nul", "prn"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$
         Arrays.sort(INVALID_RESOURCE_BASENAMES);
         //CLOCK$ may be used if an extension is provided
         INVALID_RESOURCE_FULLNAMES = new String[] {"clock$"}; //$NON-NLS-1$
      } else {
         //only front slash and null char are invalid on UNIXes
         //taken from http://www.faqs.org/faqs/unix-faq/faq/part2/section-2.html
         INVALID_RESOURCE_CHARACTERS = new char[] {'/', '\0',};
         INVALID_RESOURCE_BASENAMES = null;
         INVALID_RESOURCE_FULLNAMES = null;
      }
   }

   /**
    * Returns true if the given name is a valid resource name on this operating system,
    * and false otherwise.
    */
   public static boolean isNameValid(String name) {
      //. and .. have special meaning on all platforms
      if (name.equals(".") || name.equals("..")) //$NON-NLS-1$ //$NON-NLS-2$
         return false;
      if (INSTALLED_PLATFORM.equals(Platform.OS_WIN32)) {
         //empty names are not valid
         final int length = name.length();
         if (length == 0)
            return false;
         final char lastChar = name.charAt(length-1);
         // filenames ending in dot are not valid
         if (lastChar == '.')
            return false;
         // file names ending with whitespace are truncated (bug 118997)
         if (Character.isWhitespace(lastChar))
            return false;
         int dot = name.indexOf('.');
         //on windows, filename suffixes are not relevant to name validity
         String basename = dot == -1 ? name : name.substring(0, dot);
         if (Arrays.binarySearch(INVALID_RESOURCE_BASENAMES, basename.toLowerCase()) >= 0)
            return false;
         return Arrays.binarySearch(INVALID_RESOURCE_FULLNAMES, name.toLowerCase()) < 0;
      }
      return true;
   }
}

Dies ist, wie ich dies umgesetzt:

public boolean isValidFileName(final String aFileName) {
    final File aFile = new File(aFileName);
    boolean isValid = true;
    try {
        if (aFile.createNewFile()) {
            aFile.delete();
        }
    } catch (IOException e) {
        isValid = false;
    }
    return isValid;
}

Für mich scheint es, ein Betriebssystem abhängig Problem. Sie können einfach für einige ungültige Zeichen im Dateinamen überprüfen möchten. Windows tut dies, wenn Sie versuchen, die Datei umzubenennen, es erscheint eine Meldung, die besagt, dass eine Datei keine der folgenden Zeichen enthalten: \ /: *? <> | Ich bin nicht sicher, ob Ihre Frage: „Gibt es eine Bibliothek, die die Arbeit für mich tun?“ in diesem Fall weiß ich nicht.

Nur etwas, das ich gefunden, in Java 7 und später gibt es eine Klasse mit dem Namen Paths , die eine Methode namens get hat, die eine oder mehrere Strings nimmt und wirft

  

InvalidPathException - wenn die Pfadzeichenfolge kann nicht auf einen Pfad umgewandelt werden

Mit

String validName = URLEncoder.encode( fileName , "UTF-8");

File newFile = new File( validName );

macht die Arbeit.

Ich habe gerade heute gefunden. Ich bin mir nicht sicher, ob es 100% der Zeit funktioniert, aber bisher habe ich gültige Dateinamen zu erhalten konnten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top