2011-04-25 7 views
2

Android에서 재귀 적 디렉토리 검색을 사용하여 검색 문자열을 파일 이름과 대조하려고합니다. 문제는 문자가 일본어이고 경우에 따라 일치하지 않는다는 것입니다. 예를 들어, 파일 이름의 시작과 일치시키려는 검색 문자열은 "呼 ぶ"입니다. file.getName()에서 파일 이름을 인쇄 할 때이를 정확하게 반영합니다. 콘솔에 인쇄 된 파일 이름은 "呼 ぶ"로 시작합니다. 하지만 검색 문자열에 일치 항목을 지정할 때 fileName.startwith ("呼 ぶ"), 그것은 일치하지 않습니다.안드로이드, 일본어 문자로 된 파일 이름 비교 문제

검색 할 파일 이름의 하위 문자열을 인쇄 할 때 두 번째 문자가 다르다는 것을 알게되었습니다. 단어는 "呼 ぶ"대신 "呼 ふ"입니다. 바이트를 추출하여 16 진수 문자를 출력하면 마지막 바이트는 1 씩 어긋납니다. "ぶ"와 "ふ"의 차이 일 것입니다.

String name = soundFile.getName(); 
    String string1 = question.kanji; 


    Log.d(TAG, "searching for : s1:" + question.kanji + " + " + question.hiragana + " + " + question.english); 
    Log.d(TAG, "name is: " + name); 

    Log.d(TAG, "question.kanaji.length(): " + question.kanji.length()); 
    Log.d(TAG, "question.hiragana.length(): " + question.hiragana.length()); 


    String compareStart = name.substring(0, string1.length()); 

    Log.d(TAG, "string1.length(): " + string1.length()); 
    Log.d(TAG, "compareStart.length(): " + compareStart.length());  

     byte[] nameUTF8 = null; 
    byte[] s1UTF8 = null; 
    byte[] csUTF8 = null; 

    nameUTF8 = name.getBytes(); 
    s1UTF8 = string1.getBytes(); 
    csUTF8 = compareStart.getBytes(); 


    Log.d(TAG, "nameUTF8.length: " + s1UTF8.length);    
    Log.d(TAG, "s1UTF8.length: " + s1UTF8.length); 
    Log.d(TAG, "csUTF8.length: " + csUTF8.length); 

    for (int i = 0; i < s1UTF8.length; i++) { 
     Log.d(TAG, "s1UTF8[i]: " + Integer.toString(s1UTF8[i] & 0xff, 16).toUpperCase()); 
    } 

    for (int i = 0; i < csUTF8.length; i++) { 
     Log.d(TAG, "csUTF8[i]: " + Integer.toString(csUTF8[i] & 0xff, 16).toUpperCase()); 
    } 

    for (int i = 0; i < nameUTF8.length; i++) { 
     Log.d(TAG, "nameUTF8[i]: " + Integer.toString(nameUTF8[i] & 0xff, 16).toUpperCase()); 
    } 

부분 출력은 다음과 같다 : 여기서

차이 표시하는 데 사용하는 코드이다

