javadatainputstream

How to read and write Bytes without skipping the zeros in Java


Does anyone know how to input or output bytes without skipping the zeros I am trying to write a program that exports an array of ints to unsigned shorts. I have written code to write and read wave files, but they aren't formatted right.

Read Example

        // dwChunkSize
        byteConvertedLong = extractBytes(4);
        dwFormatChunkSize = convertBytesToLong(byteConvertedLong);
        System.out.println("Format Chunk size: " + dwFormatChunkSize);
        // wFormatTag
        byteConvertedInt = extractBytes(2);
        System.out.println("Format Tag: " + convertBytesToInt(byteConvertedInt));

functions for reading data:

    // convert byte to long
    public long convertBytesToLong(byte[] values) {
        byte[] spliceToArray = {0, 0, 0, 0, 
            values[0], values[1], values[2], values[3]};
        ByteBuffer debuffer = ByteBuffer.wrap(spliceToArray);
        long returnValue = (long)debuffer.getLong();
        return returnValue;
    }

    // convert byte to int
    public int convertBytesToInt(byte[] values) {
        byte[] spliceToArray = {0, 0, values[0], values[1]};
        ByteBuffer debuffer = ByteBuffer.wrap(spliceToArray);
        int returnValue = debuffer.getInt();
        return returnValue;
    }

    // extract bytes to DataOutputStream
    public byte[] extractBytes(int bytesToExtract)
            throws IOException {

        // define byte array
        byte[] extractedBytes = new byte[bytesToExtract];

        // extract bytes
        dis.read(extractedBytes, byteTracker, bytesToExtract);

        return extractedBytes;
    }

Write example

// dwChunkSize
        byteConvertedLong = convertLongToBytes(dwFormatChunkSize);
        appendBytes(byteConvertedLong, 4, 8);
        // wFormatTag
        byteConvertedInt = convertIntToByte(W_FORMAT_TAG);
        appendBytes(byteConvertedInt, 2, 4);

Functions for writing;

// convert long to byte
    public byte[] convertLongToBytes(long value) {
        ByteBuffer buffer = ByteBuffer.allocate(8);
        buffer.putLong(value);
        return buffer.array();
    }

    // convert int to byte
    public byte[] convertIntToByte(int value) {
        ByteBuffer buffer = ByteBuffer.allocate(4);
        buffer.putInt(value);
        return buffer.array();
    }

    // append bytes to DataOutputStream
    public void appendBytes(byte[] bytesToAppend, int start, int end)
            throws IOException {
        for (int i = start; i < end; i++) {
            dos.writeByte(bytesToAppend[i]);
        }
    }

I have to use Long and int variabls to read and write ints and shorts respectively so that they are written as unsigned numbers.

I have been following instructions on this site https://blogs.msdn.microsoft.com/dawate/2009/06/23/intro-to-audio-programming-part-2-demystifying-the-wav-format/ to make sure all the data is formatted right

The main problem with both reading and writing is that if I read 1 as a short (0000000000000001), it will skip the zeros and start reading from 1 (10000000000000000). If that isn't the problem I don't know what is?


Solution

  • It turned out that Wave files are written in little endian and I was writing in big endian. I needed to implement a function that reversed the bytes of the byte array. I came up with this.

    // bigToLittleEndien method
        public byte[] bigToLittleEndien(byte[] oldArray) {
    
            // new array
            byte[] newArray = new byte[oldArray.length];
    
            // reverse the order of byes
            for (int i = 0, j = oldArray.length - 1; i < oldArray.length; i++, j--) {
                newArray[i] = oldArray[j];
            }
    
            // return the new bytes
            return newArray;
        }
    

    I had some other problems that were small but I fixed them all.