using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using com.hnshituo.core.webapp.vo;
using Common;
using CoreFS.CA06;
namespace MeterPlugInLibrary
{
public class ImageCurlControl
{
Thread task;
public ImageCurlControl()
{
Init();
}
private void Init()
{
}
///
/// 启动TFP上传线程
///
public void Start()
{
if (task == null)
{
task = new Thread(new ThreadStart(Doworks));
task.Start();
}
}
public void Stop()
{
if (task != null)
{
task.Abort();
task = null;
}
}
private void Doworks()
{
do
{
int waitSecs = 1000;
int i = 0;
try
{
//为了避免给图片编号与这边压缩同时操作一个图片,所以需等车辆下去后进行该操作
if (PbCache.collect?.weight < 500 && !string.IsNullOrEmpty(PbCache.oldTempImgId) && !string.IsNullOrEmpty(PbCache.oldActualFirstNo))
{
string sPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "imgShort\\";
string picPath = Path.Combine(sPath, "formalImg");
ArrayList UnZipedFiles = GetFiles(picPath, ".jpg");//tmp!
i = 3;
ZipFiles(UnZipedFiles); //2021年3月2日不再进行图片压缩,直接存到正式文件夹formalImg中
i = 4;
//获取正式目录文件进行上传
ArrayList files = GetFiles(sPath + "formalImg", ".jpg");
i = 5;
UploadFiles(files);
}
}
catch (Exception exp)
{
WriteLog("ImageControl.Doworks在" + i + "位置异常,异常信息:" + exp.Message);
}
finally
{
Thread.Sleep(waitSecs);
}
} while (true);
}
private void ZipFiles(ArrayList UnzipedFiles)
{
//ImageZip iz = new ImageZip();
string oldTempImgId = PbCache.oldTempImgId, oldActualFirstNo = PbCache.oldActualFirstNo;
if (UnzipedFiles == null || UnzipedFiles.Count == 0) return;
foreach (string fn in UnzipedFiles)
{
if (string.IsNullOrEmpty(fn)) continue;
if (!File.Exists(fn)) continue;
//如果带tempImg则说明没有压缩过,需要压缩
int i = fn.Length;
if (fn.Contains("tempImg"))
{
//临时目录图片压缩后存储与正式目录
string jpgFile = fn.Replace("_tempImg", "").Replace(oldTempImgId, oldActualFirstNo);
Image img = ImageZip.BytesToBitmap(ImageZip.ZipImageByte(fn));
if (fn.Contains("_2.jpg")) //fn.Contains("_1.jpg") ||
{
ImageZip.CompressionImage(img, jpgFile, AppConfigCache.imgMass > 100 ? 100 : AppConfigCache.imgMass);
}
else
{
ImageZip.CompressionImage(img, jpgFile, AppConfigCache.imgMass2 > 100 ? 100 : AppConfigCache.imgMass2);
}
File.Delete(fn);//删除临时目录数据
}
else if (!fn.Contains(oldTempImgId) && !fn.Contains(oldActualFirstNo))
{
string[] lastName = fn.Split('\\');
if (lastName[lastName.Length-1].Length > 34)
{
string path = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "imgShort\\bakImg";
if (!Directory.Exists(path))//如果不存在就创建file文件夹
{
Directory.CreateDirectory(path);
}
//要是正常,则以后这里直接File.Delete(fn);
File.Move(fn, fn.Replace("formalImg", "bakImg"));
}
}
}
}
public ArrayList GetFiles(string _dirPath, string extensionName)
{
ArrayList files = new ArrayList();
if (!Directory.Exists(_dirPath)) return null;
DirectoryInfo theFolder = new DirectoryInfo(_dirPath);
FileInfo[] fileinfos = theFolder.GetFiles("*" + extensionName);
if (fileinfos != null && fileinfos.Count() > 0)
{
foreach (FileInfo fi in fileinfos)
{
files.Add(fi.FullName);
}
}
DirectoryInfo[] dirInfos = theFolder.GetDirectories();
if (dirInfos != null && dirInfos.Count() > 0)
{
foreach (DirectoryInfo di in dirInfos)
{
files.AddRange(GetFiles(di.FullName, extensionName));
}
}
return files;
}
// 后台刷FTP线程调用
private void UploadFiles(ArrayList files)
{
string localpath = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, @"imgShort\formalImg\"));
string lastpath = AppConfigCache.ftpPath;
foreach (string _filepath in files)
{
try
{
// 临时文件不上传
if (!_filepath.Contains("_temp"))
{
string ftpdir = Path.Combine(AppConfigCache.ftpPath, DateTime.Now.ToString("yyyy-MM-dd"));
//验证文件名是否合法
string filename = Path.GetFileName(_filepath);
//filename : 计量作业编号_序号.jpg 计量作业编号:计量点编号+年月日时分秒
MeterWorkImage ci = ParseFileName(filename, ftpdir.Replace("upload", "download"));
if (ci == null) continue;
// 上传文件
UploadRequest(ftpdir, localpath + filename);
//存储计量数据的时候,实际上是先将计量数据及图片路径
MeterWorkImageService service = new MeterWorkImageService();
RESTfulResult rm = service.doSaveWf(ci); //db.doOption("MeterWorkImageService", "doSaveWf", new object[] { ci }, 1);
if (rm.Succeed)
{
WriteLog(string.Format("更新图片记录[{0}]:{1}", ci.actualFirstNo, filename));
File.Delete(_filepath);
}
else
{
WriteLog(string.Format("上传图片失败! [{0}]\n{1}", ci.actualFirstNo, filename));
}
//
}
}
catch (Exception exp)
{
WriteLog(string.Format("上传图片失败! [{0}]\n{1}", _filepath, exp.Message));
}
}
}
private void RemoveRedundantDir(string _path, int deep)
{
DirectoryInfo theFolder = new DirectoryInfo(_path);
DirectoryInfo[] dirInfos = theFolder.GetDirectories();
if (dirInfos != null && dirInfos.Count() > 0)
{
foreach (DirectoryInfo di in dirInfos)
{
RemoveRedundantDir(di.FullName, deep + 1);
}
}
try
{
if (deep == 0) return;
FileInfo[] fileinfos = theFolder.GetFiles();
if (fileinfos == null || fileinfos.Count() == 0)
{
DateTime dt;
if (DateTime.TryParseExact(theFolder.Name, "yyyy-MM-dd", CultureInfo.CurrentCulture, DateTimeStyles.AllowWhiteSpaces, out dt))
{
if (TimeSpan.FromTicks(DateTime.Today.Ticks).Subtract(TimeSpan.FromTicks(dt.Date.Ticks)).TotalDays > 1)
{
Directory.Delete(_path);
}
}
}
}
catch { }
}
///
/// 验证图片名称
///
/// 计量点编号_作业编号_序号.jpg
///
///
private MeterWorkImage ParseFileName(string filename, string ftpdir)
{
MeterWorkImage ci = new MeterWorkImage();
filename = Path.GetFileName(filename);
string[] segs = filename.Split(new char[] { '_' }, StringSplitOptions.RemoveEmptyEntries);
if (segs == null || segs.Count() < 3)
{
WriteLog("文件名不符合要求! (3段命名):" + filename);
return null;
}
int seq;
//int icar_seq = 0;
//int.TryParse(car_seq, out icar_seq);
string[] seqs = segs[2].Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
if (seqs == null || seqs.Count() == 0 || !int.TryParse(seqs[0], out seq))
{
WriteLog("文件名不符合要求! (序号不正确):" + filename);
return null;
}
string fullfilename = ftpdir + "/" + filename;
if (fullfilename.Substring(0, 8) == "https://")
{
fullfilename = fullfilename.Substring(0, 8) + fullfilename.Substring(8).Replace("//", "/").Replace("//", "/");
}
else if (fullfilename.Substring(0, 7) == "http://")
{
fullfilename = fullfilename.Substring(0, 7) + fullfilename.Substring(7).Replace("//", "/").Replace("//", "/");
}
else
{
fullfilename = fullfilename.Replace("//", "/").Replace("//", "/");
}
PropertyInfo pi = null;
try
{
pi = ci.GetType().GetProperty(string.Format("imageFile{0}", seq));
pi.SetValue(ci, fullfilename.Replace("/pub", ""));
}
catch
{
WriteLog("文件名不符合要求! (序号超出数据库要求):" + fullfilename);
return null;
}
//ci.image_time = DateTime.ParseExact(segs[0].Substring(segs[0].Length - 14, 14), "yyyyMMddHHmmss", CultureInfo.CurrentCulture);
ci.actualFirstNo = segs[1];
return ci;
}
private static void WriteLog(string str)
{
// 20220925 By BourneCao 暂时屏蔽语音播放日志
return;
try
{
string m_szRunPath;
m_szRunPath = System.Environment.CurrentDirectory;
if (System.IO.Directory.Exists(m_szRunPath + "\\log") == false)
{
System.IO.Directory.CreateDirectory(m_szRunPath + "\\log");
}
string strDate = System.DateTime.Now.ToString("yyyyMMdd");
string strPathFile = m_szRunPath + "\\log\\" + strDate;
if (!Directory.Exists(strPathFile))//如果不存在就创建file文件夹
{
Directory.CreateDirectory(strPathFile);
}
System.IO.TextWriter tw = new System.IO.StreamWriter(strPathFile + "\\FTP_image_" + strDate + ".log", true);
tw.WriteLine(System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
tw.WriteLine(str);
tw.WriteLine("\r\n");
tw.Close();
}
catch { }
}
private void UploadRequest(string url, string filePath)
{
// 时间戳,用做boundary
string timeStamp = DateTime.Now.Ticks.ToString("x");
//根据uri创建HttpWebRequest对象
HttpWebRequest oWebrequest = (HttpWebRequest)WebRequest.Create(new Uri(url));
//如果是发送HTTPS请求
if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
{
ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3
| SecurityProtocolType.Tls
| (SecurityProtocolType)0x300 //Tls11
| (SecurityProtocolType)0xC00; //Tls12
oWebrequest = WebRequest.Create(url) as HttpWebRequest;
oWebrequest.ProtocolVersion = HttpVersion.Version11;
}
else
{
oWebrequest = WebRequest.Create(url) as HttpWebRequest;
}
//HttpWebRequest httpReq = (HttpWebRequest)WebRequest.Create(new Uri(url));
oWebrequest.Method = "POST";
oWebrequest.AllowWriteStreamBuffering = false; //对发送的数据不使用缓存
oWebrequest.Timeout = 300000; //设置获得响应的超时时间(300秒)
oWebrequest.ContentType = "multipart/form-data; boundary=" + timeStamp;
//文件
FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
BinaryReader binaryReader = new BinaryReader(fileStream);
//头信息
string boundary = "--" + timeStamp;
string dataFormat = boundary + "\r\nContent-Disposition: form-data; name=\"{0}\";filename=\"{1}\"\r\nContent-Type:application/octet-stream\r\n\r\n";
string header = string.Format(dataFormat, "file", Path.GetFileName(filePath));
byte[] postHeaderBytes = Encoding.UTF8.GetBytes(header);
//结束边界
byte[] boundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + timeStamp + "--\r\n");
long length = fileStream.Length + postHeaderBytes.Length + boundaryBytes.Length;
oWebrequest.ContentLength = length;//请求内容长度
try
{
//每次上传4k
int bufferLength = 4096;
byte[] buffer = new byte[bufferLength];
//已上传的字节数
long offset = 0;
int size = binaryReader.Read(buffer, 0, bufferLength);
Stream postStream = oWebrequest.GetRequestStream();
//发送请求头部消息
postStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
while (size > 0)
{
postStream.Write(buffer, 0, size);
offset += size;
size = binaryReader.Read(buffer, 0, bufferLength);
}
//添加尾部边界
postStream.Write(boundaryBytes, 0, boundaryBytes.Length);
postStream.Close();
//获取服务器端的响应
using (HttpWebResponse response = (HttpWebResponse)oWebrequest.GetResponse())
{
Stream receiveStream = response.GetResponseStream();
StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8);
string returnValue = readStream.ReadToEnd();
response.Close();
readStream.Close();
}
}
catch (Exception ex)
{
//Debug.WriteLine("文件传输异常: " + ex.Message);
}
finally
{
fileStream.Close();
binaryReader.Close();
}
}
private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
return true; //总是接受
}
}
}