Bagi mereka yang mencari solusi umum, ini mungkin kriteria umum:
- Nama file harus menyerupai string.
- Pengkodean harus dapat dibalik jika memungkinkan.
- Kemungkinan tabrakan harus diminimalkan.
Untuk mencapai ini, kita dapat menggunakan regex untuk mencocokkan karakter ilegal, mengenkodenya dalam persen , lalu membatasi panjang string yang dikodekan.
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);
}
Pola
Pola di atas didasarkan pada subset konservatif dari karakter yang diperbolehkan dalam spesifikasi POSIX .
Jika Anda ingin mengizinkan karakter titik, gunakan:
private static final Pattern PATTERN = Pattern.compile("[^A-Za-z0-9_\\-\\.]");
Berhati-hatilah dengan string seperti "." dan ".."
Jika Anda ingin menghindari tabrakan pada sistem file yang tidak peka huruf besar kecil, Anda harus keluar dari kapital:
private static final Pattern PATTERN = Pattern.compile("[^a-z0-9_\\-]");
Atau hindari huruf kecil:
private static final Pattern PATTERN = Pattern.compile("[^A-Z0-9_\\-]");
Daripada menggunakan daftar putih, Anda dapat memilih untuk memasukkan karakter yang dicadangkan ke daftar hitam untuk sistem file spesifik Anda. EG Regex ini sesuai dengan sistem file FAT32:
private static final Pattern PATTERN = Pattern.compile("[%\\.\"\\*/:<>\\?\\\\\\|\\+,\\.;=\\[\\]]");
Panjangnya
Di Android, 127 karakter adalah batas aman. Banyak sistem file mengizinkan 255 karakter.
Jika Anda lebih suka mempertahankan ekor, daripada kepala senar, gunakan:
// Truncate the string.
int start = Math.max(0,encoded.length()-MAX_LENGTH);
return encoded.substring(start,encoded.length());
Decoding
Untuk mengubah nama file kembali ke string asli, gunakan:
URLDecoder.decode(filename, "UTF-8");
Batasan
Karena string yang lebih panjang dipotong, ada kemungkinan nama bertabrakan saat encoding, atau rusak saat decoding.