191 lines
6.6 KiB
C#
191 lines
6.6 KiB
C#
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
|
|||
|
using System.Text;
|
|||
|
using System.Threading;
|
|||
|
using System.IO;
|
|||
|
using Thousandto.Update.Log;
|
|||
|
using Thousandto.Update.Flow;
|
|||
|
|
|||
|
namespace Thousandto.Update.Data
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// 解压下载的二进制基础资源文件
|
|||
|
/// </summary>
|
|||
|
public class UnzipResource
|
|||
|
{
|
|||
|
string _TAG = "UnzipResource.cs ";
|
|||
|
|
|||
|
string _resPath;
|
|||
|
|
|||
|
object _lockObj = new object();
|
|||
|
|
|||
|
public string ResPath
|
|||
|
{
|
|||
|
get { return _resPath; }
|
|||
|
set { _resPath = value; }
|
|||
|
}
|
|||
|
string _outPath;
|
|||
|
|
|||
|
public string OutPath
|
|||
|
{
|
|||
|
get { return _outPath; }
|
|||
|
set { _outPath = value; }
|
|||
|
}
|
|||
|
|
|||
|
public UnzipResource(string resFile, string unzipPath)
|
|||
|
{
|
|||
|
_resPath = resFile;
|
|||
|
_outPath = unzipPath;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 释放资源
|
|||
|
/// 文件结构 4x32 文件头 |32位记录路径长度|32位记录文件名|32位记录md5长度|32位记录文件大小|
|
|||
|
/// 然后根据这4个结构获取具体的路径、文件名、md5值、文件内容
|
|||
|
/// </summary>
|
|||
|
/// <returns></returns>
|
|||
|
public int UnzipRes()
|
|||
|
{
|
|||
|
UpdateLog.INFO_LOG(_TAG + "unzipRes()");
|
|||
|
|
|||
|
int ret = CodeDefine.RET_SUCCESS;
|
|||
|
FileStream resFileStream = null;
|
|||
|
long filePostion = 0;
|
|||
|
long fileSize = 0;
|
|||
|
try
|
|||
|
{
|
|||
|
resFileStream = new FileStream(_resPath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
|||
|
fileSize = resFileStream.Length;
|
|||
|
|
|||
|
List<ResourceFileData> fileDataList = new List<ResourceFileData>();
|
|||
|
|
|||
|
//启动线程池
|
|||
|
// var threadPool = new HttpThreadPool<UnzipData>(4, ThreadFunc);
|
|||
|
while (fileSize > 0 && filePostion < fileSize)
|
|||
|
{
|
|||
|
ResourceFileData fileData = new ResourceFileData();
|
|||
|
|
|||
|
//4x32长度的头
|
|||
|
fileData.DirLen = int.Parse(read(resFileStream, 32, filePostion, out filePostion));
|
|||
|
fileData.NameLen = int.Parse(read(resFileStream, 32, filePostion, out filePostion));
|
|||
|
fileData.Md5Len = int.Parse(read(resFileStream, 32, filePostion, out filePostion));
|
|||
|
fileData.FileSize = long.Parse(read(resFileStream, 32, filePostion, out filePostion));
|
|||
|
|
|||
|
//读取内容
|
|||
|
fileData.Dir = read(resFileStream, fileData.DirLen, filePostion, out filePostion);
|
|||
|
fileData.Name = read(resFileStream, fileData.NameLen, filePostion, out filePostion);
|
|||
|
fileData.Md5 = read(resFileStream, fileData.Md5Len, filePostion, out filePostion);
|
|||
|
|
|||
|
//跳过localversion的释放
|
|||
|
if (fileData.Name.ToLower().Equals("localversion.xml"))
|
|||
|
{
|
|||
|
resFileStream.Seek(fileData.FileSize, SeekOrigin.Current);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
|
|||
|
writeFile(resFileStream, fileData.FileSize, fileData.Dir, fileData.Name);
|
|||
|
|
|||
|
//resFileStream.Seek(fileData.FileSize, SeekOrigin.Current);
|
|||
|
//UnzipData ud = new UnzipData(fileData, filePostion, fileSize);
|
|||
|
//threadPool.addTask(ud);
|
|||
|
}
|
|||
|
filePostion += fileData.FileSize;
|
|||
|
}
|
|||
|
|
|||
|
//等待所有文件下载完
|
|||
|
//threadPool.waitWhileWorking();
|
|||
|
}
|
|||
|
catch (System.Exception ex)
|
|||
|
{
|
|||
|
ret = CodeDefine.RET_FAIL_UNZIP_RES_FILE;
|
|||
|
UpdateLog.ERROR_LOG(_TAG + ex.Message + "\n" + ex.StackTrace);
|
|||
|
UpdateLog.EXCEPTION_LOG(ex);
|
|||
|
}
|
|||
|
finally
|
|||
|
{
|
|||
|
if (resFileStream != null)
|
|||
|
{
|
|||
|
resFileStream.Close();
|
|||
|
}
|
|||
|
}
|
|||
|
return ret;
|
|||
|
}
|
|||
|
|
|||
|
long _unzipSizeCounter = 0;
|
|||
|
private void ThreadFunc(UnzipBaseResData data)
|
|||
|
{
|
|||
|
var resFileStream = new FileStream(_resPath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
|||
|
resFileStream.Seek(data.StartPos, SeekOrigin.Begin);
|
|||
|
writeFile(resFileStream, data.FileData.FileSize, data.FileData.Dir, data.FileData.Name);
|
|||
|
resFileStream.Close();
|
|||
|
lock (_lockObj)
|
|||
|
{
|
|||
|
_unzipSizeCounter += data.FileData.FileSize;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void writeFile(FileStream resFileStream, long fileLen, string dir, string name)
|
|||
|
{
|
|||
|
DirectoryInfo dirInfo = new DirectoryInfo(_outPath + "/" + dir);
|
|||
|
if (!dirInfo.Exists)
|
|||
|
{
|
|||
|
dirInfo.Create();
|
|||
|
}
|
|||
|
string filePath = _outPath + "/" + dir + name;
|
|||
|
FileStream writeStream = new FileStream(filePath, FileMode.Create);
|
|||
|
|
|||
|
byte[] buffer = null;
|
|||
|
long bufferSize = 1024;
|
|||
|
if (fileLen < bufferSize)
|
|||
|
{
|
|||
|
bufferSize = fileLen;
|
|||
|
}
|
|||
|
|
|||
|
buffer = new byte[bufferSize];
|
|||
|
do
|
|||
|
{
|
|||
|
resFileStream.Read(buffer, 0, (int)bufferSize);
|
|||
|
writeStream.Write(buffer, 0, (int)bufferSize);
|
|||
|
|
|||
|
fileLen -= bufferSize;
|
|||
|
if (fileLen < 1024)
|
|||
|
{
|
|||
|
bufferSize = fileLen;
|
|||
|
}
|
|||
|
} while (fileLen > 0);
|
|||
|
|
|||
|
writeStream.Close();
|
|||
|
}
|
|||
|
|
|||
|
private string read(FileStream resFileStream, int readLen, long position, out long filePosition)
|
|||
|
{
|
|||
|
Byte[] beginBuf = new Byte[readLen];
|
|||
|
resFileStream.Read(beginBuf, 0, readLen);
|
|||
|
filePosition = position + readLen;
|
|||
|
string retStr = System.Text.Encoding.Default.GetString(beginBuf);
|
|||
|
return retStr;
|
|||
|
}
|
|||
|
|
|||
|
//内嵌数据结构
|
|||
|
private class UnzipBaseResData
|
|||
|
{
|
|||
|
public ResourceFileData FileData { get; set; }
|
|||
|
//指向stream中的起始位置
|
|||
|
public long StartPos { get; set; }
|
|||
|
////源文件,base资源
|
|||
|
//public string SourcePath { get; set; }
|
|||
|
////源文件总大小
|
|||
|
public long SourceSize { get; set; }
|
|||
|
|
|||
|
public UnzipBaseResData(ResourceFileData fileData, long pos, long sourceSize)
|
|||
|
{
|
|||
|
FileData = fileData;
|
|||
|
StartPos = pos;
|
|||
|
// SourcePath = path;
|
|||
|
SourceSize = sourceSize;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|