일반적인 솔루션을 찾는 사람들에게는 다음과 같은 일반적인 기준이있을 수 있습니다.
- 파일 이름은 문자열과 유사해야합니다.
- 인코딩은 가능한 경우 되돌릴 수 있어야합니다.
- 충돌 가능성을 최소화해야합니다.
이를 달성하기 위해 정규식을 사용하여 잘못된 문자를 일치 시키고 퍼센트 인코딩 한 다음 인코딩 된 문자열의 길이를 제한 할 수 있습니다.
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이 정규식은 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");
한계
긴 문자열은 잘 리기 때문에 인코딩시 이름 충돌이 발생하거나 디코딩시 손상 될 수 있습니다.