2011-11-06 35 views
10

Dưới đây là mã của tôi để thay thế DataInputStream để bọc InputStream, nhưng cung cấp các phương thức bổ sung để đọc các kiểu dữ liệu cuối cuối cùng với các phương thức bình thường đọc các kiểu cuối lớn. Hãy sử dụng nó nếu bạn muốn.Java: DataInputStream thay thế cho endianness

Tôi có một số đặt chỗ như sau. Lưu ý các phương thức không thay đổi chức năng (các hàm đọc các kiểu cuối lớn). Không có cách nào tôi có thể thực hiện DataInputStream làm lớp cơ sở và sử dụng các phương thức của nó, như read(), readInt(), readChar(), v.v ...?

Phân cấp lớp của tôi có vẻ hơi lạ ở đây. Điều này có phù hợp không?

Có bất kỳ loại nào trong số các loại khác như readUTF() hoặc readLine() cần một phiên bản cuối nhỏ không? Hoặc là chủ quan cho các chương trình cụ thể?

Java lưu trữ các loại boolean như thế nào? Đó có phải là chủ quan đối với endianness không?

Cảm ơn để đáp ứng sự tò mò của tôi :)

import java.io.*; 

/** 
* Replacement for a DataInputStream that provides both little and big endian reading capabilities for convenience without need to implement a ByteBuffer 
* @author Bill ([email protected]) 
*/ 
public class EndianInputStream extends InputStream implements DataInput { 
    private DataInputStream dataInStream; 
    private InputStream inStream; 
    private byte byteBuffer[]; 

    /** 
    * Constructor to wrap InputStream for little and big endian data 
    * @param refInStream Inputstream to wrap 
    */ 
    public EndianInputStream(InputStream refInStream) { 
     inStream = refInStream; 
     dataInStream = new DataInputStream(inStream); 
     byteBuffer = new byte[8]; // Largest data type is 64-bits (8 bytes) 
    } 

    @Override 
    public int available() throws IOException { 
     return dataInStream.available(); 
    } 

    @Override 
    public final int read(byte refBuffer[], int offset, int readLen) throws IOException { 
     return inStream.read(refBuffer, offset, readLen); 
    } 

    @Override 
    public int read() throws IOException { 
     return inStream.read(); 
    } 

    @Override 
    public final int readUnsignedByte() throws IOException { 
     return dataInStream.readUnsignedByte(); 
    } 

    @Deprecated 
    @Override 
    public final String readLine() throws IOException { 
     return dataInStream.readLine(); 
    } 

    @Override 
    public final String readUTF() throws IOException { 
     return dataInStream.readUTF(); 
    } 

    @Override 
    public final void close() throws IOException { 
     dataInStream.close(); 
    } 

    @Override 
    public final void readFully(byte refBuffer[]) throws IOException { 
     dataInStream.readFully(refBuffer, 0, refBuffer.length); 
    } 

    @Override 
    public final void readFully(byte refBuffer[], int offset, int readLen) throws IOException { 
     dataInStream.readFully(refBuffer, offset, readLen); 
    } 

    @Override 
    public final int skipBytes(int n) throws IOException { 
     return dataInStream.skipBytes(n); 
    } 

    @Override 
    public final boolean readBoolean() throws IOException { 
     return dataInStream.readBoolean(); 
    } 

    @Override 
    public final byte readByte() throws IOException { 
     return dataInStream.readByte(); 
    } 

    @Override 
    public final float readFloat() throws IOException { 
     return Float.intBitsToFloat(readInt()); 
    } 

    @Override 
    public final double readDouble() throws IOException { 
     return Double.longBitsToDouble(readLong()); 
    } 

    @Override 
    public final short readShort() throws IOException { 
     return dataInStream.readShort(); 
    } 

    @Override 
    public final int readUnsignedShort() throws IOException { 
     return dataInStream.readUnsignedShort(); 
    } 

    @Override 
    public final long readLong() throws IOException { 
     return dataInStream.readLong(); 
    } 

    @Override 
    public final char readChar() throws IOException { 
     return dataInStream.readChar(); 
    } 

    @Override 
    public final int readInt() throws IOException { 
     return dataInStream.readInt(); 
    } 

    /** 
    * Reads floating point type stored in little endian (see readFloat() for big endian) 
    * @return float value translated from little endian 
    * @throws IOException if an IO error occurs 
    */ 
    public final float readLittleFloat() throws IOException { 
     return Float.intBitsToFloat(readLittleInt()); 
    }  

    /** 
    * Reads double precision floating point type stored in little endian (see readDouble() for big endian) 
    * @return double precision float value translated from little endian 
    * @throws IOException if an IO error occurs 
    */  
    public final double readLittleDouble() throws IOException { 
     return Double.longBitsToDouble(readLittleLong()); 
    } 

