fullpath = dt.Rows[i]["path"].ToString();
string fid = dt.Rows[i]["fid"].ToString();
clsDownloadFiles returm = new clsDownloadFiles();
var client = new RestClient("download_path");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AlwaysMultipartFormData = true;
request.AddParameter("accesskeyid", "accesskeyid");
request.AddParameter("accesssecret", "accesssecret");
request.AddParameter("dstfile", fullpath);
request.AddParameter("machineid", "657");
//获取文件
IRestResponse response = client.Execute(request);
clsDownloadFiles dailyResult = Newtonsoft.Json.JsonConvert.DeserializeObject<clsDownloadFiles>(response.Content);
byte[] memoryToString1 = dailyResult.data.data;
string filename = dailyResult.data.name.ToString();
200M的json 确实太大了些,接口不能分页去取吗 ,然后再合并
处理大文件时报错:内存溢出System.OutOfMemoryException
代码里不要把数据一次性读入内存,可以进行分片读取
一个文件可能很大,无法一次读取到内存中,所以要分段读取;虽然简单,不过经常用到,就写到这里;
这里为了简单演示,将所有代码在一个函数中完成,具体应用中当然还是要封装一下;
void CTmfc2Dlg::ReadFileT()
{
// TODO: Add your control notification handler code here
char * pstrFileName = "G:\\176x144.264";
const int nBufLen = 1000;
BYTE pbuf[nBufLen]={0};
int nTell = 0;
int nReadLen = 0;
static int nFileLen = 0;
static BOOL b = TRUE;
if ( b == TRUE )//»ñÈ¡Îļþ´óС£»
{
FILE * fpFileLen = fopen( pstrFileName, "r+b" );
fseek( fpFileLen, 0, SEEK_END );
nFileLen =ftell(fpFileLen);
fclose(fpFileLen);
b = 0;
}
static FILE * fp = fopen( pstrFileName, "r+b" );
nReadLen = fread( pbuf, 1, nBufLen, fp );
nTell = ftell( fp );
SetDlgItemInt( IDC_EDIT1, nReadLen );
SetDlgItemInt( IDC_EDIT2, nTell );
SetDlgItemInt( IDC_EDIT3, nFileLen );
if ( nTell == nFileLen )
{
fclose( fp );
AfxMessageBox("Îļþ¶ÁÈ¡OK¡£");
}
}
将文件分包下载,调用端传入文件信息(名称,内容批次,每次长度),服务端按参数读取文件内容返回即可。其实就是数据的分页查询的思路。
返回200M文件用base64编码一下,再通过json格式返回? 这么魔性的API设计也真是醉了,这后端是实习生开发的吧。。。
假设后端没法改的情况下,前端可以这么来做:
1 搜一下 C# http 下载文件,找代码参考
2 得到http响应的Stream
3 创建BufferStream来读Stream(减少系统调用次数)
4 循环读一个字符,直到冒号: 再循环读一个字符,直到引号" (找到实际base64数据的开头)
5 循环:
5.1 读4个非空字符 (如果空格换行则再读下一个字符,如果非base64字符则跳出循环)
5.2 base64解码得到1至3个字节 (前面每段3字节,最后一段可能没有3字节)
5.3 写入解码后的字节到文件
Json.NET 支持从流中反序列化,所以可以将你下载的json字符串转换成二进制流,然后通过JsonReader
对象进行反序列化,示例如下:
var json = "你的JSON字符串";
var serializer = new JsonSerializer();
MyObject o;
using (var s = new MemoryStream(Encoding.UTF8.GetBytes(json)))
using (var sr = new StreamReader(s))
using (JsonReader reader = new JsonTextReader(sr))
{
while (reader.Read())
{
if (reader.TokenType == JsonToken.StartObject)
{
o = serializer.Deserialize<MyObject>(reader);
}
}
}
public class MyObject
{
public string Data { get; set; }
}
完整示例:
using Newtonsoft.Json;
using System;
using System.IO;
using System.Text;
namespace ConsoleApp2
{
internal class Program
{
static void Main(string[] args)
{
var json = "{\"data\":\"123456\"}"; // 你的JSON字符串
var serializer = new JsonSerializer();
var o = new MyObject();
using (var s = new MemoryStream(Encoding.UTF8.GetBytes(json)))
using (var sr = new StreamReader(s))
using (JsonReader reader = new JsonTextReader(sr))
{
while (reader.Read())
{
if (reader.TokenType == JsonToken.StartObject)
{
o = serializer.Deserialize<MyObject>(reader);
}
}
}
Console.WriteLine(o.Data);
Console.ReadKey();
}
}
public class MyObject
{
public string Data { get; set; }
}
}
你好,
建议你使用二进制流。
public static byte[] ReadFully(Stream input)
{
byte[] buffer = new byte[16*1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
return ms.ToArray();
}
}
文件切分,多次传输。
然后本地处理。
压缩也可以试试,但是效果不一定。
如果能申请一下更大的内存也行。
或者先存本地,然后用本地的其他方式处理
链接:https://pan.baidu.com/s/1AJJQ2wn1z5qFm4WduNHfIQ
提取码:sqmj
我将两个json放在了百度云盘,每个文档里面有个data,就是要将它转换成文件;
两个json文件的data转换生成两个压缩文件
pm_hq_order_spot.7z.001 和pm_hq_order_spot.7z.002
能解压说明就成功了,但是一般在解压pm_hq_order_spot.7z.001就会失败
你先获取数据长度,根据长度初始化一个同样长的变量,用来接收数据。
发生类型为 System.OutOfMemoryException 的异常是设置错误造成的,解决方法为:
1、首先使用百度杀毒软件对全盘进行杀毒操作,杀毒完成后重新安装软件。
2、开始→运行→输入cmd→回车。
3、进入,在命令提示符下输入for %1 in (%windir%\system32*.ocx) do regsvr32 /s %1右键粘贴 回车 。
4、完成后再输入for %1 in (%windir%\system32*.dll) do regsvr32.exe /s %1右键粘贴 回车 即可。
在machine.config配置文件中,的“memoryLimit”属性,这个属性的值是一个百分值,默认是60。对于一台>4G内存的服务器,最好将“memoryLimit”属性设置成“20”,可以调整试下。