柚子快报激活码778899分享:断点续传(上传)C#版

http://yzkb.51969.com/

 断点续传(上传)Java版

1. 客户每次上传前先获取一下当前文件已经被服务器接受了多少

2. 上传时设定偏移量

服务端代码如下:

///

/// 断点续传,获取已上传文件大小

///

///

[HttpPost]

public long GetFileLength()

{

long result = 0;

FileStream fStream = null;

BinaryReader bReader = null;

try

{

var fileName = "";

IEnumerable hasFileNameList = new List();

bool hasFileName = Request.Headers.TryGetValues("FileName", out hasFileNameList);

if (hasFileName && hasFileNameList.Any())

{

fileName = hasFileNameList.First();

}

//设置文件存放路径

string dir = HttpContext.Current.Server.MapPath(@"~\UploadFiles");

fileName= dir+"\\"+fileName;

if (File.Exists(fileName))

{

FileInfo file = new FileInfo(fileName);

result = file.Length;

}

}

catch (Exception ex)

{

logger.Error(ex, ex.Message);

}

return result;

}

///

/// 断点续传 服务端保存文件代码

/// Offset 偏移量

///

///

[HttpPost]

public Bussiness UploadFile()

{

#region Log Test

FileStream fStreamLog = null;

BinaryReader bReaderLog = null;

try

{

fStreamLog = new FileStream(SavePath + "\\" + $"{DateTime.Now:HHmmss}.File.tmp", FileMode.OpenOrCreate, FileAccess.ReadWrite);

int upLoadLengthTest = (int)HttpContext.Current.Request.InputStream.Length;

bReaderLog = new BinaryReader(HttpContext.Current.Request.InputStream);

byte[] dataTest = new byte[upLoadLengthTest];

bReaderLog.Read(dataTest, 0, upLoadLengthTest); //将上传文件流读到byte[]中

fStreamLog.Write(dataTest, 0, upLoadLengthTest); //将byte[]写到文件中,

}

catch (Exception exr)

{

logger.Error(exr, exr.Message);

}

finally

{

if (fStreamLog != null)

{

//释放流

fStreamLog.Close();

}

if (bReaderLog != null)

{

bReaderLog.Close();

}

}

#endregion

var uploadFileName = HttpContext.Current.Request.Form["UploadFileName"];

Bussiness result = new Bussiness();

FileStream fStream = null;

BinaryReader bReader = null;

try

{

long offset = 0; //客户端定义,从X开始往后写,该值由服务端GetFileLength方法提供

IEnumerable hasOffsetList = new List();

bool hasOffset = Request.Headers.TryGetValues("Offset", out hasOffsetList);

if (hasOffset && hasOffsetList.Any())

{

long.TryParse(hasOffsetList.First(), out offset);

}

var offsetStr = HttpContext.Current.Request.Form["Offset"];

if (!string.IsNullOrEmpty(offsetStr))

{

long.TryParse(offsetStr, out offset);

}

if (string.IsNullOrEmpty(uploadFileName))

{

result.BussinessCode = -1;

result.BussinessMsg = "uploadFileName 上传文件名不能为空";

result.BussinessData = false;

return result;

}

//设置文件存放路径

//string dir = HttpContext.Current.Server.MapPath(SavePath);

string dir = SavePath;

//如果不存在文件夹,就创建文件夹

if (!Directory.Exists(dir))

Directory.CreateDirectory(dir);

//////var fileName = dir + "\\" + file.FileName; ///TODO

var fileName = dir + "\\" + (string.IsNullOrEmpty(uploadFileName) ? $"{DateTime.Now.ToString("HHmmss")}.txt" : uploadFileName);

fStream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);

//偏移指针

fStream.Seek(offset, SeekOrigin.Begin);

if (HttpContext.Current.Request.Files.Count > 0)

{

#region 文件形式

HttpPostedFile file = HttpContext.Current.Request.Files["UploadFile"];

int upLoadLength = Convert.ToInt32(file.InputStream.Length);

//从客户端的请求中获取文件流

bReader = new BinaryReader(file.InputStream);

byte[] data = new byte[upLoadLength];

bReader.Read(data, 0, upLoadLength); //将上传文件流读到byte[]中

fStream.Write(data, 0, upLoadLength);//将byte[]写到文件中,

logger.Info($"上传文件 {uploadFileName} Offset => {offset} File.ContentLength => {upLoadLength} => {fileName}");

#endregion

}

else

{

#region Base64

//如果没传文件是以byte[]

var byteFile = HttpContext.Current.Request.Form["UploadFile"];

byte[] byteArray = Convert.FromBase64String(byteFile);

int upLoadLength = Convert.ToInt32(byteArray.Length);

fStream.Write(byteArray, 0, upLoadLength);//将byte[]写到文件中,

logger.Info($"上传文件 {uploadFileName} Offset => {offset} File.ContentLength => {upLoadLength} => {fileName}");

#endregion

}

result.BussinessData = true;

result.BussinessMsg = $"上传成功!";

result.BussinessCode = 0;

}

catch (Exception ex)

