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

라인 윤곽을 파일에 저장 특수 문자가 있습니다

  • CR LF (0x0d로 0x0A) 윈도우/DOS에 (\ 연구 \ 없음) 및
  • 0x0A (\ n)도에 UNIX는 시스템.

루비의 gets은 유닉스 방식을 사용합니다. 따라서 Windows 파일을 읽으면 \ r \ n 바이트가 \ n으로 변환되므로 읽는 모든 행에 대해 1 바이트가 손실됩니다.

또한 String.length은 문자열 크기의 적절한 척도가 아닙니다 (바이트 단위). String가 ASCII가 아닌 경우 한 문자는 두 개 이상의 바이트 (유니 코드)로 표시 될 수 있습니다. 즉, 바이트 수가 아닌 문자열의 문자 수를 반환합니다.

파일 크기를 얻으려면 File.size(file_name)을 사용하십시오.

+0

실제로, 사용중인 Ruby 버전에 따라 str.length가 바이트 수 또는 문자 수를 반환 할 수 있습니다. (나는 1.8.6 이상을 믿고, 문자 수를, 그 전에는 바이트 수를 제공한다.) 이식성을 고려한다면, 한 가지 더 명심해야 할 점이있다. –

+0

이것은 아주 좋습니다. 추적 조사 좀 할래? http : // stackoverflow.com/questions/628096 –

3

내 생각 엔 당신이 Windows에 있고 "testThis.txt"파일의 줄 끝이 \ r \ n 인 것 같습니다. 텍스트 모드에서 파일을 열면 끝나는 각 줄은 단일 \ n 문자로 변환됩니다. 따라서 한 줄에 1 문자를 잃게됩니다.

테스트 파일에 60 줄이 있습니까? 그것은이 설명과 일치합니다.

3

줄 끝 문제가 가장 큰 원인입니다.

텍스트 파일의 문자 인코딩이 ASCII 이외의 문자 인 경우 두 문자간에 불일치가 생길 수도 있습니다. 파일이 UTF-8 인 경우 표준 ASCII 문자 만 사용하는 영어 및 일부 유럽 언어에서 작동합니다. 그 외에도 파일 크기와 문자 수는 크게 다를 수 있습니다 (문자 수에 비해 파일 크기가 최대 4 배 또는 6 배까지).

'1 문자 = 1 바이트'에 의존하는 것은 어떤 시점에서 거의 확실하게 실패 할 것이므로 문제를 묻는 것입니다.

+0

이제 진짜 질문 : 1 문자 = 1 바이트보다 나은 점은 무엇입니까? –

+0

1 문자 = 1 문자, 1 바이트 = 1 바이트 및 twain은 만나지 않아야합니다 :) – workmad3

+0

Terse,하지만 저는 아이디어를 얻었습니다. 내가 그것을 이해할 수 없다면 나는 다시 말 할 것이다. 감사! –

관련 문제