2009-11-11 3 views
1

BinaryWriter를 사용하여 레코드를 파일에 쓰고 있습니다. 레코드는 다음 속성 데이터 유형을 가진 클래스로 구성됩니다..NET BinaryWriter.Write() 메서드 - 동시에 여러 데이터 형식 작성

INT32,
INT16은
바이트 [], 널 문자


각 레코드를 작성하려면, 나는 BinaryWriter.Write 네 번 호출 - 각 데이터 유형에 대해 하나. 이 잘 작동하지만 BinaryWriter.Write() 메서드를 이러한 데이터 형식을 모두 사용하여 한 번 호출하는 방법이 있는지 알고 싶습니다. 이 이유는 다른 프로그램이 내 바이너리 파일을 읽으며 쓰기 호출 사이에서 읽기를 시작하기 때문에 때때로 레코드의 일부만 읽습니다. 불행하게도 다른 프로그램에 대한 코드를 제어 할 수는 없지만 읽는 방식을 수정합니다.

답변

1

BinaryWriter에 쓰기를 유지하면서 BinaryWriter에 기록 된 두 번째 BinaryWriter를 사용하여 이진 레코드를 만듭니다. 이미 주요 BinaryWriter에 쓰고있어로

public void WriteTo(BinaryWriter writer) 
    { 
     MemoryStream ms = new MemoryStream(); 
     BinaryWriter bw = new BinaryWriter(ms); 
     bw.Write(value1); 
     bw.Write(value2); 
     bw.Write(value3); 
     bw.Write(value4); 

     writer.Write(ms.ToArray()); 
    } 

이 다음 쓰기 그냥 한 번에 모든 것을 구축 할 것 같은 형식으로 하나의 레코드를 만들 것입니다 : 그래서 클래스에이 같은 방법을 가질 수있다 바이트 배열로.

1

바이너리 포맷 기록의 클래스를 만들고 사용 : 나 자신 그래서 난이, 클래스가 다른 데이터를 포함 할 수 없습니다 일하는 것이 절대적으로 확실하지 않다 이런 짓을하지 않은

FileStream fs = new FileStream("file.dat", FileMode.Create); 
BinaryFormatter formatter = new BinaryFormatter(); 
formatter.Serialize(fs, <insert instance of a class here>); 
fs.Close(); 

을, 그건 물론. 클래스와 운이 없다면 구조체를 시도 할 수 있습니다.

편집 : 그냥 다른 가능한 솔루션을 내놓았다의 Buffer.BlockCopy 기능을 데이터의 구조체를 생성하고 사용

byte[] writeBuffer = new byte[sizeof(structure)]; 
structure[] strucPtr = new structure[1]; // must be an array, 1 element is enough though 
strucPtr[0].item1 = 0213; // initialize all the members 

// Copy the structure array into the byte array. 
Buffer.BlockCopy(strucPtr, 0, writeBuffer, 0, writeBuffer.Length); 

지금 당신이 한 번에 파일로 writeBuffer를 작성할 수 있습니다.

두 번째 편집 : 해결할 수없는 동기화 문제에 동의하지 않습니다. 우선, 데이터는 한 번에 한 바이트가 아닌 전체 섹터에서 파일에 기록됩니다. 그리고 파일은 플러시 할 때까지 실제로 업데이트되지 않으므로 데이터를 쓰고 파일 길이를 업데이트합니다. 가장 좋고 안전한 방법은 파일을 독점적으로 열거 나 레코드 (또는 여러 개)를 작성하고 파일을 닫는 것입니다. 따라서 읽기 응용 프로그램은 비슷한 방식으로 파일을 읽어야하며 (예 : 열린 파일, 읽기, 닫기) "액세스 거부"오류를 정상적으로 처리해야합니다.

어쨌든, 한 번에 전체 기록을 쓰는시기가 언제 더 좋을지 나는 확신합니다.

+0

+1 당신이 말한대로 다른 응용 프로그램이 얼마나 잘 작동하는지에 따라 달라집니다. 파일이 잠긴 것으로 확인되면 심하게 공황 상태가 될 것인가, 아니면 평온한가? – MarkJ

2

바이트를 반환하는 클래스에 .ToBinary() 메서드를 추가하십시오. 당신의 호출 코드 (대략 나는이 컴파일하지 않은 것처럼)

stream.BinaryWrite(myObj.toBinary()); 

당신은 여전히 ​​독립적으로 각 값을 기록하고 있지만, 코드를 조금 정리에

public byte[] ToBinary() 
{ 
    byte[] result= new byte[number_of_bytes_you_need]; 

    // fill buf 

    return result; 
} 

.

또한, sindre가 제안한 것처럼 직렬화를 사용하는 것이 좋습니다. 문제의 파일에서 개체를 쉽게 재현 할 수 있으며 시도하는 동안 파일을 작성하는 것보다 적은 노력이 필요하기 때문입니다.

동기화 : 파일 동기화 문제를 해결하기 위해 이러한 솔루션을 사용할 수 없습니다. 직렬화 나 내가 설명한 ToToBinary() 메서드를 사용하지 않고 binaryWrite() 호출을 단일 문으로 줄이는 경우에도 바이트는 여전히 프레임 워크에 의해 순차적으로 작성됩니다. 이것은 디스크의 물리적 구조에 대한 제한 사항입니다. 파일 형식을 제어 할 수있는 경우, 레코드 데이터 앞에 기록 길이 필드를 추가하십시오.파일을 읽는 응용 프로그램에서 파일의 다음 레코드를 처리하기 전에 record_length 바이트가 있는지 확인하십시오. 당신이 그것에있는 동안, 데이터베이스에 넣어. 파일 형식을 제어 할 수 없다면 운이없는 것입니다.

관련 문제