문제

내가 노력하고를 읽는 바이너리 파일이 BinaryReader 클래스고,필요해요 그것을 읽으로 블럭의 UInt32 고,다음 몇 가지 비트 시프트 등등.상품.

하지만,어떤 이유로 이 비문을 반전 사용할 때 내 ReadUInt32 방법입니다.

면 예를 들어 있는 파일의 첫번째 네 개의 바이트에서 다음과 같이 보입니다 육, 0x12345678, 그들은 결국 같은 이 후로 읽 ReadUInt32: 0x78563412.

내가 사용하는 경우에 ReadBytes(4)메소드,내가 예상 배열:

[0x00000000]    0x12    byte
[0x00000001]    0x34    byte
[0x00000002]    0x56    byte
[0x00000003]    0x78    byte

왜 그렇습니까?그것은 단지 방법입니다.net 나타냅 uints 에서 메모리가 있습니까?그것은 동일에 걸쳐 다양한 플랫폼(나는 실행하는 64 비트 윈도우 7,.net3.5sp1)?

도움이 되었습니까?

해결책

이 될 것으로 보인 엔디안 문제입니다. 문서 말 ReadUint32 읽 little-endian 그래서 첫 번째 바이트는 적어도 중요 그래서 그것을 가장 낮은 메모리 위치에 있습니다.당신의 작가이어야 합 big-endian?

BinaryWriter.Write(UInt32) 그것을 말한다 기록 little-endian too.귀하의 바이너리 데이터를 원하지 않는 BinaryWriter?

기본적으로 필요가 무엇을 할 수정하는 것입니다:

uint a = 0x12345678;
uint b = ((a & 0x000000FF) << 24) + ((a & 0x0000FF00) << 8) + ((a & 0x00FF0000) >> 8) + ((a & 0xFF000000) >> 24);

이 교대를 최소한 바이트까지 24 비트,제 2LSB8 비트 3 데이터베이스를 최신으로 유지하려는 8 비트,그리고 4LSB(MSB)아래로는 24 비트입니다.이 일을 하는 것은 커버에 여러 가지 라이브러리입니다.

아마도 사용 BitConverter 것은 좀 더 명확:

uint a = 0x12345678;
byte[] bytes = BitConverter.GetBytes(a);
// Swap byte order
uint b = BitConverter.ToUInt32(new byte[] { bytes[3], bytes[2], bytes[1], bytes[0] }, 0);

다른 팁

예, 이것은 컴퓨터 하드웨어가 메모리에 저장하는 방법과 관련이 있습니다. 대부분의 데스크탑 컴퓨터는 동일해야하지만 플랫폼마다 다를 수 있습니다.

이것을 Endianness라고합니다. 여기 Wikipedia를 참조하십시오.

http://en.wikipedia.org/wiki/endian

EndianbinaryReader 및 EndianbitConverter와 같은 Endian* 클래스에 대한 Jon Skeet의 Miscutil Library를 살펴보십시오.

http://www.yoda.arachsys.com/csharp/miscutil/

Jon Skeet은 구성 가능한 Endian-sness가있는 비트 컨버터를 작성했습니다. 유용하다고 생각할 수 있습니다.

http://www.yoda.arachsys.com/csharp/miscutil/

이것은 플랫폼의 문제입니다 endianess. 스트림에서 데이터를 읽으면 endianess에 따라 읽어 져야합니다. .NET에서 데이터를 만든 경우 .NET은 올바르게 읽습니다.

읽다 제네릭 바이린 리더 및 바이린 라이터 확장자, 관리되지 않는 방식으로 일반적인 캐스팅을 처리하는 좋은 방법.

vb.net의 경우 (안전한 코드 만 C#에서도 달성 할 수 있음) 다음을 사용하십시오.

Imports System.io Imports System.Runtime.comPilerservices Imports System.Runtime.InterOpServices

<HideModuleName()>
Public Module BinaryReaderExtensions

 <Extension()>
 Public Function Read(Of T As Structure)(br As BinaryReader) As T
  Dim bytes = br.ReadBytes(Marshal.SizeOf(GetType(T)))
  Dim handle = GCHandle.Alloc(bytes, GCHandleType.Pinned)
  Return Marshal.PtrToStructure(handle.AddrOfPinnedObject, GetType(T))
 End Function

 <Extension()>
 Public Function ReadReverse(Of T As Structure)(br As BinaryReader) As T
  Dim bytes = br.ReadBytes(Marshal.SizeOf(GetType(T))).Reverse.ToArray
  Dim handle = GCHandle.Alloc(bytes, GCHandleType.Pinned)
  Return Marshal.PtrToStructure(handle.AddrOfPinnedObject, GetType(T))
 End Function

End Module

이제 동일한 기능을 구현할 수 있습니다 BitConverter, 을 위한 BinaryWriter 등.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top