一個簡單的圖片監聽和上傳程序

在製造業的某些工藝中,可能會對產品進行拍照,這時須要監聽圖片文件並上傳到服務器進行保存。一開始,想將圖片的二進制數據轉換成string類型,而後經過webservice上傳,可是報錯「HTTP 狀態 400 失敗: Bad Request」。畢竟,webservice使用的是HTTP協議,若是想傳文件的話,有FTP協議幹嗎不用。而後在網上找了個C#使用FTP的幫助類(有點改動):html

static public class FtpHelper
    {
        //基本設置
        static private string path = @"ftp://" + ConfigurationManager.AppSettings["ServerIp"] + "/"; //目標路徑
        static private string ftpip = ConfigurationManager.AppSettings["ServerIp"]; //ftp IP地址
        static private string username = ConfigurationManager.AppSettings["Username"];//ftp用戶名
        static private string password = ConfigurationManager.AppSettings["Password"];//ftp密碼

        //獲取ftp上面的文件和文件夾
        public static string[] GetFileList(string dir)
        {
            string[] downloadFiles;
            StringBuilder result = new StringBuilder();
            FtpWebRequest request;
            try
            {
                request = (FtpWebRequest)FtpWebRequest.Create(new Uri(path));
                request.UseBinary = true;
                request.Credentials = new NetworkCredential(username, password);//設置用戶名和密碼
                request.Method = WebRequestMethods.Ftp.ListDirectory;
                request.UseBinary = true;

                WebResponse response = request.GetResponse();
                StreamReader reader = new StreamReader(response.GetResponseStream());

                string line = reader.ReadLine();
                while (line != null)
                {
                    result.Append(line);
                    result.Append("\n");
                    Console.WriteLine(line);
                    line = reader.ReadLine();
                }
                // to remove the trailing '\n'
                result.Remove(result.ToString().LastIndexOf('\n'), 1);
                reader.Close();
                response.Close();
                return result.ToString().Split('\n');
            }
            catch (Exception ex)
            {
                Console.WriteLine("獲取ftp上面的文件和文件夾:" + ex.Message);
                downloadFiles = null;
                return downloadFiles;
            }
        }

        /// <summary>
        /// 獲取文件大小
        /// </summary>
        /// <param name="file">ip服務器下的相對路徑</param>
        /// <returns>文件大小</returns>
        public static int GetFileSize(string file)
        {
            StringBuilder result = new StringBuilder();
            FtpWebRequest request;
            try
            {
                request = (FtpWebRequest)FtpWebRequest.Create(new Uri(path + file));
                request.UseBinary = true;
                request.Credentials = new NetworkCredential(username, password);//設置用戶名和密碼
                request.Method = WebRequestMethods.Ftp.GetFileSize;

                int dataLength = (int)request.GetResponse().ContentLength;

                return dataLength;
            }
            catch (Exception ex)
            {
                Console.WriteLine("獲取文件大小出錯:" + ex.Message);
                return -1;
            }
        }

        /// <summary>
        /// 文件上傳
        /// </summary>
        /// <param name="filePath">原路徑(絕對路徑)包括文件名</param>
        /// <param name="fileName">上傳的文件名</param>
        /// <param name="objPath">目標文件夾:服務器下的相對路徑 不填爲根目錄</param>
        public static void FileUpLoad(string filePath, string fileName, string objPath = "")
        {
            string url = path;
            if (objPath != "")
                url += objPath + "/";
            try
            {

                FtpWebRequest reqFTP = null;
                //待上傳的文件 (全路徑)
                try
                {
                    FileInfo fileInfo = new FileInfo(filePath);
                    using (FileStream fs = fileInfo.OpenRead())
                    {
                        long length = fs.Length;
                        reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(url + fileName));

                        //設置鏈接到FTP的賬號密碼
                        reqFTP.Credentials = new NetworkCredential(username, password);
                        //設置請求完成後是否保持鏈接
                        reqFTP.KeepAlive = false;
                        //指定執行命令
                        reqFTP.Method = WebRequestMethods.Ftp.UploadFile;
                        //指定數據傳輸類型
                        reqFTP.UseBinary = true;

                        using (Stream stream = reqFTP.GetRequestStream())
                        {
                            //設置緩衝大小
                            int BufferLength = 5120;
                            byte[] b = new byte[BufferLength];
                            int i;
                            while ((i = fs.Read(b, 0, BufferLength)) > 0)
                            {
                                stream.Write(b, 0, i);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                }
            }
            catch (Exception ex)
            {
            }
        }

        /// <summary>
        /// 刪除文件
        /// </summary>
        /// <param name="fileName">服務器下的相對路徑 包括文件名</param>
        public static void DeleteFileName(string fileName)
        {
            try
            {
                FileInfo fileInf = new FileInfo(ftpip + "" + fileName);
                string uri = path + fileName;
                FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
                // 指定數據傳輸類型
                reqFTP.UseBinary = true;
                // ftp用戶名和密碼
                reqFTP.Credentials = new NetworkCredential(username, password);
                // 默認爲true,鏈接不會被關閉
                // 在一個命令以後被執行
                reqFTP.KeepAlive = false;
                // 指定執行什麼命令
                reqFTP.Method = WebRequestMethods.Ftp.DeleteFile;
                FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
                response.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine("刪除文件出錯:" + ex.Message);
            }
        }

        /// <summary>
        /// 新建目錄 上一級必須先存在
        /// </summary>
        /// <param name="dirName">服務器下的相對路徑</param>
        public static void MakeDir(string dirName)
        {
            try
            {
                string uri = path + dirName;
                FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
                // 指定數據傳輸類型
                reqFTP.UseBinary = true;
                // ftp用戶名和密碼
                reqFTP.Credentials = new NetworkCredential(username, password);
                reqFTP.Method = WebRequestMethods.Ftp.MakeDirectory;
                FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
                response.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine("建立目錄出錯:" + ex.Message);
            }
        }

        /// <summary>
        /// 刪除目錄 上一級必須先存在
        /// </summary>
        /// <param name="dirName">服務器下的相對路徑</param>
        public static void DelDir(string dirName)
        {
            try
            {
                string uri = path + dirName;
                FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
                // ftp用戶名和密碼
                reqFTP.Credentials = new NetworkCredential(username, password);
                reqFTP.Method = WebRequestMethods.Ftp.RemoveDirectory;
                FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
                response.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine("刪除目錄出錯:" + ex.Message);
            }
        }

        /// <summary>
        /// 從ftp服務器上得到文件夾列表
        /// </summary>
        /// <param name="RequedstPath">服務器下的相對路徑</param>
        /// <returns></returns>
        public static List<string> GetDirctory(string RequedstPath)
        {
            List<string> strs = new List<string>();
            try
            {
                string uri = path + RequedstPath;   //目標路徑 path爲服務器地址
                FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
                // ftp用戶名和密碼
                reqFTP.Credentials = new NetworkCredential(username, password);
                reqFTP.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
                WebResponse response = reqFTP.GetResponse();
                StreamReader reader = new StreamReader(response.GetResponseStream());//中文文件名

                string line = reader.ReadLine();
                while (line != null)
                {
                    if (line.Contains("<DIR>"))
                    {
                        string msg = line.Substring(line.LastIndexOf("<DIR>") + 5).Trim();
                        strs.Add(msg);
                    }
                    line = reader.ReadLine();
                }
                reader.Close();
                response.Close();
                return strs;
            }
            catch (Exception ex)
            {
                Console.WriteLine("獲取目錄出錯:" + ex.Message);
            }
            return strs;
        }

        /// <summary>
        /// 從ftp服務器上得到文件列表
        /// </summary>
        /// <param name="RequedstPath">服務器下的相對路徑</param>
        /// <returns></returns>
        public static List<string> GetFile(string RequedstPath)
        {
            List<string> strs = new List<string>();
            try
            {
                string uri = path + RequedstPath;   //目標路徑 path爲服務器地址
                FtpWebRequest reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
                // ftp用戶名和密碼
                reqFTP.Credentials = new NetworkCredential(username, password);
                reqFTP.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
                WebResponse response = reqFTP.GetResponse();
                StreamReader reader = new StreamReader(response.GetResponseStream());//中文文件名

                string line = reader.ReadLine();
                while (line != null)
                {
                    if (!line.Contains("<DIR>"))
                    {
                        string msg = line.Substring(39).Trim();
                        strs.Add(msg);
                    }
                    line = reader.ReadLine();
                }
                reader.Close();
                response.Close();
                return strs;
            }
            catch (Exception ex)
            {
                Console.WriteLine("獲取文件出錯:" + ex.Message);
            }
            return strs;
        }

    }
View Code

下面建立一個WindowsForm項目:MyWatcherweb

添加一個配置文件:數據庫

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings>
    <add name="conn" connectionString="Data Source=;Initial Catalog=;User ID=;Password=;" providerName="System.Data.SqlClient"/>
  </connectionStrings>
  <appSettings>
    <add key="WatchPath" value="E:\"/>
    <add key="WatchType" value="*.jpg"/>

    <add key="Line" value="Default"/>
    <add key="Station" value="Default"/>
    <add key="Employee" value="Default"/>
    
    <add key="ServerIp" value=""/>
    <add key="Username" value=""/>
    <add key="Password" value=""/>
  </appSettings>
</configuration>

使用FileSystemWatcher進行文件監聽和處理時要注意,OnCreate事件是文件剛建立的時候就觸發,此時文件還未完成寫操做,文件也不是一個完整的文件。因此,在下面的代碼中,將文件的監聽和上傳分開去作,並經過一個字典做爲中間的媒介。服務器

注意:在一個監聽的目錄下面,文件名相同的,默認視爲相同的文件,即便它們的子目錄不一樣,在字典中的鍵是同樣的。app

下面是監聽程序的代碼框架:框架

using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Threading;
using System.Windows.Forms;

namespace MyWatch
{
    public partial class MyForm : Form
    {
        public MyForm()
        {
            InitializeComponent();
        }

        //建立一個字典,記錄最新建立的圖片
        private Dictionary<string, string> _fileList = new Dictionary<string, string>();
        //監聽目錄
        private string _watchPath = ConfigurationManager.AppSettings["WatchPath"];
        //監聽類型
        private string _watchType = ConfigurationManager.AppSettings["WatchType"];
        //監聽線程
        private Thread thread;

        private void MyForm_Load(object sender, EventArgs e)
        {
            FileSystemWatcher myWather = new FileSystemWatcher(_watchPath, _watchType);
            myWather.IncludeSubdirectories = true;
            myWather.Created += new FileSystemEventHandler(OnCreated);//建立
            myWather.Changed += new FileSystemEventHandler(OnChanged);//更改
            myWather.EnableRaisingEvents = true;

            thread = new Thread(SaveFile);
            thread.Start();
        }

        //監聽事件
        private void OnCreated(object source, FileSystemEventArgs e)
        {
            WatchProcess(e);
        }
        private void OnChanged(object source, FileSystemEventArgs e)
        {
            WatchProcess(e);
        }

        //監聽處理:在文件建立或更改時,將<圖片名稱,圖片地址>保存到字典中
        private void WatchProcess(FileSystemEventArgs e)
        {

        }

        //上傳圖片
        private void SaveFile() 
        {
            while (true)
            {
               
            }
        }
    }
}

下面的是監聽到文件建立時的處理:ide

//監聽處理:在文件建立或更改時,將<圖片名稱,圖片地址>保存到字典中
private void WatchProcess(FileSystemEventArgs e)
{
    string[] pathArr = e.FullPath.Split('\\');
    if (pathArr.Length > 1)
    {
          //文件更改時產生的系統文件會以$開頭
          string fileName = pathArr[pathArr.Length - 1].ToUpper().Trim();
          if (fileName.ToCharArray()[0] == '$')
             return;
          //進行數據更新
          lock (_fileList)
          {
             _fileList[fileName] = e.FullPath;
          }
      }
}

使用線程上傳圖片:ui

//上傳圖片
private void SaveFile()
{
    while (true)
    {
        //獲取當前保存在字典中的文件數量,而後給個等待時間,讓文件建立結束
        int count = _fileList.Count;
        Thread.Sleep(10 * 1000);

        //保存上傳過的EL圖片文件名,用於從字典中刪除上傳過的圖片
        List<string> stringKeys = new List<string>();

        //參數
        string strDate = DateTime.Now.ToString("yyyyMMdd");
        string strLine = ConfigurationManager.AppSettings["Line"];
        string strStation = ConfigurationManager.AppSettings["Station"];
        string strEmployee = ConfigurationManager.AppSettings["Employee"];

        //使用緩衝過的數據量進行操做
        for (int i = 0; i < count; i++)
        {
            //文件被刪除就不處理
            if (!File.Exists(_fileList.ElementAt(i).Value))
                continue;

            string[] fi = _fileList.ElementAt(i).Key.Split('.');
            if (fi.Length != 2)
                continue;

            //隱藏文件不處理
            FileInfo fileInfo = new FileInfo(_fileList.ElementAt(i).Value);
            if ((fileInfo.Attributes & FileAttributes.Hidden) != FileAttributes.Hidden)
            {
                try
                {
                    //獲取服務器目錄:日期
                    List<string> pathDate = FtpHelper.GetDirctory("");
                    if (!pathDate.Contains(strDate))
                        FtpHelper.MakeDir(strDate);
                    //獲取服務器目錄:線別
                    List<string> pathLine = FtpHelper.GetDirctory("/" + strDate);
                    if (!pathLine.Contains(strLine))
                        FtpHelper.MakeDir(strDate + "/" + strLine);
                    //獲取服務目錄:工位
                    List<string> pathStation = FtpHelper.GetDirctory("/" + strDate + "/" + strLine);
                    if (!pathStation.Contains(strStation))
                        FtpHelper.MakeDir(strDate + "/" + strLine + "/" + strStation);

                    //若是文件名存在,則建立一個帶時間後綴的文件
                    string objPath = strDate + "/" + strLine + "/" + strStation;
                    string fName = _fileList.ElementAt(i).Key;
                    if (FtpHelper.GetFileSize(objPath + "/" + fName) > -1)
                        fName = fi[0] + "_" + DateTime.Now.ToString("HHmmss") + "." + fi[1];

                    //上傳
                    FtpHelper.FileUpLoad(_fileList.ElementAt(i).Value, fName, objPath);

                    //數據庫操做
                    //此處省略
                }
                catch { }
            }

            //保存這個鍵,用於從Dictionary中刪除上傳過的EL,不能在for循環中進行刪除,會致使長度不一致
            stringKeys.Add(_fileList.ElementAt(i).Key);
        }

        //從Dictionary中移除添
        lock (_fileList)
        {
            foreach (var i in stringKeys)
            {
                _fileList.Remove(i);
            }
        }
    }
}

源碼下載url

參考:spa

http://wenku.baidu.com/link?url=oM5DGnopZkeLxGopJZP7EypkO-X-sTeoXTxX9lCkMqiAoXzrJPaSrxKDd5Qz12hM5tbuixHOi-QgK6GaQYvS_PkR8Y7YUVJWSB6sGShXEie

http://www.cnblogs.com/rond/archive/2012/07/30/2611295.html

http://www.cnblogs.com/zhaojingjing/archive/2011/01/21/1941586.html

 

附:ftp添加有問題,會致使530錯誤

相關文章
相關標籤/搜索