2015-02-04 6 views
1

그래서 Java로 문자열을 추출해야하는 이진 FRX 파일이 있습니다.
나는 그렇게처럼 내 자바 프로그램에 쓴 : 이것은 완벽하게 작동특정 바이트를 이진 파일에서 가장 효율적으로 문자열로 변환하는 방법

FileInputStream ReadFRX = null ; 
FileOutputStream TempCapt = null ; 
    try{     
     // refNum is hex number on end of VB form property converted to decimal, ex: $"frmResidency.frx":0134 
     int refNum = Integer.parseInt(line.substring(line.length() - 4, line.length()), 16); 

     // FRXtemp.txt is created, to temporarily write FRX captions onto to be read from. 
     PrintWriter writer = new PrintWriter("FRXtemp.txt", "UTF-8"); 
     writer.close(); 

     //opens corresponding FRX file to read into 
     ReadFRX = new FileInputStream("FRXFiles\\"+curFrmName + ".frx"); 
     //aLittleEndian... must be used to match readInt() little-endianness 
     LittleEndianDataInputStream ActReadFRX = new LittleEndianDataInputStream(ReadFRX); 
     TempCapt = new FileOutputStream("FRXtemp.txt"); 

     ActReadFRX.skipBytes(refNum); 
     int length = ActReadFRX.readInt(); 
     int c; 

      for (c = 0; c < length; c++) { 
       // first read byte and check for EOF 
       TempCapt.write(ActReadFRX.read()); 
      } 
     } 
//If caption is not read properly (ie. possibly wrong bytes), EOF Exception will occur and designer will break 
catch (EOFException e){ 

    System.out.println("ERROR : FRX Caption property was mishandled"); 
    break; 
} 

//Read data from FRXtemp.txt into string 
String actCaption = "\"" + new Scanner(new File("FRXtemp.txt")).useDelimiter("\\A").next() + " \" "; 

내가보기 엔 불필요한해야합니다 그것의 떨어져 읽을 수 있도록, 그러나 나는 임시 파일에 쓰는 생각합니다.

나는 더 효율적인 방법을 생각할 수없는 이유 : 그러나 나는 해야 만이, 내가 훨씬 더 실용적인 접근 느낌
Byte[] Array 사용하고 문자열로 그것을 변환하는 것 문자열이 저장된 바이트 연구에 의하면 이 필요했기 때문에 ReadInt에서 오프셋을 설정하여 RandomAccessFile이 little-endian 형식 인 반면 big-endian 형식을 사용한다고 가정했습니다. 나는 분명히 변환 할 수 있지만, 현재의 솔루션은 그 시점에서 실행 가능한 것으로 보인다.

내 질문이이며, 4 바이트 정수에 해당하는 바이트의 특정 부분을 변환 할 수있는 효율적인 방법은 자바에서 문자열로 (리틀 엔디안 형식의 이진 파일에서)이있다?

나는 훨씬 더 간단한 것을 간과해야하는 것처럼 느낍니다. 감사합니다 :)

+1

팁 팁 : 다른 접근 방식의 속도를 비교하려면 [JMH] (http://openjdk.java.net/projects/code-tools/jmh/)를 사용하십시오. –

+0

흥미 롭다. 고맙다. – HavelTheGreat

답변

2

가장 간단한 방법 일 수는 있지만 몇 가지 방법을 사용할 수 있습니다.

try (DataInputStream dis = new DataInputStream(new FileInputStream(file))) { 
    dis.skip(bytesToSkip); 
    int length = Integer.reverseBytes(dis.readInt()); 
    byte[] bytes = new bytes[length]; 
    dis.readFully(bytes); 
    return new String(bytes, "UTF-8"); 
} 

당신이 찾고있는 수있는 방법은 Integer

/** 
* Returns the value obtained by reversing the order of the bytes in the 
* two's complement representation of the specified {@code int} value. 
* 
* @param i the value whose bytes are to be reversed 
* @return the value obtained by reversing the bytes in the specified 
*  {@code int} value. 
* @since 1.5 
*/ 
public static int reverseBytes(int i) { 
    return ((i >>> 24)   ) | 
      ((i >> 8) & 0xFF00) | 
      ((i << 8) & 0xFF0000) | 
      ((i << 24)); 
} 
+1

필자는 필자가 누락되어 "정수"라는 방법을 사용하여 과도한 합병증을 일으켰습니다. 많은 감사합니다! – HavelTheGreat

+0

@ 엘리자온 길고 짧음도 마찬가지입니다. 이 방법은 비효율적 인 것처럼 보이지만 많은 JVM에서 내장 함수로 처리됩니다. 즉, 단일 기계 코드 명령으로 변환됩니다. –

0

이런 식으로 뭔가?

long length = 0xff && mybytes[0]; length<<8; 
length |= 0xff && mybytes[1]; length<<8; 
length |= 0xff && mybytes[2]; length<<8; 
length |= 0xff && mybytes[3]; length<<8; 
0

에 당신은 소스로 가지고있는 inputStream을 사용하고 필요에 따라 문자열을 만드는 엔디안를 해결하기 위해 ByteBuffer를 사용할 수있다 . 이것은 가장 효율적인 방법이 될 것입니다.