1

私はこれのフォローアップとしてこの小さなHelloWorldを書いていますが、数字は合計されません

filename = "testThis.txt"
total_bytes = 0
file = File.new(filename, "r")
file.each do |line|
  total_bytes += line.unpack("U*").length
end
puts "original size #{File.size(filename)}"
puts "Total bytes #{total_bytes}"

結果はファイルサイズと同じではありません。プラグインする必要があるものを知る必要があると思いますformat...または、要点を完全に見逃している可能性があります。ファイルサイズを1行ずつ測定するにはどうすればよいですか?

注:私はWindowsを使用しており、ファイルはタイプANSIとしてエンコードされています。

編集:これは同じ結果を生成します!

filename = "testThis.txt"
total_bytes = 0
file = File.new(filename, "r")
file.each_byte do |whatever|
  total_bytes += 1
end
puts "Original size #{File.size(filename)}"
puts "Total bytes #{total_bytes}"

だから今助けることができる人は誰でも...

4

6 に答える 6

2

あなたはIO#each_byteを試すかもしれません、例えば

total_bytes = 0
file_name = "test_this.txt"
File.open(file_name, "r") do |file|
  file.each_byte {|b| total_bytes += 1}
end
puts "Original size #{File.size(file_name)}"
puts "Total bytes #{total_bytes}"

もちろん、それは一度にあなたに一線を与えるものではありません。each_byteそのための最善のオプションは、に遭遇するまでファイルを経由することです\r\n。IOクラスは、役立つ可能性のある非常に低レベルの読み取りメソッドを多数提供します。

于 2009-03-09T23:32:48.270 に答える
2

IO#gets は、コマンド ラインから入力をキャプチャする場合と同じように機能します。「Enter」は入力の一部として送信されません。ファイルまたは IO の他のサブクラスで #gets が呼び出されたときにも渡されないため、数値は確実に一致しません。

関連するつるはしセクションを参照してください

行の長さの合計がファイル サイズになることをなぜそんなに気にかけているのかお尋ねしてもよろしいですか? 必要以上に難しい問題を解いているかもしれません...

あはは。私は今それを得ると思います。

便利な iPod (またはその他の種類) がないので、正確に 4K のチャンクが必要かどうかはわかりません。行ごとに分割する方が幸せです。その場合、次のようなものが機能するはずです。

class Chunkifier
  def Chunkifier.to_chunks(path)
    chunks, current_chunk_size = [""], 0
    File.readlines(path).each do |line|
      line.chomp! # strips off \n, \r or \r\n depending on OS
      if chunks.last.size + line.size >= 4_000 # 4096?
        chunks.last.chomp! # remove last line terminator
        chunks << ""
      end
      chunks.last << line + "\n" # or whatever terminator you need
    end
    chunks
  end
end

if __FILE__ == $0
  require 'test/unit'
  class TestFile < Test::Unit::TestCase
    def test_chunking
      chs = Chunkifier.to_chunks(PATH)
      chs.each do |chunk|
        assert 4_000 >= chunk.size, "chunk is #{chunk.size} bytes long"
      end
    end
  end
end

すべてのテキストを 1 回のスラープで取得するために IO#readlines を使用していることに注意してください: #each または #each_line も同様です。String#chomp を使用しました。OSが何をしていても、最後のバイトが削除されるようにするため、 \n または何でも出力に強制できるようになります。

出力には #print や #puts ではなく File#write を使用することをお勧めします。後者は OS 固有の改行シーケンスを提供する傾向があるためです。

マルチバイト文字が本当に気になる場合は、each_byte または unpack(C*) オプションを使用して、次のようなモンキー パッチ文字列を使用することを検討してください。

class String
  def size_in_bytes
    self.unpack("C*").size
  end
end

unpack バージョンは、私のマシンの each_byte バージョンよりも約 8 倍高速です。

于 2009-03-10T00:07:37.703 に答える
1

ここでいくつかの重複する問題が発生する可能性があります。

  1. 改行文字\r\n\n(以前の投稿による)。また、EOFファイル文字(^ Z)?

  2. 問題ステートメントでの「サイズ」の定義:「文字数」(マルチバイト文字エンコードを考慮)を意味しますか、それとも「バイト数」を意味しますか?

  3. $KCODEグローバル変数 の相互作用(ruby 1.9では非推奨。1.9でString#encoding実行している場合は、友達を参照してください)。たとえば、ファイルにアクセント付きの文字がありますか?

  4. のフォーマット文字列#unpackC*本当にバイト数を数えたいのなら、ここが欲しいと思います。

IO#each_line(を捨てて、whileもう少しルビーイディオムになることができるように;-))の存在にも注意してください。

于 2009-03-09T21:51:39.980 に答える
1

問題は、Windows でテキスト ファイルを保存する場合、改行が 2 文字 (文字 13 と 10) であるため 2 バイトであり、Linux で保存すると 1 (文字 10) しかないことです。ただし、ruby はこれらの両方を単一の文字 '\n' として報告します。文字 10 と表示されます。さらに悪いことに、Linux で Windows ファイルを使用している場合、ruby は両方の文字を表示します。

したがって、ファイルが常に Windows テキスト ファイルから取得され、Windows で実行されることがわかっている場合は、改行文字を取得するたびにカウントに 1 を追加できます。それ以外の場合は、いくつかの条件と小さなステート マシンです。

ところで、EOF「文字」はありません。

于 2009-03-11T06:43:29.367 に答える
0

現在のファイルポインタが読み取りファイルの行の先頭に設定されていると仮定すると、次の簡単な解決策があります。

    last_pos = file.pos
    next_line = file.gets
    current_pos = file.pos
    backup_dist = last_pos - current_pos
    file.seek(backup_dist, IO::SEEK_CUR)

この例では、「ファイル」は読み取り元のファイルです。これをループで行うには:

    last_pos = file.pos
    begin loop
        next_line = file.gets
        current_pos = file.pos
        backup_dist = last_pos - current_pos
        last_pos = current_pos
        file.seek(backup_dist, IO::SEEK_CUR)
    end loop
于 2013-03-30T21:42:05.870 に答える
0
f = File.new("log.txt")
begin
    while (line = f.readline)
        line.chomp
        puts line.length
    end
rescue EOFError
    f.close
end
于 2009-03-09T21:38:08.517 に答える