Pour ceux qui recherchent une solution générale, ceux-ci pourraient être commun critéres:
- Le nom de fichier doit ressembler à la chaîne.
- Le codage doit être réversible si possible.
- La probabilité de collisions doit être réduite au minimum.
Pour parvenir à cela, nous pouvons utiliser des regex pour correspondre à des caractères illégaux, % - encoder , puis de contraindre la longueur de la chaîne codée.
private static final Pattern PATTERN = Pattern.compile("[^A-Za-z0-9_]");
private static final int MAX_LENGTH = 127;
public static String escapeUrlAsFilename(String url){
StringBuffer sb = new StringBuffer();
// Apply the regex.
Matcher m = PATTERN.matcher(url);
while (m.find()) {
m.appendReplacement(sb,
// Convert matched character to percent-encoded.
"%"+Integer.toHexString(m.group().charAt(0)).toUpperCase()
);
}
m.appendTail(sb);
String encoded = sb.toString();
// Truncate the string.
int end = Math.min(encoded.length(),MAX_LENGTH);
return encoded.substring(0,end);
}
Modèles
Le schéma ci-dessus est basée sur un conservateur sous-ensemble de caractères autorisés dans la POSIX spec.
Si vous souhaitez autoriser le point de caractères, utilisez:
private static final Pattern PATTERN = Pattern.compile("[^A-Za-z0-9_\\.]");
Méfiez-vous des chaînes de caractères comme "." et ".."
Si vous voulez éviter les collisions à la casse des systèmes de fichiers, vous aurez besoin d'échapper capitales:
private static final Pattern PATTERN = Pattern.compile("[^a-z0-9_]");
Ou d'échapper à des lettres minuscules:
private static final Pattern PATTERN = Pattern.compile("[^A-Z0-9_]");
Plutôt que d'utiliser une liste blanche, vous pouvez choisir de la liste noire de caractères réservés pour votre système de fichiers. E. G. Cette expression convient pour les 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 permettent de 255 caractères.
Si vous préférez conserver la queue, plutôt que la tête de votre chaîne de caractères, utilisez:
// Truncate the string.
int start = Math.max(0,encoded.length()-MAX_LENGTH);
return encoded.substring(start,encoded.length());
Décodage
Pour convertir le nom de fichier dos à la chaîne d'origine, utilisez:
URLDecoder.decode(filename, "UTF-8");
Limitations
Parce que plus les chaînes de caractères sont tronqués, il ya la possibilité d'une collision de nom lors de l'encodage ou de la corruption lors du décodage.