2009-08-24 5 views
3

파일에서 부호없는 정수를 읽으려고합니다 (연속 바이트로 저장 됨) 정수로 변환하려고합니다. 나는 이것을 시도했다 :루비 - 파일에서 바이트를 읽고 정수로 변환

file = File.new(filename,"r") 
num = file.read(2).unpack("S") #read an unsigned short 
puts num #value will be less than expected 

내가 뭘 잘못하고 있니?

답변

1

좋아, 내가이 일을하는 데 : 모두를위한

num = file.read(8).unpack("N") 

감사합니다 당신의 도움.

0

파일에 저장된 숫자의 형식은 무엇입니까? 16 진수입니까? 귀하의 코드가 나에게 맞는 것 같습니다.

+0

VM 사양에 따르면 "멀티 바이트 데이터 항목은 항상 상위 바이트가 먼저 오는 빅 엔디안 순서로 저장됩니다." – Peter

1

이진 데이터를 처리 할 때는 Windows에서 이진 모드로 파일을 여는 지 확인해야합니다. 이것은 읽기와 쓰기 모두에 해당됩니다.

open(filename, "rb") do |file| 
    num = file.read(2).unpack("S") 
    puts num 
end 

원본 플랫폼에 따라 "엔디안"인코딩 문제가있을 수 있습니다. 예를 들어 PowerPC 기반 시스템에는 이전 Mac 시스템, IBM Power 서버, PS3 클러스터 또는 Sun Sparc 서버가 포함됩니다.

'덜'이라는 예를 게시 할 수 있습니까? 일반적으로 데이터에는 명백한 패턴이 있습니다.

예를 들어 0x1234를 원하지만 0x3412를 얻는 경우 엔디안 문제입니다.

+0

Java .class 파일의 매직 넘버를 읽으려고합니다. 내 코드는 마술 번호로 202를 생성하지만 3405691582 (0xCAFEBABE) 여야합니다. 그것은 "rb"를 사용할 때 변경되지 않았습니다. – Peter

+0

또한 Linux를 사용하고 있는데 바이너리 모드로 파일을 여는 것에 대해 걱정할 필요가 있습니까? – Peter

+0

유닉스에서 바이너리 모드를 명시 적으로 사용하는 것은 여전히 ​​좋은 방법입니다. 상처를 입히지 않고 (단지 아무 작업도하지 않지만) 코드를 더 명확하게하고 b.) 누군가가 Windows에서 코드를 실행하면 많은 디버깅을 절약 할 수 있습니다. –

6

충분한 바이트를 읽지 않습니다. 당신이 tadman의 대답에 주석에서 말하는 것처럼, 당신은, 당신이 정말로 하나의 숫자에있는 모든 8 바이트를 원하는 경우 0xCAFEBABE의 처음 2 바이트 0xCA = 202

것을 대신 3405691582

공지 사항의 202를 얻을 수 ,

은 밑줄은 원래 길이가 8 바이트가 될 것입니다 가정한다

num = file.read(8).unpack("L_") 

시도 서명되지 않은 짧은

이상 읽을 필요 확실히 보장 할 수는 없습니다.

+0

나는 그것을 시도하고, 대신에 3199925962를 얻는다. (여전히 옳지 않다!). 또한이를 구현할 수있는 플랫폼 간 방법이 있습니까? – Peter

+1

첫 번째 바이트는 0xCA이며 처음 두 개는 0xCAFE – rampion

+2

3199925962 = 0xBEBAFECA'이므로 바이트 순서 문제가있는 것 같습니다. crossplatformness 들어, 나는 일반적으로 호스트 바이트 순서보다는 네트워크 바이트 순서에 의존합니다. – rampion

2

Ruby에서 바이너리 데이터를 구문 분석하는 데 도움이되는 몇 가지 라이브러리가 있습니다. 간단한 상위 레벨 선언 DSL로 데이터 형식을 선언 한 다음 모든 패킹, 풀기, 비트 트위 빙, 시프트 및 엔디안 전환 자체

나는 이들 중 하나를 사용한 적이 없지만 두 가지 예가 있습니다. (가 많은,하지만 난 그들을 모르는) :

4

Pickaxe를 살펴 보는 것은 어떻습니까? (Ruby 1.9, p. 44)

File.open("testfile") 
do |file| 
    file.each_byte {|ch| print "#{ch.chr}:#{ch} " } 
end 

each_byte는 바이트 단위로 파일을 반복합니다.

관련 문제