Für diejenigen, die nach einer allgemeinen Lösung suchen, können dies häufige Kriterien sein:
- Der Dateiname sollte der Zeichenfolge ähneln.
- Die Codierung sollte nach Möglichkeit reversibel sein.
- Die Wahrscheinlichkeit von Kollisionen sollte minimiert werden.
Um dies zu erreichen, können wir Regex verwenden, um unzulässige Zeichen abzugleichen, sie in Prozent zu codieren und dann die Länge der codierten Zeichenfolge zu beschränken.
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);
}
Muster
Das obige Muster basiert auf einer konservativen Teilmenge zulässiger Zeichen in der POSIX-Spezifikation .
Wenn Sie das Punktzeichen zulassen möchten, verwenden Sie:
private static final Pattern PATTERN = Pattern.compile("[^A-Za-z0-9_\\-\\.]");
Seien Sie vorsichtig mit Saiten wie "." und ".."
Wenn Sie Kollisionen in Dateisystemen ohne Berücksichtigung der Groß- und Kleinschreibung vermeiden möchten, müssen Sie Großbuchstaben umgehen:
private static final Pattern PATTERN = Pattern.compile("[^a-z0-9_\\-]");
Oder entkommen Sie Kleinbuchstaben:
private static final Pattern PATTERN = Pattern.compile("[^A-Z0-9_\\-]");
Anstatt eine Whitelist zu verwenden, können Sie reservierte Zeichen für Ihr spezifisches Dateisystem auf die schwarze Liste setzen. EG Dieser reguläre Ausdruck passt zu FAT32-Dateisystemen:
private static final Pattern PATTERN = Pattern.compile("[%\\.\"\\*/:<>\\?\\\\\\|\\+,\\.;=\\[\\]]");
Länge
Unter Android sind 127 Zeichen die sichere Grenze. Viele Dateisysteme erlauben 255 Zeichen.
Wenn Sie lieber den Schwanz als den Kopf Ihrer Schnur behalten möchten, verwenden Sie:
// Truncate the string.
int start = Math.max(0,encoded.length()-MAX_LENGTH);
return encoded.substring(start,encoded.length());
Dekodierung
Verwenden Sie Folgendes, um den Dateinamen wieder in die ursprüngliche Zeichenfolge zu konvertieren:
URLDecoder.decode(filename, "UTF-8");
Einschränkungen
Da längere Zeichenfolgen abgeschnitten werden, besteht die Möglichkeit einer Namenskollision beim Codieren oder einer Beschädigung beim Decodieren.