如何通过Java将二进制数据从AS3发送到文件系统?

如何通过Java将二进制数据从AS3发送到文件系统?,java,actionscript-3,google-app-engine,servlets,google-cloud-storage,Java,Actionscript 3,Google App Engine,Servlets,Google Cloud Storage,我在AS3中有XML数据,需要在我的JavaGoogleAppEngineServlet上进行压缩、验证,然后保存到Google云存储中的一个文件中。稍后,AS3客户端将打开并解压缩该文件。如果我使用纯XML或文本进行压缩,则该过程可以工作,但如果我使用ByteArray压缩数据,则在使用“解压数据时出错”解压ByteArray时,该过程将终止 我尝试过在不同的点设置内容类型和mime类型,以及使用Base64编码,但每次尝试都以不同的方式中断,而且我从来没有收到我发送的相同XML。我需要使用多

我在AS3中有XML数据,需要在我的JavaGoogleAppEngineServlet上进行压缩、验证,然后保存到Google云存储中的一个文件中。稍后,AS3客户端将打开并解压缩该文件。如果我使用纯XML或文本进行压缩,则该过程可以工作,但如果我使用ByteArray压缩数据,则在使用“解压数据时出错”解压ByteArray时,该过程将终止

我尝试过在不同的点设置内容类型和mime类型,以及使用Base64编码,但每次尝试都以不同的方式中断,而且我从来没有收到我发送的相同XML。我需要使用多部分吗?我应该在服务器上压缩吗?这样做的最佳实践是什么

从AS3发送数据:

// compress xml using zlib
var xml:XML = <contents><thing>value</thing></contents>;
var bytes:ByteArray = new ByteArray();
bytes.writeObject(xml);
bytes.position = 0;
bytes.compress();

var request:URLRequest = new URLRequest(url);
var urlVariables :URLVariables = new URLVariables();
urlVariables.filename = "somefile.bin";
urlVariables.contents = bytes;
request.data = urlVariables;
request.method = URLRequestMethod.POST;
loader = new URLLoader();
loader.load(request);
在AS3中打开新文件:

var url :String = "http://commondatastorage.googleapis.com/bucketname/somefile.bin";
var request:URLRequest = new URLRequest(url);
request.method = URLRequestMethod.GET;
loader = new URLLoader();
loader.addEventListener(Event.COMPLETE, handleComplete);
loader.load(request);

protected function handleComplete (event:Event):void {
    var bytes:ByteArray = new ByteArray();
    bytes.writeObject(event.target.data);

    // dies on this line with "There was an error decompressing the data."
    bytes.uncompress();

    var xml:XML = new XML(new String(bytes));
    trace(xml);
}

下面是我用来保存xml的代码。我将数据发送到PHP,但我认为它将以同样的方式为您工作。。。我没有遇到任何麻烦

var createXMLURL:URLRequest = new URLRequest("createXML.php");
createXMLURL.method = URLRequestMethod.POST;
var Variables:URLVariables = new URLVariables();
Variables.xmlString = xml.toXMLString();
Variables.filename = filename;
createXMLURL.data = Variables;
var loader:URLLoader = new URLLoader();
loader.dataFormat = "VARIABLES";
loader.addEventListener(Event.COMPLETE, xmlCreated);
loader.load(createXMLURL);
如果您对某些变量有任何疑问,请告诉我,因为我没有包含它们的声明(我认为它们很容易理解)


现在,它不会像你要求的那样以二进制格式发送数据,但我不知道如果你真的需要原始字节,为什么你不能在java中接收到字符串后将其转换为二进制。

我会在你发布之前进行base64编码,如果来自客户端,以这种方式存储在TextProerty中,然后,当从客户端接收回base64时,对其进行解码/解压缩。如果您想将其作为二进制存储在GAE上,那么base64将其解码为Blob。下面是我用你的代码拼凑的一些代码片段,以及我用HttpService做的类似的事情——为没有对其进行全面校对而提前道歉。嗯

