It has always been a relatively difficult technology to upload large files on the terminal, which involves the interaction between the backend and the frontend, stability and traffic size. Moreover, everyone has their own ideas for the implementation principle. The mainstream backend uses Http more often because most of them implement breakpoint downloads. However, stability cannot be guaranteed, and once it is disconnected, it cannot be continued. So you have to adopt another popular method, TCP uploads large files.
I searched for some information online, most of which were downloaded by breakpoints, and then uploaded and received by the C# side, either HTTP or Android side only. Since the task is tight, the preferred solution I found before is of course Http to first realize file upload. The terminal uses the Post method to directly pass the file to the backend, and the backend obtains it through File.
Android side:
RequestParams params = new RequestParams(); File file = getTempFile();//Get local files try { ("file", file); } catch (FileNotFoundException e1) { (); } (URL + "/UpLoad", params, new JsonHttpResponseHandler() { ……
rear end:
var file = ["file"];
(upFileName);
There are other better ways to handle it, which can also be transmitted in without going through the file format. There is no problem when the network is good, but the network almost often gets offline when half of the uploads are dropped or multiple clients are uploaded, which is extremely unstable for large files, so we quickly develop TCP protocol file breakpoint upload.
Some netizens also implemented Http breakpoint upload. Since large files cannot work, split the files into small files to upload. The main methods of pure NET:
Upload:
bool result = true; long cruuent = 0; FileStream fStream = new FileStream(fileName, , ); BinaryReader bReader = new BinaryReader(fStream); //Simulate breakpoint upload, only 100 bytes is uploaded for the first time long length = 100; fileName = (('\\') + 1); #region Start uploading files try { byte[] data; #region Segment file upload for (; cruuent <= length; cruuent = cruuent + byteCount) { if (cruuent + byteCount > length) { data = new byte[Convert.ToInt64((length - cruuent))]; (data, 0, Convert.ToInt32((length - cruuent))); } else { data = new byte[byteCount]; (data, 0, byteCount); } try { Hashtable parms = new Hashtable(); ("fileName", fileName); ("npos", ()); byte[] byRemoteInfo = PostData(serverPath + "", data, parms); } catch (Exception ex) { msg = (); result = false; break; } #endregion } } catch (Exception ex) { msg = (); result = false; } finally { (); (); } ();
First divide the file into small streams, npos is the location of the breakpoint, that is, the size that has been uploaded, and then upload all packages in a loop.
Backend reception:
/// <summary> /// Save the file (get the file name and current pointer from the URL parameters, and save the file stream to the current pointer) /// If it is the first upload, the current pointer is 0. The code execution is the same as the continuous pass, except that the pointer has no offset /// </summary> public void SaveUpLoadFile() { string fileName = ["fileName"]; long npos = Convert.ToInt64(["npos"]); int upLoadLength = Convert.ToInt32(); string path = ("/UpLoadServer"); fileName = path + "//UpLoad//" + fileName; FileStream fStream = new FileStream(fileName, , ); //Offset pointer (npos, ); //Get file stream from client request BinaryReader bReader = new BinaryReader(); try { byte[] data = new byte[upLoadLength]; (data, 0, upLoadLength); (data, 0, upLoadLength); } catch { //TODO Add exception handling } finally { //Release the flow (); (); } }
The focus is on (npos, ); receive saves from breakpoint locations.
If you are interested, you can do it yourself.
Now we mainly talk about client TCP upload and background TCP reception. The main idea is: the Android side reads the local file and uploads the file name and file size to the server (the file name must be globally unique). The server will query whether it has been uploaded based on the file name. If it has been uploaded, the size of the transmitted file, that is, the breakpoint position, is passed to the terminal. After the terminal receives, the breakpoint position will be saved first, and then reads the file from the breakpoint position to upload intermittently until all are completed. If not uploaded, the server creates a cache file to receive.
Check out the code Android:
String head = "Length=" + () + ";filename=" + filename Socket socket = new Socket("192.168.0.123", 7080); OutputStream outStream = (); (());//send PushbackInputStream inStream = new PushbackInputStream(()); String response = (inStream);//Read String[] items = (";"); final String position = items[0].substring(items[0].indexOf("=") + 1);//Breakpoint position final String serviceurl = items[1].substring(items[1].indexOf("=") + 1);//Save to server path RandomAccessFile fileOutStream = new RandomAccessFile(uploadFile, "r"); ((position));//Read the file from the breakpoint position byte[] buffer = new byte[1024]; int len = -1; int length = (position);//The uploaded size is used for local display while ( (len = (buffer)) != -1) { (buffer, 0, len); length += len; Message msg = new Message(); ().putInt("size", length); // Update the upload progress (msg); } if (length == ()) {//If it is equal, it means the upload is successful} (); (); (); (); (); (); ();
Backend processing:
private static TcpListener listener;//Server listening IPAddress ipHost = ; listener = new TcpListener(ipHost, 7080); ();//Open monitoring Socket remoteSocketClient = (); device = new Device(remoteSocketClient); //Open a thread to process threaddev = new Thread(new ThreadStart()); = threaddev; = true; ();
Scan processing method:
string[] items = (';'); string filelength = items[0].Substring(items[0].IndexOf("=") + 1); string filename = items[1].Substring(items[1].IndexOf("=") + 1); //File save path filePath = (directoryPath, filename); //Breakpoint position long position = 0; if ((filePath)) { using (FileStream reader = new FileStream(filePath, , , )) { position = ; } } //Return message response = "position=" + position + ";serviceurl=" + dirPath + "/" + filename) ; //After the server receives the client's request information, it returns the response information to the client:;position=0 //serviceurl File location saved by the waiter /PlayFiles/video/2016/07/04/1141142221.mp4 bufferSend = Encoding.(response); (bufferSend);
Then process the content of the retransmission:
// Obtain the file content byte[] buffer = new byte[BufferSize]; int received = 0; long receive, length = (filelength); FileInfo file = new FileInfo(filePath); using (FileStream writer = ( ? : , , )) { receive = ; while (receive < length) { if ((received = (buffer)) == 0) { (" IP【" + () + "】Received pause!"); break; } (buffer, 0, received); (); receive += (long)received; } } if (receive == length) { (" IP【" + () + "】take over" + filename + "Finish!"); }
The main principle is to upload and receive from breakpoint locations.
Here we only talk about the most important code functions, and there are many details to deal with, such as the terminal needs to display progress, so we also need to save the progress, will the saving of the backend file be misplaced, will the upload of multiple files be messed up, whether multiple clients uploads create a new thread or a thread pool to handle, etc.
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.