2 Replies - 1979 Views - Last Post: 12 October 2013 - 12:26 PM Rate Topic: -----

#1 raihan26   User is offline

  • New D.I.C Head

Reputation: -1
  • View blog
  • Posts: 47
  • Joined: 04-February 10

How to deserialize the ByteArray from the file using C++ in proper way

Posted 12 October 2013 - 10:23 AM

I am writing Byte Array value into a file using Java with Big Endian Byte Order format.. Now I need to read that file from C++ program...

That Byte Array which I am writing into a file is made up of three Byte Arrays as described below-

    short employeeId = 32767;
    long lastModifiedDate = "1379811105109L";
    byte[] attributeValue = os.toByteArray();


I am writing `employeeId` , `lastModifiedDate` and `attributeValue` together into a single Byte Array and that resulting Byte Array I am writing into a file and then I will be having my C++ program which will retrieve that Byte Array data from file and then deserialize it to extract `employeeId`, `lastModifiedDate` and `attributeValue` from it.

Below is my working Java code, which writes Byte Array value into a file with Big Endian format:

    public class ByteBufferTest {
    
    	public static void main(String[] args) {
    
    		String text = "Byte Array Test For Big Endian";
    		byte[] attributeValue = text.getBytes();
    
    		long lastModifiedDate = 1289811105109L;
    		short employeeId = 32767;
    
    		int size = 2 + 8 + 4 + attributeValue.length; // short is 2 bytes, long 8 and int 4
    
    		ByteBuffer bbuf = ByteBuffer.allocate(size); 
    		bbuf.order(ByteOrder.BIG_ENDIAN);
    
    		bbuf.putShort(employeeId);
    		bbuf.putLong(lastModifiedDate);
    		bbuf.putInt(attributeValue.length);
    		bbuf.put(attributeValue);
    
    		bbuf.rewind();
    
    		// best approach is copy the internal buffer
    		byte[] bytesToStore = new byte[size];
    		bbuf.get(bytesToStore);
    
    		writeFile(bytesToStore);
    
    	}
    
    	/**
    	 * Write the file in Java
    	 * @param byteArray
    	 */
    	public static void writeFile(byte[] byteArray) {
    
    		try{
    			File file = new File("bytebuffertest");
    
    			FileOutputStream output = new FileOutputStream(file);
    			IOUtils.write(byteArray, output);			
    
    		} catch (Exception ex) {
    			ex.printStackTrace();
    		}
    	}
    }


Now I need to retrieve Byte Array from that same file using the below C++ program and deserialize it to extract `employeeId`, `lastModifiedDate` and `attributeValue` from it. I am not sure what is the best way on the C++ side. Below is the code I have so far:

    int main() {
    
    	string line;
    
    	std::ifstream myfile("bytebuffertest", std::ios::binary);
    
    	if (myfile.is_open()) {
    
    		uint16_t employeeId;
    		uint64_t lastModifiedDate;
    		uint32_t attributeLength;
			
    		char buffer[8]; // sized for the biggest read we want to do
    
    		// read two bytes (will be in the wrong order)
    		myfile.read(buffer, 2);
    		
			// swap the bytes
    		std::swap(buffer[0], buffer[1]);
    
    		// only now convert bytes to an integer
    		employeeId = *reinterpret_cast<uint16_t*>(buffer);
    
    		cout<< employeeId <<endl;
    
    		// read eight bytes (will be in the wrong order)
    		myfile.read(buffer, 8);
    		
			// swap the bytes
    		std::swap(buffer[0], buffer[7]);
    		std::swap(buffer[1], buffer[6]);
    		std::swap(buffer[2], buffer[5]);
    		std::swap(buffer[3], buffer[4]);
    
    		// only now convert bytes to an integer
    		lastModifiedDate = *reinterpret_cast<uint64_t*>(buffer);
    
    		cout<< lastModifiedDate <<endl;
    
    		// read 4 bytes (will be in the wrong order)
    		myfile.read(buffer, 4);
    		
			// swap the bytes
    		std::swap(buffer[0], buffer[3]);
    		std::swap(buffer[1], buffer[2]);
    
    		// only now convert bytes to an integer
    		attributeLength = *reinterpret_cast<uint32_t*>(buffer);
    
    		cout<< attributeLength <<endl;
    
    		myfile.read(buffer, attributeLength);
    
    		
    		// now I am not sure how should I get the actual attribute value here?
    		
    		//close the stream:
    		myfile.close();
    	}
    
    	else
    		cout << "Unable to open file";
    
    	return 0;
    }



I was reading somewhere that I can use `htons` in C++ to deserialize the Byte Array.. Not sure whether `htons` will be much better solution as compared to what I have currently?..

If yes, then I am not sure how to use that in my current C++ code?

I am using Network Byte Order (Big Endia) here.. Is this the best way to deserialize the bytearray code that I have written in C++? Or is there any other better way?

Can anybody take a look on C++ code and see what I can do to improve it, as I don't think it is looking much efficient? Any better way to deserialize the Byte Array and extract relevant information on the C++ side?

Is This A Good Question/Topic? 0
  • +

Replies To: How to deserialize the ByteArray from the file using C++ in proper way

#2 jimblumberg   User is online

  • member icon

Reputation: 5780
  • View blog
  • Posts: 17,684
  • Joined: 25-December 09

Re: How to deserialize the ByteArray from the file using C++ in proper way

Posted 12 October 2013 - 12:01 PM

Please don't post help related questions in the Advanced Discussion forum.

Moved to C/C++ forum.


Jim
Was This Post Helpful? 0
  • +
  • -

#3 jimblumberg   User is online

  • member icon

Reputation: 5780
  • View blog
  • Posts: 17,684
  • Joined: 25-December 09

Re: How to deserialize the ByteArray from the file using C++ in proper way

Posted 12 October 2013 - 12:26 PM

First if you're working on the same system you don't need to be concerned about Endian issues. The only time you need to worry about this is when you take a file generated on one system to another system. If you're using the same system to read the file in C++ then swapping the values will give you strange results.

Second "hton" converts a value to network byte order (Big Endian) format. You would probably want to convert from network byte order to system byte order "ntoh" instead, which would be a nop on a Big Endian machine.

Third when going from your Java program to a C++ program you'll need to know exactly how many bytes Java writes to the file for each type. Remember to read a binary file you need to know exactly how many bytes were written.

Is there a reason you're trying to use binary files instead of text files? Retrieving this information in text would be much easier.

Jim
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1