    /** 
    * Reads short type stored in little endian (see readShort() for big endian) 
    * @return short value translated from little endian 
    * @throws IOException if an IO error occurs 
    */  
    public final short readLittleShort() throws IOException { 
    dataInStream.readFully(byteBuffer, 0, 2); 
    return (short)((byteBuffer[1] & 0xff) << 8 | (byteBuffer[0] & 0xff)); 
    } 

    /** 
    * Reads char (16-bits) type stored in little endian (see readChar() for big endian) 
    * @return char value translated from little endian 
    * @throws IOException if an IO error occurs 
    */  
    public final char readLittleChar() throws IOException { 
     dataInStream.readFully(byteBuffer, 0, 2); 
     return (char)((byteBuffer[1] & 0xff) << 8 | (byteBuffer[0] & 0xff)); 
    }  

    /** 
    * Reads integer type stored in little endian (see readInt() for big endian) 
    * @return integer value translated from little endian 
    * @throws IOException if an IO error occurs 
    */   
    public final int readLittleInt() throws IOException { 
     dataInStream.readFully(byteBuffer, 0, 4); 
     return (byteBuffer[3]) << 24 | (byteBuffer[2] & 0xff) << 16 | 
      (byteBuffer[1] & 0xff) << 8 | (byteBuffer[0] & 0xff); 
    } 

    /** 
    * Reads long type stored in little endian (see readLong() for big endian) 
    * @return long value translated from little endian 
    * @throws IOException if an IO error occurs 
    */   
    public final long readLittleLong() throws IOException { 
     dataInStream.readFully(byteBuffer, 0, 8); 
     return (long)(byteBuffer[7]) << 56 | (long)(byteBuffer[6]&0xff) << 48 | 
      (long)(byteBuffer[5] & 0xff) << 40 | (long)(byteBuffer[4] & 0xff) << 32 | 
      (long)(byteBuffer[3] & 0xff) << 24 | (long)(byteBuffer[2] & 0xff) << 16 | 
      (long)(byteBuffer[1] & 0xff) << 8 | (long)(byteBuffer[0] & 0xff); 
    } 

    /** 
    * Reads unsigned short type stored in little endian (see readUnsignedShort() for big endian) 
    * @return integer value representing unsigned short value translated from little endian 
    * @throws IOException if an IO error occurs 
    */   
    public final int readLittleUnsignedShort() throws IOException { 
     dataInStream.readFully(byteBuffer, 0, 2); 
     return ((byteBuffer[1] & 0xff) << 8 | (byteBuffer[0] & 0xff)); 
    } 
} 

Trả lời

7

readBoolean() đọc một byte duy nhất. readLine() đọc các byte đơn và chuyển đổi từng byte thành char.

readUTF() lần đọc sửa đổi UTF-8 (có kích thước đơn vị mã là một octet). UTF-8 có no endianness.

Không có mối quan tâm về cuối cùng với các phương pháp này.

Theo thiết kế, hãy cân nhắc xem loại có cần phải là InputStream và liệu ByteBuffer có thể hữu ích hay không. Nếu bạn không sử dụng các tính năng như đánh dấu/thiết lập lại và Closeable bạn có thể không tiếp xúc với các loại mới:

public class Bytes { 
    public static DataInput littleEndian(final DataInput decorated) { 
    class LittleInput implements DataInput { 
     private ByteBuffer buffer = ByteBuffer.allocate(8); 

     public int readInt() throws IOException { 
     buffer.clear(); 
     buffer.order(ByteOrder.BIG_ENDIAN) 
      .putInt(decorated.readInt()) 
      .flip(); 
     return buffer.order(ByteOrder.LITTLE_ENDIAN) 
      .getInt(); 
     } 

     //TODO: other methods  
    } 

    return new LittleInput(); 
    } 

} 

Tôi lưu ý rằng thư viện ổi phổ biến đã có LittleEndianDataInputStream.

+0

Cảm ơn bạn. Guava có sẵn như một phần của nền tảng thời gian chạy Java tiêu chuẩn mà hầu hết mọi người đã có trên máy tính của họ không? –

+0

@ user1030796 - no, [Guava] (http://code.google.com/p/guava-libraries/) là thư viện của bên thứ 3 do Google cung cấp. – McDowell

+0

Định dạng shapefile ESRI trộn lẫn cả nhỏ và lớn với một định dạng duy nhất, vì vậy tôi muốn cung cấp cả hai loại từ một lớp duy nhất như tôi đã làm ở đây. –

Các vấn đề liên quan