2012-12-09 59 views
5

下午好。假設我有一個帶有單個字母的utf-8文件,比如說「f」(no \ n和空格),我嘗試獲得一系列的行長度。帶有BOM的UTF-8文件中第一行的長度

(with-open [rdr (reader "test.txt")] 
    (doall (map #(.length %) (line-seq rdr)))) 

我也得到

=> (2) 

爲什麼?有沒有優雅的方式來獲得第一個字符串的正確長度?

+0

我無法複製它。我在UTF-8文件中使用了包含單字節或雙字節字符的代碼,結尾處都帶有或不帶'\ n'。在所有情況下,我得到了'(1)'。你的Clojure版本是什麼? – Jan

+2

只是一個隨意的想法,如果你把BOM放在你的測試文件中怎麼辦? – SirDarius

+0

我的Clojure版本是1.4。是的,實際上是BOM。我怎麼能繞過這個問題? –

回答

7

有關Java中BOM的問題,請參閱Reading UTF-8 - BOM marker。看來,它可以使用從Apache的共享BOMInputStream或者抽象掉它必須手動刪除,即

(defn debomify 
    [^String line] 
    (let [bom "\uFEFF"] 
    (if (.startsWith line bom) 
     (.substring line 1) 
     line))) 

(doall (map #(.length %) (.split (debomify (slurp "test.txt")) "\n"))) 

如果你想讀懶洋洋地使用line-seq文件,例如,因爲它是巨大的,你要像對待第一行使用debomify。其餘的可以正常讀取。因此:

(defn debommed-line-seq 
    [^java.io.BufferedReader rdr] 
    (when-let [line (.readLine rdr)] 
    (cons (debomify line) (lazy-seq (line-seq rdr))))) 
+0

謝謝。也許這是一個解決方案。 –

+0

感謝您提供更詳細的版本。 –

+0

也許更理想的方法是簡單地(debomify(slurp「test.txt」))然後分割它。 –

相關問題