加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

Java:DataInputStream替换为字节顺序

发布时间:2020-12-14 16:28:22 所属栏目:Java 来源:网络整理
导读:下面是我的代码替换DataInputStream来包装一个InputStream,但是除了读取大尾数类型的普通方法之外,还提供了额外的方法来读取小端数据类型.如果你愿意,随意使用它. 我有几点保留如下.注意不改变功能的方法(读取大尾数类型的函数).没有办法我可以实现DataInput
下面是我的代码替换DataInputStream来包装一个InputStream,但是除了读取大尾数类型的普通方法之外,还提供了额外的方法来读取小端数据类型.如果你愿意,随意使用它.

我有几点保留如下.注意不改变功能的方法(读取大尾数类型的函数).没有办法我可以实现DataInputStream作为基类,并使用它的方法,如read(),readInt(),readChar()等等?

我的班级层次似乎有点奇怪.这是否合适?

像readUTF()或readLine()这样的其他类型的其他类型需要一个小的endian版本吗?还是主观具体方案?

Java如何存储布尔类型?这是否也是主观的?

感谢您的满足我的好奇心:)

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 (unspecified.specification@gmail.com)
 */
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,refBuffer.length);
    }

    @Override
    public final void readFully(byte refBuffer[],int readLen) throws IOException {
        dataInStream.readFully(refBuffer,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,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,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,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,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,2);
        return ((byteBuffer[1] & 0xff) << 8 | (byteBuffer[0] & 0xff));
    }
}

解决方法

readBoolean()读取一个字节. readLine()读取单个字节并将其转换为char.

readUTF()读取修改的UTF-8(其代码单元大小为一个八位位组). UTF-8有no endianness.

这些方法没有任何关注.

关于设计,请考虑该类型是否需要InputStream,以及ByteBuffer是否有用.如果您没有使用像mark / reset和Closeable这样的功能,您可能不会公开新的类型:

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();
  }

}

我注意到,流行的番石榴图书馆已经有LittleEndianDataInputStream.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读