private var _serviceHttp:HTTPService = new HTTPService;

private function postBytes():void {
    var xml:XML = <contents><thing>value</thing></contents>;
    var bytes:ByteArray = new ByteArray();
    bytes.writeObject(xml);
    bytes.position = 0;
    bytes.compress();
    var enc:Base64Encoder = new Base64Encoder();
    enc.encodeBytes(bytes, 0, bytes.length);
    var myObj:Object = new Object();
    myObj["bytes"] = enc.toString();
    // myObj["other_variables"] = your_other_varaibles;
    _serviceHttp.method = "POST";
    _serviceHttp.resultFormat = "flashvars";
    _serviceHttp.url = your_url_here;
    _serviceHttp.addEventListener(ResultEvent.RESULT, urlHandler);
    _serviceHttp.addEventListener(FaultEvent.FAULT, urlErrorHandler);
    _serviceHttp.send(myObj);
}
private var\u serviceHttp:HTTPService=newhttpservice;
私有函数postBytes():void{
var-xml:xml=value;
变量字节:ByteArray=newbytearray();
bytes.writeObject(xml);
字节。位置=0;
compress();
var enc:Base64Encoder=新的Base64Encoder();
enc.encodeBytes(字节,0,字节.长度);
var myObj:Object=新对象();
myObj[“字节”]=enc.toString();
//myObj[“其他变量”]=您的其他变量;
_serviceHttp.method=“POST”;
_serviceHttp.resultFormat=“flashvars”;
_serviceHttp.url=此处为您的url;
_serviceHttp.addEventListener(ResultEvent.RESULT,urlHandler);
_serviceHttp.addEventListener(FaultEvent.FAULT,urlErrorHandler);
_serviceHttp.send(myObj);
}

在取消压缩之前,请尝试使用bytes.position=0?谢谢,但没有帮助。我试着在压缩后打印出字节值,在解压缩前打印出字节值——一半的符号被问号替换了。必须是编码,对吗?可能,我会查看(httpfox)发送到服务器的数据,并与返回的数据进行比较。一旦运行压缩,文件将不再是人类可读的。我能想到的一件事是尝试编写xml文件的字符串版本。toXMLString();它的可读性足以告诉我们它已经改变了。之前:·ÉI-KãRP°)I,IË/Ê-34āGð@råùyÅvF6È0?3Ô0QÍuL IXZëIŧ!n?6=之后:I-K?RP??I,I?/?-34?G?r?y?vF6?0?3?0Q?uL?IXZ?I@Cm?!这只是我的压缩代码。正如我所提到的,这很好——它是以二进制格式发送的,我遇到了一个问题。当我添加Base64(它没有普通二进制那么紧凑)时,我在解压字符串的开头添加了额外的字符:“Wvalue”,因此对“new XML(new string(bytes))”的调用会因格式错误的XML错误而终止。啊哈!终于找到了“W”的来源,它是由
bytes.writeObject(xml)
添加的某种头。如果改用
bytes.writeUTFBytes(xml)
,它不会出现。
private var _serviceHttp:HTTPService = new HTTPService;

private function postBytes():void {
    var xml:XML = <contents><thing>value</thing></contents>;
    var bytes:ByteArray = new ByteArray();
    bytes.writeObject(xml);
    bytes.position = 0;
    bytes.compress();
    var enc:Base64Encoder = new Base64Encoder();
    enc.encodeBytes(bytes, 0, bytes.length);
    var myObj:Object = new Object();
    myObj["bytes"] = enc.toString();
    // myObj["other_variables"] = your_other_varaibles;
    _serviceHttp.method = "POST";
    _serviceHttp.resultFormat = "flashvars";
    _serviceHttp.url = your_url_here;
    _serviceHttp.addEventListener(ResultEvent.RESULT, urlHandler);
    _serviceHttp.addEventListener(FaultEvent.FAULT, urlErrorHandler);
    _serviceHttp.send(myObj);
}