{

logger.Error(ex, ex.Message);

result.BussinessCode = -1;

result.BussinessMsg = ex.Message;

result.BussinessData = false;

#region 出异常后,看看客户端上传的啥

FileStream fstreamErr = null;

BinaryReader readerErr = null;

try

{

fstreamErr = new FileStream(SavePath + "\\" + $"{uploadFileName}_{DateTime.Now:HHmmss}.err", FileMode.OpenOrCreate, FileAccess.ReadWrite);

int upLoadLength = (int)HttpContext.Current.Request.InputStream.Length;

readerErr = new BinaryReader(HttpContext.Current.Request.InputStream);

byte[] data = new byte[upLoadLength];

readerErr.Read(data, 0, upLoadLength); //将上传文件流读到byte[]中

fstreamErr.Write(data, 0, upLoadLength); //将byte[]写到文件中,

}

catch (Exception exr)

{

logger.Error(exr, exr.Message);

}

finally

{

if (fstreamErr != null)

{

//释放流

fstreamErr.Close();

}

if (readerErr != null)

{

readerErr.Close();

}

}

#endregion

return result;

}

finally

{

if (fStream != null)

{

//释放流

fStream.Close();

}

if (bReader != null)

{

bReader.Close();

}

}

return result;

}

 

上传前,源和目标文件对比

用 Postman 测试

先获取已上传文件的大小,供下面设置偏移量使用

 

 

 

 

 

 

 

 

 

上传后的源和目标文件对比

 

 

 

 

java 客户端代码

package com.vipsoft.demo.Controller;

import org.springframework.core.io.FileSystemResource;

import org.springframework.util.LinkedMultiValueMap;

import org.springframework.util.MultiValueMap;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;

import java.io.File;

import java.io.RandomAccessFile;

import java.util.Base64;

@RestController

@RequestMapping("/demo")

public class DemoController {

@GetMapping(value = "/test")

public String login() {

return "这是demo下面的,用来写测试代码,测试通过后,移到正式项目中!";

}

@GetMapping(value = "/uploadFile")

public String uploadFile(HttpServletRequest request) throws Exception {

String url = "http://localhost:44999/api/Upload/UploadFile";

RestTemplate restTemplate = new RestTemplate();

String filePath = "D:\\Projects\\TEST.DAT";

File file = new File(filePath);

FileSystemResource resource = new FileSystemResource(file);

MultiValueMap param = new LinkedMultiValueMap<>();

param.add("Offset", "6");

param.add("UploadFileName", "ABC.txt");

param.add("UploadFile", resource);

String rev = restTemplate.postForObject(url, param, String.class);

System.out.println(rev);

return rev;

}

@GetMapping(value = "/uploadByte")

public String uploadByte(HttpServletRequest request) throws Exception {

String url = "http://localhost:44999/api/Upload/UploadFile";

RestTemplate restTemplate = new RestTemplate();

String filePath = "D:\\Projects\\TEST.DAT";

File file = new File(filePath);

//每次上传 10KB

int step = 10 * 1024;

for (long i = 0; i <= file.length(); i = i + step) {

//偏移量

long offset = i;

byte[] bytes = new byte[step];

//如果超过了就取最后的。

if (i + step > file.length()) {

bytes = new byte[(int) (file.length() - i)];

}

RandomAccessFile raf = new RandomAccessFile(file, "r");

raf.seek(offset);

int readSize = raf.read(bytes);

MultiValueMap param = new LinkedMultiValueMap<>();

param.add("Offset", i);

param.add("UploadFileName", "ABC.txt");

//转成 Base64

param.add("UploadFile", Base64.getEncoder().encodeToString(bytes));

String rev = restTemplate.postForObject(url, param, String.class);

//如果接口返回值出错,break

System.out.println(rev);

}

return "";

}

}

 

 

C# 客户端伪代码

 

///

/// 客户端上传伪代码

///

/// 待上传文件全路径

/// 上传时的流量控制,文件较大时,用于切割文件上传

/// 错误信息

/// 成功或者失败

public static bool UpLoadFile(string fileName, int byteCount, out string msg)

{

msg = "";

bool result = true;

long cruuent = GetServerFileLength(fileName); //客户端需要读取服务器已上传了多少内容,然后从偏移量开始往后读取发送

FileStream fStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);

BinaryReader bReader = new BinaryReader(fStream);

long length = fStream.Length;

fileName = fileName.Substring(fileName.LastIndexOf('\\') + 1);

#region 开始上传文件

try

{

#region 续传处理

byte[] data;

if (cruuent > 0)

{

fStream.Seek(cruuent, SeekOrigin.Current);

}

#endregion

#region 分割文件上传

for (; cruuent <= length; cruuent = cruuent + byteCount)

{

try

{

if (cruuent + byteCount > length)

{

data = new byte[Convert.ToInt64((length - cruuent))];

bReader.Read(data, 0, Convert.ToInt32((length - cruuent)));

}

else

{

data = new byte[byteCount];

bReader.Read(data, 0, byteCount);

}

Hashtable parms = new Hashtable();

parms.Add("Offset", cruuent.ToString());

var falg= PostData("",param);

if (falg == false)

{

break;

}

}

catch (Exception ex)

{

msg = ex.ToString();

result = false;

break;

}

#endregion

}

}

catch (Exception ex)

{

throw ex;

}

finally

{

bReader.Close();

fStream.Close();

}

GC.Collect();

#endregion

return result;

}

 

柚子快报激活码778899分享:断点续传(上传)C#版

http://yzkb.51969.com/

精彩内容

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。