0

I am using this adobe example under "reading and writing objects" to try and convert an XML file to a byteArray and save the file somewhere. I use this to upload the file to s3. When i download the XML file with s3 i get 4 random characters in front of the XML file. Looking into the issue [example of what i think is happening], it seems that the extra characters are being created with the encoding scheme. However, adobes example uses writeObject to convert an XML to a byteArray, so I don't see how i am using the incorrect encoding scheme.

my code is fairly simple.

creating the byteArray:

            var _bookXml:XML = _book.serialize(); //converts book to XML
                var photobookXmlName:String = photobookToken + "_layout.xml";
                _s3uploader.uploadObjectToS3(_bookXml, photobookXmlName); //uploads XML

and the uploadObjectToS3 code:

    public function uploadObjectToS3(file:Object, objectName:String):void{
        var data:ByteArray = new ByteArray;
        data.writeObject(file);
        data.position = 0;
        //code to do s3 upload
    }

heres a before/after example XML file i used as a test case:

before:

<xml>
  <test>data</test>
</xml>

after:

��5<xml>
  <test>data</test>
</xml>

any idea how to fix this issue so I dont get random characters? I've tried a few things but they didn't work.

thanks

edit: before anyone suggests, i already trtied changing the uploadObjectToS3 input form an object to a ByteArray. It didnt change anything.

Community
  • 1
  • 1
Zyren
  • 603
  • 2
  • 7
  • 21
  • the other question you referenced is referring to byte order marks. see http://en.wikipedia.org/wiki/Byte_order_mark for more details. but that's not what you are seeing here. – J. Holmes Oct 12 '11 at 15:05

2 Answers2

3

You are using data.writeObject(file);. Those are not random characters, those are serialization markers.

You aren't sending an xml document to S3, you are sending a serialized Actionscript XML object (in AMF3 format).

_bookXml.toXMLString() will give you the xml document as a string. then you should be able to use ByteArray.writeMultiByte() to get what you want. Check out the following example:

    var test:XML = <test><data>Data</data></test>;

    var serializeObject:ByteArray = new ByteArray();
    serializeObject.writeObject(test);
    trace(serializeObject.toString());

    var rawString:ByteArray = new ByteArray();
    rawString.writeMultiByte(test.toXMLString(), 'utf-8');
    trace(rawString.toString());

The output is:

�E<test>
  <data>Data</data>
</test>

<test>
  <data>Data</data>
</test>

The difference is the first is a serialized object (that you could use .readObject() to deserialize the object out of the byte array back into a XML object in flash). The latter is simply the raw bytes of the string (in utf-8).

In your case, I would suggest something like this:

public function uploadObjectToS3(file:Object, objectName:String):void{
    var data:ByteArray = new ByteArray;
    data.writeObject(file);
    data.position = 0;

    uploadByteArrayToS3(data, objectName);
}

public function uploadXmlToS3(file:XML, objectName:String):void{
    var data:ByteArray = new ByteArray;
    data.writeMultiByte(file.toXMLString(), "utf-8");
    data.position = 0;

    uploadByteArrayToS3(data, objectName);
}

private function uploadByteArrayToS3(file:ByteArray, objectName:String):void{
    //code to do s3 upload
}
J. Holmes
  • 18,466
  • 5
  • 47
  • 52
0

Unless you are receiving a unicode prefix per line, I believe you are seeing the length of the string for deserialization.

This would be exhibited by:

writeUTF(value:String) - Writes a UTF-8 string to the file stream, byte stream, or byte array. The length of the UTF-8 string in bytes is written first, as a 16-bit integer, followed by the bytes representing the characters of the string.

writeUTFBytes(value:String) - Writes a UTF-8 string. Similar to writeUTF(), but does not prefix the string with a 16-bit length word.

Jason Sturges
  • 15,855
  • 14
  • 59
  • 80