I have the following problem.
I have an ActiveX control written in C ++ / CLI that I use on the client side. one of the control methods returns a binary file at a fixed block size (for example, at 1024). This file is archived.
I need to write a method using C ++ / CLI that will send every fragment of the file to the server. I have a Java Spring MVC method that receives this byte [] chunk and adds it to a file. In other words, I just upload the zip file in chunks.
My problem is that although the file size of both files (the original and its copying on the server), the MD5 checksum of this file is different from it, and I can not open this file using zip. The file is damaged.
I just take each chunk byte [] convert it from BASE64 and send it to the server using my usual POST request:
My code is as follows:
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;
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();
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 is as follows:
@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 is resolved. The original Base64 String had “+” characters, after sending the request to the server, the chunk parameter was URLdecoded with Spring, and all the “+” characters were replaced with spaces, causing the zip file to be corrupted. Please give me back my +50 reputation :)
Thanks, Danny.