之前的学长写的一个APP部署在Telerik,近期由于某些原因需要对数据做迁移。
由此,进入第一步:从Telerik获取数据
Telerik提供的rest api简单易用,直接通过对应的文件存储的路径,就可以获取对应的JSON数据
- 获取用户存储的数据http://api.everlive.com/v1/appid/Files/
- 获取用户信息http://api.everlive.com/v1/“ + appId + “/Users/“
以下为项目完整代码(可人为控制成功率)
class Program
{
/// <summary>
/// // 收集下载失败的文件的信息
/// </summary>
private static List<Items>
itemsList = new List<Items>();
private static string PATH = "";
/// <summary>
/// 文件总数 默认 0
/// </summary>
private static int count = 0;
/// <summary>
/// 已下载文件数
/// </summary>
private static int downed = 0;
/// <summary>
/// 正在下载的文件的序号
/// </summary>
private static int downing = 0;
/// <summary>
/// 下载成功文件数
/// </summary>
private static int succ = 0;
/// <summary>
/// 下载失败文件数
/// </summary>
private static int erro = 0;
/// <summary>
/// 再次下载时,成功的次数
/// </summary>
private static int succag = 0;
/// <summary>
/// 再次下载时,失败的次数
/// </summary>
private static int erroag = 0;
/// <summary>
/// 此次需要下载的文件次数
/// </summary>
private static int countag = 0;
/// <summary>
/// 下载失败的log路径
/// </summary>
private static string path0 = "";
/// <summary>
/// 写入文件的字符
/// </summary>
private static StringBuilder sb = new StringBuilder();
static void Main(string[] args)
{
downlaodCC();
//Task.Run(()=> readUsers());
Console.ReadKey();
}
/// <summary>
/// 从指定路径URI再次下载文件
/// </summary>
/// <param name="uri"></param>
/// <param name="path"></param>
public static void downag(string uri, string path)
{
//Console.WriteLine("第" + (downing + 1) + "个文件" + "开始下载");
WebClient client = new WebClient();
try
{
client.DownloadFile(uri, path);
WriteLog("第" + (downing + 1) + "个文件" + uri + "下载成功");
Console.WriteLine("第" + (downing + 1) + "个文件" + uri + "下载成功");
succag++;
//downed++;
}
catch
{
WriteLog("第" + (downing + 1) + "个文件" + uri + "下载失败");
Console.WriteLine("第" + (downing + 1) + "个文件" + uri + "下载失败");
//downsag(uri, path, 1 , (downing + 1));
Items items = new Items();
items.CreatedBy = "";
items.Filename = path;
items.Uri = uri;
itemsList.Add(items);
erroag++;
sb.AppendLine("第" + downing + "个文件" + uri + " 下载失败");
}
downed++;
downing++;
if (downed == countag)
{
succ += succag;
erro = erroag;
WriteLog("第二次下载完成,共" + countag + "个文件\n" + "成功" + succag + "个;\n 失败" + erro + "个\n" + "失败率" + Convert.ToDouble((erro * 1.00 / (succag + erro))).ToString("P"));
Console.WriteLine("第二次下载完成,共" + countag + "个文件\n" + "成功" + succag + "个;\n 失败" + erro + "个\n" + "失败率" + Convert.ToDouble((erro * 1.00 / (succag + erro))).ToString("P"));
sb.AppendLine("总计" + count + "个文件");
WriteLog("总计" + count + "个文件\n" + "成功" + succ + "个;\n 失败" + erro + "个\n" + "失败率" + Convert.ToDouble((erro * 1.00 / count)).ToString("P"));
Console.WriteLine("总计" + count + "个文件\n" + "成功" + succ + "个;\n 失败" + erro + "个\n" + "失败率" + Convert.ToDouble((erro * 1.00 / count)).ToString("P"));
sb.AppendLine("共" + erroag + "个文件下载失败");
if (File.Exists(path0))
{
File.Delete(path0);
}
File.WriteAllText(path0, sb.ToString());
// 控制失败率为1% 进行循环下载
if ((erro * 1.00 / count) > 0.01)
{
showErro();
}
else
{
readUsers();
}
}
}
/// <summary>
/// 此方法目前未用
/// </summary>
/// <param name="uri"></param>
/// <param name="path"></param>
/// <param name="times"></param>
/// <param name="downingNum"></param>
public static void downsag(string uri, string path, int times, int downingNum)
{
if (times < 1)
{
WebClient client = new WebClient();
try
{
client.DownloadFile(uri, path);
WriteLog("第" + downingNum + "个文件" + "第" + (times + 1) + "次尝试下载 " + uri + "下载成功");
Console.WriteLine("第" + downingNum + "个文件" + "第" + (times + 1) + "次尝试下载 " + uri + "下载成功");
succ++;
erro--;
downed++;
}
catch
{
WriteLog("第" + downingNum + "个文件" + "第" + (times + 1) + "次尝试下载 " + uri + "下载失败");
Console.WriteLine("第" + downingNum + "个文件" + "第" + (times + 1) + "次尝试下载 " + uri + "下载失败");
downsag(uri, path, (times + 1), downingNum);
}
}
else
{
downed++;
sb.AppendLine("第" + downingNum + "个文件" + "11次尝试下载 " + uri + " 下载失败");
}
if (downed == count)
{
WriteLog("ccccc下载完成,共" + count + "个文件\n" + "成功" + succ + "个;\n 失败" + erro + "个\n" + "失败率" + Convert.ToDouble((erro * 1.00 / count)).ToString("P"));
Console.WriteLine("ccccc下载完成,共" + count + "个文件\n" + "成功" + succ + "个;\n 失败" + erro + "个\n" + "失败率" + Convert.ToDouble((erro * 1.00 / count)).ToString("P"));
sb.AppendLine("共" + erro + "个文件下载失败");
File.WriteAllText(path0, sb.ToString());
}
}
public static void downlaodCC()
{
string appId = "";
WriteLog("Select the app you want\n input 'b':babycare \t input 'o':others");
Console.WriteLine("Select the app you want\n input 'b':babycare \t input 'o':others");
string app = Console.ReadLine();
if (app.Equals("b"))
{
appId = "kzdfjgbhdjkfghjkdfsgjksdngjklsdhgjklsdhngjfgkds";
}
else
{
WriteLog("Input your appId:");
Console.Write("Input your appId:");
appId = Console.ReadLine();
}
WriteLog("Input your File path");
Console.WriteLine("Input your File path");
inputPath();
#region MyRegion
/*string filePath = Console.ReadLine();
PATH = filePath + @"\telerikFile";
try
{
Directory.CreateDirectory(PATH);
Console.WriteLine("创建成功");
}
catch
{
Console.WriteLine("路径错误请重新输入");
inputPath();
}*/
#endregion
//提供用于将数据发送到由 URI 标识的资源及从这样的资源接收数据的常用方法。
WebClient wc = new WebClient();
try
{
//wc.DownloadFile("http://api.everlive.com/v1/"+appId+"/Files/", @"e:\Files.txt");
// 下载用户信息 Json
wc.DownloadFile("http://api.everlive.com/v1/" + appId + "/Users/", PATH + @"Users.txt");
}
catch
{
WriteLog("网络不通");
Console.WriteLine("网络不通");
}
//string str = System.IO.File.ReadAllText("e:\Files.txt");
// 下载指定APP的用户文件基本信息
string json = wc.DownloadString("http://api.everlive.com/v1/appid/Files/");
JObject sum = (JObject)JsonConvert.DeserializeObject(json);
// 获取文件总数
count = int.Parse(sum["Count"].ToString());
WriteLog("一共有" + count + "个文件");
Console.WriteLine("一共有" + count + "个文件");
JArray result = JArray.Parse(sum["Result"].ToString());
for (var i = 0; i < result.Count; i++)
{
JObject j = JObject.Parse(result[i].ToString());
WriteLog("第" + (i + 1) + "组数据" + "开始下载");
Console.WriteLine("第" + (i + 1) + "组数据" + "开始下载");
string path = PATH + j["CreatedBy"].ToString() + "\\";
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
WriteLog(j["CreatedBy"].ToString());
Console.WriteLine(j["CreatedBy"].ToString());
WriteLog(j["Uri"].ToString());
Console.WriteLine(j["Uri"].ToString());
WriteLog(j["Filename"].ToString());
Console.WriteLine(j["Filename"].ToString());
//ThreadPool.QueueUserWorkItem(new WaitCallback(dt.downs));
Task.Run(() => downs(j["Uri"].ToString(), path + j["Filename"].ToString()));
//路径应该设置为用户注册邮箱,设想:重新查询后,对文件夹进行重命名
//Thread.Sleep(10);
}
}
/// <summary>
/// 输入保存用户文件的路径
/// </summary>
public static void inputPath()
{
string ss = Console.ReadLine();
PATH = ss + @"\telerikFile\";
try
{
Directory.CreateDirectory(PATH);
WriteLog("路径可用\n正在继续");
Console.WriteLine("路径可用\n正在继续");
path0 = PATH + @"\log.txt";
}
catch
{
WriteLog("路径错误请重新输入");
Console.WriteLine("路径错误请重新输入");
inputPath();
}
}
public static void showErro()
{
WriteLog("再次尝试下载");
Thread.Sleep(3000);
Console.WriteLine("第二次尝试下载");
int i = 1;
sb = new StringBuilder();
erroag = 0;
succag = 0;
countag = erro;
downing = 0;
downed = 0;
/* string ins = Console.ReadLine();
if (ins.Equals("y")) { */
List<Items> itemsListag = itemsList;
itemsList = new List<Items>();
foreach (Items items in itemsListag)
{
WriteLog("第" + i + "个文件" + items.Uri + "开始下载");
Console.WriteLine("第" + i + "个文件" + items.Uri + "开始下载");
//Console.WriteLine("第"+i+"个失败文件"+items.CreatedBy);
//Console.WriteLine(items.Filename);
//Console.WriteLine(items.Uri);
Task.Run(() => downag(items.Uri, items.Filename));
i++;
// }
}
}
/// <summary>
/// 获取用户
/// </summary>
public static void readUsers()
{
Object obj = new object();
lock(obj)
{
WebClient wc = new WebClient();
//wc.DownloadFile("http://api.everlive.com/v1/appid/Users/", PATH + @"Users.txt");
string str = System.IO.File.ReadAllText(@"E:\telerikFile\Users.txt");
JObject sum = (JObject)JsonConvert.DeserializeObject(str);
count = int.Parse(sum["Count"].ToString());
WriteLog("一共有" + count + "用户");
Console.WriteLine("一共有" + count + "用户");
JArray result = JArray.Parse(sum["Result"].ToString());
for (var i = 0; i < result.Count; i++)
{
JObject j = JObject.Parse(result[i].ToString());
WriteLog("第" + (i + 1) + "个用户");
WriteLog(j["Email"].ToString());
WriteLog(j["Id"].ToString());
WriteLog(j["Owner"].ToString());
Console.WriteLine("第" + (i + 1) + "个用户");
Console.WriteLine(j["Email"].ToString());
Console.WriteLine(j["Id"].ToString());
Console.WriteLine(j["Owner"].ToString());
// 用id命名文件夹
string pathO = PATH + j["Id"].ToString();
// 用邮箱命名文件夹
string pathN = PATH + j["Email"].ToString();
Task.Run(() => rename(pathO, pathN));
}
}
}
/// <summary>
/// 如果同一个用户存在两个文件夹,则合并为一个,没有做比较就之间删除文件 处理不恰当
/// </summary>
/// <param name="pathO">原文件夹</param>
/// <param name="pathN">新文件夹</param>
public static void rename(string pathO, string pathN)
{
try
{
if (Directory.Exists(pathN))
{
Directory.Delete(pathN, true);
}
Directory.Move(pathO, pathN);
}
catch
{
//Console.WriteLine("重命名失败");
}
}
/// <summary>
/// 写入文件,做记录测试
/// </summary>
/// <param name="str"></param>
private static void WriteLog(string str)
{
Task.Run(() =>
{
try
{
string filePath = PATH + "downloadLog.txt";
StreamWriter sw = null;
if (!File.Exists(filePath))
{
sw = File.CreateText(filePath);
}
else
{
sw = File.AppendText(filePath);
}
sw.Write(str + Environment.NewLine);//+ DateTime.Now.ToString()
sw.Close();
}
catch (Exception ex)
{
ex.ToString();
}
});
}
}
`</pre>
<div>
<pre>` class Items
{
/// <summary>
/// 数据的创建人
/// </summary>
public string CreatedBy { get; set; }
/// <summary>
/// 数据的URI
/// </summary>
public string Uri { get; set; }
/// <summary>
/// 文件名字
/// </summary>
public string Filename { get; set; }
}
</div>
</div>
存在的问题
- 文件夹合并、文件的取舍,应该对比MD5值
- 公共变量未加锁Lock