I have the following problem.
I have a ActiveX control written in C++/CLI, which I'm using on client side. one of the control method return binary file by fixed chunk size (for example by 1024). This file is zipped.
I need to write method using C++/CLI whi开发者_如何学运维ch will send each file chunk to the server. I have Java Spring MVC method which receives this byte[] chunk and append it to file. In other words I'm just uploading zip file by chunks.
My problem is, that although the file size of both files (Original and its copy on server) ,the MD5 checksum of this file is not the same and I can't open this file using zip. The file is corrupted.
I'm just taking each chunk byte[] convert it with BASE64 and send it to server using my regular POST request:
My code is the following:
int SceneUploader::AddChunk(int id, array<Byte> ^buffer,int size){
WebRequest^ request = WebRequest::Create(AddChunkURI);
request->Method = "POST";
request->ContentType = "application/x-www-form-urlencoded";
System::String ^base64Image = Convert::ToBase64String(buffer);
String ^param = "id="+id+"&chunk="+base64Image+"&len="+size;
//Just make another copy of the file to verify that sent byted are ok!!!
String ^path = "C:\\Users\\dannyl\\AppData\\Local\\Temp\\test.zip";
FileStream ^MyFileStream = gcnew FileStream(path, FileMode::Append, FileAccess::Write);
MyFileStream->Write(buffer,0,size);
MyFileStream->Close();
//Adding the byteArray to the stream.
System::IO::Stream ^stream = request->GetRequestStream();
System::IO::StreamWriter ^streamWriter = gcnew System::IO::StreamWriter(stream);
streamWriter->Write(param);
streamWriter->Close();
HttpWebResponse^ response = dynamic_cast<HttpWebResponse^>(request->GetResponse());
Stream^ dataStream = response->GetResponseStream();
StreamReader^ reader = gcnew StreamReader( dataStream );
String^ responseFromServer = reader->ReadToEnd();
return System::Int32::Parse(responseFromServer);
}
My MVC controller looks like this:
@RequestMapping(value="/addChunk.dlp",method = RequestMethod.POST)
@ResponseBody
public String addChunk(@RequestParam("id") String id,
@RequestParam("chunk") String chunk,
@RequestParam("len") String len){
try{
BASE64Decoder decoder = new BASE64Decoder();
Integer length = Integer.decode(len);
byte[] decodedBytes = new byte[length];
decodedBytes = decoder.decodeBuffer(chunk.trim());
File sceneFile = new File(VAULT_DIR+id+".zip");
if (!sceneFile.exists()){
sceneFile.createNewFile();
}
long fileLength = sceneFile.length();
RandomAccessFile raf = new RandomAccessFile(sceneFile, "rw");
raf.seek(fileLength);
raf.write(decodedBytes);
raf.close();
}
catch(FileNotFoundException ex){
ex.getStackTrace();
System.out.println(ex.getMessage());
return "-1";
}
catch(IOException ex){
ex.getStackTrace();
System.out.println(ex.getMessage());
return "-1";
}
return "0";
}
What am I doing wrong?
Update: the problem solved. Original Base64 String had '+' characters, after the request was submitted to server the chunk parameter was URLdecoded by Spring and all'+' characters were replaced by spaces, as a result zip file was corrupted. Please give me back my +50 of reputation :)
Thank you, Danny.
I have not experienced about your client-side for sending file to server with HTTP.
In server side, however, you may check out the Spring MVC Multipart. And in client side, sending file with Multipart is another way to achieve your goal.
精彩评论