สำหรับผู้ที่มองหาวิธีแก้ปัญหาทั่วไปสิ่งเหล่านี้อาจเป็น critera ทั่วไป:
- ชื่อไฟล์ควรคล้ายกับสตริง
- การเข้ารหัสควรย้อนกลับได้หากทำได้
- ควรลดความน่าจะเป็นของการชนให้น้อยที่สุด
เพื่อให้บรรลุสิ่งนี้เราสามารถใช้ regex เพื่อจับคู่อักขระที่ผิดกฎหมายเข้ารหัสเปอร์เซ็นต์เหล่านั้นจากนั้น จำกัด ความยาวของสตริงที่เข้ารหัส
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);
}
รูปแบบ
รูปแบบดังกล่าวข้างต้นจะขึ้นอยู่กับเซตอนุลักษณ์ของตัวละครที่ได้รับอนุญาตในข้อมูลจำเพาะ POSIX
หากคุณต้องการอนุญาตให้ใช้อักขระจุด:
private static final Pattern PATTERN = Pattern.compile("[^A-Za-z0-9_\\-\\.]");
ระวังสตริงเช่น "." และ ".. "
หากคุณต้องการหลีกเลี่ยงการชนกันในระบบไฟล์ที่ไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่คุณจะต้องหลีกเลี่ยงตัวพิมพ์ใหญ่:
private static final Pattern PATTERN = Pattern.compile("[^a-z0-9_\\-]");
หรือหลีกหนีอักษรตัวพิมพ์เล็ก:
private static final Pattern PATTERN = Pattern.compile("[^A-Z0-9_\\-]");
แทนที่จะใช้รายการที่อนุญาตคุณอาจเลือกที่จะขึ้นบัญชีดำอักขระที่สงวนไว้สำหรับระบบไฟล์เฉพาะของคุณ EG regex นี้เหมาะกับระบบไฟล์ FAT32:
private static final Pattern PATTERN = Pattern.compile("[%\\.\"\\*/:<>\\?\\\\\\|\\+,\\.;=\\[\\]]");
ความยาว
บน Android 127 อักขระคือขีด จำกัด ที่ปลอดภัย ระบบไฟล์จำนวนมากอนุญาต 255 อักขระ
หากคุณต้องการคงหางไว้แทนที่จะเป็นส่วนหัวของสตริงให้ใช้:
// Truncate the string.
int start = Math.max(0,encoded.length()-MAX_LENGTH);
return encoded.substring(start,encoded.length());
ถอดรหัส
ในการแปลงชื่อไฟล์กลับเป็นสตริงเดิมให้ใช้:
URLDecoder.decode(filename, "UTF-8");
ข้อ จำกัด
เนื่องจากสตริงที่ยาวกว่าถูกตัดทอนจึงมีความเป็นไปได้ที่ชื่อจะชนกันเมื่อเข้ารหัสหรือเกิดความเสียหายเมื่อถอดรหัส