64 votes

Existe-t-il une méthode Java multiplateforme pour supprimer les caractères spéciaux de nom de fichier?

Je suis en train de faire une application multiplate-forme qui renomme les fichiers en fonction des données récupérées en ligne. Je tiens à désinfecter les Cordes j'ai pris à partir d'une API web pour la plate-forme actuelle.

Je sais que les différentes plates-formes ont différentes de nom de fichier exigences, donc je me demandais si il y a une croix-plate-forme de façon de le faire?

Edit: Sur les plates-formes Windows, vous ne pouvez pas avoir un point d'interrogation"? " dans un nom de fichier, alors que sous Linux, vous pouvez. Les noms de fichier peuvent contenir de tels personnages et j'aimerais que les plates-formes qui prennent en charge ces caractères pour les garder, mais sinon, bande de sortir.

Aussi, je préfère un standard de Java solution qui ne nécessite pas de bibliothèques tierces.

33voto

Sarel Botha Points 5911

Comme le suggère d'ailleurs, ce n'est généralement pas ce que vous voulez faire. Il est généralement préférable de créer un fichier temporaire à l'aide d'une méthode sécurisée de Fichiers.createTempFile().

Vous ne devriez pas le faire avec une liste blanche et de ne garder que les "bonnes" des personnages. Si le fichier ne contient que des caractères Chinois, alors vous dépouiller de tout, hors de lui. Nous ne pouvons pas utiliser une liste blanche pour cette raison, nous devons utiliser une liste noire.

Linux assez bien permet de tout ce qui peut être une vraie douleur. Je voudrais juste limite Linux à la même liste que vous limiter à Windows de sorte que vous enregistrez vous-même des maux de tête à l'avenir.

L'utilisation de ce C# extrait sur Windows, j'ai produit une liste de caractères qui ne sont pas valides sur Windows. Il ya tout à fait quelques personnages de plus dans cette liste que vous pouvez penser (41), de sorte que je ne recommande pas d'essayer de créer votre propre liste.

        foreach (char c in new string(Path.GetInvalidFileNameChars()))
        {
            Console.Write((int)c);
            Console.Write(",");
        }

Ici est une simple classe Java qui "nettoie" un nom de fichier.

public class FileNameCleaner {
final static int[] illegalChars = {34, 60, 62, 124, 0, 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, 58, 42, 63, 92, 47};
static {
    Arrays.sort(illegalChars);
}
public static String cleanFileName(String badFileName) {
    StringBuilder cleanName = new StringBuilder();
    for (int i = 0; i < badFileName.length(); i++) {
        int c = (int)badFileName.charAt(i);
        if (Arrays.binarySearch(illegalChars, c) < 0) {
            cleanName.append((char)c);
        }
    }
    return cleanName.toString();
}
}

EDIT: Comme Stephen suggéré probablement vous devriez également vérifier que ces fichiers ne peut accéder qu'à se produire au sein de l'annuaire vous permettent.

La réponse suivante est un exemple de code pour la création d'un custom contexte de sécurité en Java et donc l'exécution de code dans 'bac à sable'.

Comment voulez-vous créer une sécurité JEXL (script) sandbox?

28voto

Dirk Points 1309

ou tout simplement faire ceci:

String filename = "A20/B22b#öA\\BC#Ä$%ld_ma.la.xps";
String sane = filename.replaceAll("[^a-zA-Z0-9\\._]+", "_");

Résultat: A20_B22b_A_BC_ld_ma.la.xps

Explication:

[a-zA-Z0-9\\._] correspond à une lettre de a à z, en minuscules ou en majuscules, des nombres, des points et des traits de soulignement

[^a-zA-Z0-9\\._] est l'inverse. c'est à dire tous les caractères qui ne correspondent pas à la première expression

[^a-zA-Z0-9\\._]+ est une séquence de caractères qui ne correspondent pas à la première expression

Ainsi, chaque séquence de caractères qui ne sont pas constitués de caractères a-z, 0-9 ou . _ va être remplacé.

9voto

Aaron Digulla Points 143830

Voici le code que j'utilise:

 public static String sanitizeName( String name ) {
    if( null == name ) {
        return "";
    }

    if( SystemUtils.IS_OS_LINUX ) {
        return name.replaceAll( "/+", "" ).trim();
    }

    return name.replaceAll( "[\u0001-\u001f<>:\"/\\\\|?*\u007f]+", "" ).trim();
}
 

SystemUtils provient d' Apache commons-lang3

6voto

Carboni Points 469

Il existe une très bonne solution Java intégrée - Character.isXxx () .

Essayez Character.isJavaIdentifierPart(c) :

 String name = "name.é+!@#$%^&*(){}][/=?+-_\\|;:`~!'\",<>";
StringBuilder filename = new StringBuilder();

for (char c : name.toCharArray()) {
  if (c=='.' || Character.isJavaIdentifierPart(c)) {
    filename.append(c);
  }
}
 

Le résultat est "name.é $ _".

5voto

Stephen C Points 255558

Il n'est pas clair à partir de votre question, mais puisque vous êtes planification à accepter des chemins d'accès à partir d'un formulaire web (?) vous avez probablement devrait bloquer les tentatives de renommer certaines choses; par exemple, "C:\Program les Fichiers". Cela implique que vous devez accepter les chemins d'accès afin d'éliminer les "." et ".." avant de faire vos contrôles d'accès.

Étant donné que, je ne voudrais pas essayer d'enlever des caractères illégaux. Au lieu de cela, j'utiliserais "nouveau Fichier(str).getCanonicalFile()" afin de produire de l'canonique chemins, à côté de vérifier qu'ils remplissent votre bac à sable restrictions, et enfin l'utilisation de Fichiers".exists()", "Fichier.isFile()", etc pour vérifier que la source et la destination sont casher, et ne sont pas le même système de fichier de l'objet. Je préfère traiter avec des caractères illégaux en essayant de faire les opérations et attraper les exceptions.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X