문제
이진 문자열(말 그대로 1과 0만 포함하는 문자열 개체)이 있는 경우 이를 파일에 비트로 어떻게 출력합니까?
이것은 제가 작업하고 있던 텍스트 압축기를 위한 것입니다.아직도 저를 괴롭히고 있어요. 마침내 작동하게 된다면 좋을 것 같아요.감사해요!
해결책
가장 쉬운 방법은 단순히 8개의 연속 문자를 가져와서 바이트로 변환하고 해당 바이트를 출력하는 것입니다.스트림 끝을 인식할 수 있는 경우 끝에 0을 채우거나 파일 시작 부분에 길이(비트 단위)의 헤더를 추가합니다.
내부 루프는 다음과 같습니다.
byte[] buffer = new byte[ ( string.length + 7 ) / 8 ];
for ( int i = 0; i < buffer.length; ++i ) {
byte current = 0;
for ( int j = 7; j >= 0; --j )
if ( string[ i * 8 + j ] == '1' )
current |= 1 << j;
output( current );
}
약간의 조정이 필요하지만 이것이 일반적인 생각입니다.
다른 팁
운이 좋다면 java.math.BigInteger가 모든 것을 대신해 줄 수도 있습니다.
String s = "11001010001010101110101001001110";
byte[] bytes = (new java.math.BigInteger(s, 2)).toByteArray();
이는 바이트 순서(빅 엔디안) 및 오른쪽 정렬(비트 수가 8의 배수가 아닌 경우)에 따라 다르지만 문자 변환을 직접 수행하는 것보다 나중에 배열을 수정하는 것이 더 간단할 수 있습니다. .
public class BitOutputStream extends FilterOutputStream
{
private int buffer = 0;
private int bitCount = 0;
public BitOutputStream(OutputStream out)
{
super(out);
}
public void writeBits(int value, int numBits) throws IOException
{
while(numBits>0)
{
numBits--;
int mix = ((value&1)<<bitCount++);
buffer|=mix;
value>>=1;
if(bitCount==8)
align8();
}
}
@Override
public void close() throws IOException
{
align8(); /* Flush any remaining partial bytes */
super.close();
}
public void align8() throws IOException
{
if(bitCount > 0)
{
bitCount=0;
write(buffer);
buffer=0;
}
}
}
그런 다음...
if (nextChar == '0')
{
bos.writeBits(0, 1);
}
else
{
bos.writeBits(1, 1);
}
문자열에 8비트의 배수가 있다고 가정하면(그렇지 않으면 채울 수 있음) Integer.valueOf 메서드에 내장된 Java 구문 분석 기능을 활용하여 다음과 같은 작업을 수행합니다.
String s = "11001010001010101110101001001110";
byte[] data = new byte[s.length() / 8];
for (int i = 0; i < data.length; i++) {
data[i] = (byte) Integer.parseInt(s.substring(i * 8, (i + 1) * 8), 2);
}
그런 다음 바이트를 FileOutputStream
꽤 간단합니다.
반면에 효율성을 찾고 있다면 처음부터 비트를 저장하기 위해 문자열을 사용하지 않고 압축기에서 직접 바이트를 구축하는 것을 고려해야 합니다.
제휴하지 않습니다 StackOverflow