D/AnswerView(12078): searching for : s1:呼ぶ + よぶ + to call out,to invite 
D/AnswerView(12078): name is: 呼ぶ              よぶ     to call out,to invite.mp3 
D/AnswerView(12078): question.kanaji.length(): 2 
D/AnswerView(12078): question.hiragana.length(): 2 
D/AnswerView(12078): string1: 呼ぶ 
D/AnswerView(12078): compareStart: 呼ふ 
D/AnswerView(12078): string1.length(): 2 
D/AnswerView(12078): compareStart.length(): 2 
D/AnswerView(12078): string1.length(): 2 
D/AnswerView(12078): compareStart.length(): 2 
D/AnswerView(12078): nameUTF8.length: 6 
D/AnswerView(12078): s1UTF8.length: 6 
D/AnswerView(12078): csUTF8.length: 6 
D/AnswerView(12078): s1UTF8[i]: E5 
D/AnswerView(12078): s1UTF8[i]: 91 
D/AnswerView(12078): s1UTF8[i]: BC 
D/AnswerView(12078): s1UTF8[i]: E3 
D/AnswerView(12078): s1UTF8[i]: 81 
D/AnswerView(12078): s1UTF8[i]: B6 
D/AnswerView(12078): csUTF8[i]: E5 
D/AnswerView(12078): csUTF8[i]: 91 
D/AnswerView(12078): csUTF8[i]: BC 
D/AnswerView(12078): csUTF8[i]: E3 
D/AnswerView(12078): csUTF8[i]: 81 
D/AnswerView(12078): csUTF8[i]: B5 
D/AnswerView(12078): nameUTF8[i]: E5 
D/AnswerView(12078): nameUTF8[i]: 91 
D/AnswerView(12078): nameUTF8[i]: BC 
D/AnswerView(12078): nameUTF8[i]: E3 
D/AnswerView(12078): nameUTF8[i]: 81 
D/AnswerView(12078): nameUTF8[i]: B5 
D/AnswerView(12078): nameUTF8[i]: E3 
D/AnswerView(12078): nameUTF8[i]: 82 
D/AnswerView(12078): nameUTF8[i]: 99 
D/AnswerView(12078): nameUTF8[i]: 20 
D/AnswerView(12078): nameUTF8[i]: 20 
D/AnswerView(12078): nameUTF8[i]: 20 
D/AnswerView(12078): nameUTF8[i]: 20 

게재하는 파일 이름의 압축 문자열의 여섯 번째 바이트로서 파일 이름 자체는 검색 문자열에있는 그대로 "B6"대신 "B5"입니다. 그러나 인쇄 된 파일 이름이 올바르게 표시됩니다. 나는 혼란 스럽다. 기본 문자가 다른 경우 파일 이름이 콘솔에 올바르게 표시되는 이유는 무엇입니까? 파일 이름의 시작 부분에 3 개의 비어 있지 않은 바이트가 추가로있는 이유는 무엇입니까? "ぶ"문자를 나타 내기 위해 검색 문자열에 필요하지 않은 것은 무엇입니까?

답변

2

문제는 정규화 양식 중 하나 인 것처럼 보입니다. 예를 들어, Mac에서는 파일 시스템이 항상 NFD에 있다는 것을 알고 있습니다. 하지만 게시 한 문자열은 NFC에 있습니다. 보기 :

% cat /tmp/u 
呼ぶ 

% uwc /tmp/u 
    Paras Lines Words Graphs Chars Bytes File 
     0  1  1  3  3  7 /tmp/u 

% uniquote -v /tmp/u 
\N{CJK UNIFIED IDEOGRAPH-547C}\N{HIRAGANA LETTER BU} 

% nfd /tmp/u | uniquote -v 
\N{CJK UNIFIED IDEOGRAPH-547C}\N{HIRAGANA LETTER HU}\N{COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK} 

% nfc /tmp/u | uniquote -v 
\N{CJK UNIFIED IDEOGRAPH-547C}\N{HIRAGANA LETTER BU} 

그래서 나는 NFD로 전환하는 것에 대해 생각해야한다고 생각합니다.

BTW, U + 547C CJK 코드 포인트는 Unihan 데이터베이스에서이 될 일이 있다는 : 여기

呼 U+547C Lo Han CJK UNIFIED IDEOGRAPH-547C 
    Mandarin  hu1 xu1 
    Cantonese fu1 
    JapaneseKun yobu 
    JapaneseOn ko 
    Korean  ho 
    HanyuPinlu hu1(378) hu5(107) 
    Vietnamese hô 
+0

이렇게하면 문제가 설명됩니다. 추가 3 바이트가 있기 때문에 파일 이름은 NFD 여야합니다.이 파일은 "ふ"를 "υ"로 변환하는 추가 squiggles입니다. Java (노말 라이저 사용)의 솔루션뿐만 아니라이를 설명하는 링크를 발견했습니다. http://weblogs.java.net/blog/joconner/archive/2007/02/normalization_c.html –

0
String compareStart = name.substring(0, string1.length()); 

당신이 name 슬라이스를 string1에서 가져온 길이를 사용하고 있습니다. Tom이 지적했듯이, 문자열은 다른 정규화 형식에 있으므로 길이가 일치 할 필요는 없습니다.

관련 문제