2009-03-09 2 views
0

ファイルサイズが重要な場所で何かする必要があります。これは、このRubyはライン読み取りのために異なるファイルサイズを読み込みます

original size 20121 
Totals 20061 

がなぜ二つ目は短い来ているような奇妙な結果

filename = "testThis.txt" 
total_chars = 0 
file = File.new(filename, "r") 
file_for_writing = nil 
while (line = file.gets) 
    total_chars += line.length 
end 
puts "original size #{File.size(filename)}" 
puts "Totals #{total_chars}" 

を生産していますか?

編集:回答者の礼儀正しい:テストファイルには60行あります。この行を変更した場合

total_chars += line.length + 1 

これは完全に機能します。しかし、* nixではこの変更は間違っていますか?

編集:フォローアップは現在hereです。ありがとう!

+0

修正は、windozeでのみ動作します。 – workmad3

答えて

5

ラインを描くファイルに格納されている特殊文字があります。UNIX上でWindows/DOSと

  • は0x0A(\ n)が上

    • CR LF(0x0Dを0x0Aを)(\ r個の\ nは)システム。

    ルビーのgetsはUNIX方式を使用しています。したがって、Windowsファイルを読み込むと、\ r \ nバイトが\ nに変換されるので、読み込んだ行ごとに1バイトが失われます。

    また、String.lengthは、文字列のサイズ(バイト単位)の適切な尺度ではありません。文字列がASCIIでない場合、1文字は複数のバイト(Unicode)で表すことができます。つまり、バイト数ではなく文字列内の文字数を返します。

    ファイルのサイズを取得するには、File.size(file_name)を使用してください。

  • +0

    実際には、使用しているRubyのバージョンによっては、str.lengthがバイト数または文字数を返すことがあります。 (私は1.8.6以上を信じています、それはあなたに文字の数を与えます、その前に、バイト数。)あなたがこれを移植可能にすることを考えているなら、もう1つ注意してください。 –

    +0

    これは素晴らしいことです。あなたはフォローアップを見ていただけますか? http:// stackoverflow。com/questions/628096 –

    3

    私はあなたがWindows上にあり、あなたの "testThis.txt"ファイルは\ r \ n行末を持っていると推測します。ファイルをテキストモードで開くと、各行の終わりは1つの\ n文字に変換されます。したがって、1行に1文字を失います。

    テストファイルに60行ありますか?それはこの説明と一貫しています。

    3

    ここでは、行末の問題が原因である可能性が最も高いです。

    また、テキストファイルの文字エンコーディングがASCII以外のものである場合は、2との間に矛盾があることにも注意してください。ファイルがUTF-8の場合は、標準のASCIIアルファベット記号のみを使用する英語および一部のヨーロッパ言語で使用できます。それを超えると、ファイルサイズと文字数は大きく変動する可能性があります(文字数と比較してファイルサイズが最大4倍または6倍まで)。

    「1文字= 1バイト」に依存することは、ある時点でほぼ確実に失敗するため、問題を求めているだけです。

    +0

    本当の質問:1文字= 1バイトよりも優れているのは何ですか? –

    +0

    1文字= 1文字、1バイト= 1バイトと決して満たされなければならない:) – workmad3

    +0

    Terse、しかし私は考えを得る。もし私がそれを理解できないなら、私はコメントします。ありがとう! –

    関連する問題