Pour ceux qui recherchent une solution générale, il peut s'agir de critères courants:
- Le nom de fichier doit ressembler à la chaîne.
- Le codage doit être réversible dans la mesure du possible.
- La probabilité de collision doit être minimisée.
Pour ce faire, nous pouvons utiliser regex pour faire correspondre les caractères illégaux, les encoder en pourcentage , puis contraindre la longueur de la chaîne encodée.
private static final Pattern PATTERN = Pattern.compile("[^A-Za-z0-9_\\-]");
private static final int MAX_LENGTH = 127;
public static String escapeStringAsFilename(String in){
StringBuffer sb = new StringBuffer();
// Apply the regex.
Matcher m = PATTERN.matcher(in);
while (m.find()) {
// Convert matched character to percent-encoded.
String replacement = "%"+Integer.toHexString(m.group().charAt(0)).toUpperCase();
m.appendReplacement(sb,replacement);
}
m.appendTail(sb);
String encoded = sb.toString();
// Truncate the string.
int end = Math.min(encoded.length(),MAX_LENGTH);
return encoded.substring(0,end);
}
Motifs
Le modèle ci-dessus est basé sur un sous-ensemble conservateur de caractères autorisés dans la spécification POSIX .
Si vous souhaitez autoriser le caractère point, utilisez:
private static final Pattern PATTERN = Pattern.compile("[^A-Za-z0-9_\\-\\.]");
Méfiez-vous simplement des chaînes telles que "." et ".."
Si vous souhaitez éviter les collisions sur les systèmes de fichiers insensibles à la casse, vous devrez échapper les majuscules:
private static final Pattern PATTERN = Pattern.compile("[^a-z0-9_\\-]");
Ou échapper aux lettres minuscules:
private static final Pattern PATTERN = Pattern.compile("[^A-Z0-9_\\-]");
Plutôt que d'utiliser une liste blanche, vous pouvez choisir de mettre sur liste noire les caractères réservés pour votre système de fichiers spécifique. EG Cette regex convient aux systèmes de fichiers FAT32:
private static final Pattern PATTERN = Pattern.compile("[%\\.\"\\*/:<>\\?\\\\\\|\\+,\\.;=\\[\\]]");
Longueur
Sur Android, 127 caractères est la limite de sécurité. De nombreux systèmes de fichiers autorisent 255 caractères.
Si vous préférez conserver la queue plutôt que la tête de votre corde, utilisez:
// Truncate the string.
int start = Math.max(0,encoded.length()-MAX_LENGTH);
return encoded.substring(start,encoded.length());
Décodage
Pour reconvertir le nom de fichier dans la chaîne d'origine, utilisez:
URLDecoder.decode(filename, "UTF-8");
Limites
Étant donné que les chaînes plus longues sont tronquées, il existe un risque de collision de noms lors du codage ou de corruption lors du décodage.