2011-10-04 8 views
0

바이트로 오래된 .dat 파일을 읽으려고하는데 문제가 발생했습니다 : 레코드는 \ n (개행)로 종료됩니다. 전체 바이트 배열을 읽은 다음 문자로 나누고 싶습니다.특정 바이트에서 바이트 배열 분할하기

파일에서 전체 바이트 배열을 읽고 바이트 배열의 내용으로 String을 만든 다음 String.split()을 호출하지만 비효율적이라고 생각하면됩니다. 가능한 경우 바이트 배열을 직접 분할하고 싶습니다.

누구든지 도와 줄 수 있습니까?

업데이트 : 코드가 요청되었습니다.

public class NgcReader { 

public static void main(String[] args) { 

    String location; 
    if (System.getProperty("os.name").contains("Windows")) { 
     location = "F:\\Programming\\Projects\\readngc\\src\\main\\java\\ngcreader\\catalog.dat"; 
    } else { 
     location = "/media/My Passport/Programming/Projects/readngc/src/main/java/ngcreader/catalog.dat"; 
    } 

    File file = new File(location); 

    InputStream is = null; 
    try { 
     is = new FileInputStream(file); 
    } catch (FileNotFoundException e) { 
     System.out.println("It didn't work!"); 
     System.exit(0); 
    } 

    byte[] fileByteArray = new byte[(int) file.length() - 1]; 

    try { 
     is.read(fileByteArray); 
     is.close(); 
    } catch (IOException e) { 
     System.out.println("IOException!"); 
     System.exit(0); 
    } 

    // I do NOT like this. I'd rather split the byte array on the \n character 
    String bigString = new String(fileByteArray); 
    List<String> stringList = Arrays.asList(bigString.split("\\n")); 
    for (String record : stringList) { 
     System.out.print("Catalog number: " + record.substring(1, 6)); 
     System.out.print(" Catalog type: " + record.substring(7, 9)); 
     System.out.print(" Right Ascension: " + record.substring(10, 12) + "h " + record.substring(13, 17) + "min"); 
     System.out.print(" Declination: " + record.substring(18, 21) + " " + record.substring(22, 24)); 
     if (record.length() > 50) { 
      System.out.print(" Magnitude: " + record.substring(47, 51)); 
     } 

     if (record.length() > 93) { 
      System.out.print(" Original Notes: " + record.substring(54,93)); 
     } 

     if (record.length() > 150) { 
      System.out.print(" Palomar Notes: " + record.substring(95,150)); 
     } 
     if (record.length() > 151) { 
      System.out.print(" Notes: " + record.substring(152)); 
     } 
     System.out.println(); 
    } 

} 

또 다른 업데이트 : 여기에 내가 처리하고있어 파일의 설명과 함께 README이 : 그것은이 같은 소리

http://cdsarc.u-strasbg.fr/viz-bin/Cat?VII/1B

+0

내부에 가까운 지금까지 코드를 표시 할 수 있습니다 둔다? – stivlo

+3

이 파일이 * text * 파일인지 여부는 확실하지 않습니다.이 경우 파일을 텍스트 또는 * 바이너리 파일로로드해야합니다.이 경우 문자에 관해서는 안됩니다. –

+0

예, 코드! 또한이 .dat 파일이 텍스트 파일 또는 이진 파일입니까? – claymore1977

답변

2

실제로 단지 시작하는 텍스트 파일을, 될 수있는 경우 :

InputStream stream = new FileInputStream(location); 
try { 
    BufferedReader reader = new BufferedReader(new InputStreamReader(stream, 
                    "ASCII")); 
    String line; 
    while ((line = reader.readLine()) != null) { 
     // Handle the line, ideally in a separate method 
    } 
} finally { 
    stream.close(); 
} 

이렇게하면 한 번에 두 줄 이상의 파일을 메모리에 저장할 필요가 없습니다.

+0

예, 그게 전부입니다. 텍스트 파일에있는 설명은 바이트 단위로 설명 했으므로 그렇게 처리하려고했습니다. 멍청한 나. – Jason

2

당신이 바이트 배열을 사용하여 설정하는 경우 ...

byte[] buff = new byte[1024];//smaller buffer 

try { 
    int ind=0,from=0,read; 
    while((read=is.read(buff,ind,buff.length-ind))!=-1){ 
     for(int i=ind;i<ind+read;i++){ 
      if(buff[i]=='\n'){ 
       string record = new String(buff,from,i+1); 
       //handle 
       from=i+1; 
      } 
     } 
     System.arraycopy(buff,from,buff,0,buff.length-from); 
     ind=ind+read-from; 
     from=0; 
    } 

} catch (IOException e) { 
    System.out.println("IOException!"); 
    //System.exit(0); 
    throw RunTimeException(e);//cleaner way to die 
} finally{ 
    is.close(); 
} 

이 또한 전체 파일의 로딩을 방지하고 그것이 결국