为了更好的建立自己的MVC Portal我们首先要做些准备,这些准备就是建立自己的一些常用类库,将自己将要使用的技术进行有效的管理和准备。
首先我们要建立一个类工程:VonLibrary,在这里面我们将实现常用数据管理的基类,加密和摘要机制,以及Json转换等基础类。
首先建立一个VonLibrary工程文件:
添加第一个文件,Crypto.cs
using System.IO; using System.Text; using System.Security.Cryptography; namespace VonPortal.Library { public static class Crypto { const string B64Chars = "6XutUOdSRPYpQ5ev1@mhgx7r3DiGk0BnM24a8FLAVlIyjZqf%E9CKzHWcwboGsNT%MmCBNyx1bUP5SZWtI0qrd@sDpoHnu8LT3Re9lkF24EiAvYVfgj7ac6GKzXGQOwhjmCS3bGPI0sXTVFy%8ezk9aAcqnZtDlNKUYwWHiLruMG5xf4@1g2QE7R6opOvdhBfI6X@vP3qikhFgdMmbNOS9Rr%jUsLlDuG7We4ywCEoapYZVHT0xKBc1G5t8AnQ2z"; public static string MD5File(string filename) { FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read); MD5CryptoServiceProvider MD5 = new MD5CryptoServiceProvider(); byte[] md5byte = MD5.ComputeHash(fs); string str = ""; foreach (byte b in md5byte) { str += B64Chars[b]; } fs.Close(); return str; } public static string MD5String(string text) { byte[] byts = Encoding.UTF8.GetBytes(text); MD5CryptoServiceProvider MD5 = new MD5CryptoServiceProvider(); byte[] md5byte = MD5.ComputeHash(byts); string str = ""; foreach (byte b in md5byte) { str += B64Chars[b]; } return str; } } }
GZip.cs
using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Collections; using System.Linq; using System.IO.Compression; namespace VonPortal.Library { public class GZip { /// <summary> /// Compress /// </summary> /// <param name="lpSourceFolder">The location of the files to include in the zip file, all files including files in subfolders will be included.</param> /// <param name="lpDestFolder">Folder to write the zip file into</param> /// <param name="zipFileName">Name of the zip file to write</param> public static GZipResult Compress(string lpSourceFolder, string lpDestFolder, string zipFileName) { return Compress(lpSourceFolder, "*.*", SearchOption.AllDirectories, lpDestFolder, zipFileName, true); } /// <summary> /// Compress /// </summary> /// <param name="lpSourceFolder">The location of the files to include in the zip file</param> /// <param name="searchPattern">Search pattern (ie "*.*" or "*.txt" or "*.gif") to idendify what files in lpSourceFolder to include in the zip file</param> /// <param name="searchOption">Only files in lpSourceFolder or include files in subfolders also</param> /// <param name="lpDestFolder">Folder to write the zip file into</param> /// <param name="zipFileName">Name of the zip file to write</param> /// <param name="deleteTempFile">Boolean, true deleted the intermediate temp file, false leaves the temp file in lpDestFolder (for debugging)</param> public static GZipResult Compress(string lpSourceFolder, string searchPattern, SearchOption searchOption, string lpDestFolder, string zipFileName, bool deleteTempFile) { DirectoryInfo di = new DirectoryInfo(lpSourceFolder); FileInfo[] files = di.GetFiles("*.*", searchOption); return Compress(files, lpSourceFolder, lpDestFolder, zipFileName, deleteTempFile); } /// <summary> /// Compress /// </summary> /// <param name="files">Array of FileInfo objects to be included in the zip file</param> /// <param name="folders">Array of Folder string</param> /// <param name="lpBaseFolder">Base folder to use when creating relative paths for the files /// stored in the zip file. For example, if lpBaseFolder is 'C:\zipTest\Files\', and there is a file /// 'C:\zipTest\Files\folder1\sample.txt' in the 'files' array, the relative path for sample.txt /// will be 'folder1/sample.txt'</param> /// <param name="lpDestFolder">Folder to write the zip file into</param> /// <param name="zipFileName">Name of the zip file to write</param> public static GZipResult Compress(FileInfo[] files, string[] folders, string lpBaseFolder, string lpDestFolder, string zipFileName) { //support compress folder IList<FileInfo> list = new List<FileInfo>(); foreach (FileInfo li in files) list.Add(li); foreach (string str in folders) { DirectoryInfo di = new DirectoryInfo(str); foreach (FileInfo info in di.GetFiles("*.*", SearchOption.AllDirectories)) { list.Add(info); } } return Compress(list.ToArray(), lpBaseFolder, lpDestFolder, zipFileName, true); } /// <summary> /// Compress /// </summary> /// <param name="files">Array of FileInfo objects to be included in the zip file</param> /// <param name="lpBaseFolder">Base folder to use when creating relative paths for the files /// stored in the zip file. For example, if lpBaseFolder is 'C:\zipTest\Files\', and there is a file /// 'C:\zipTest\Files\folder1\sample.txt' in the 'files' array, the relative path for sample.txt /// will be 'folder1/sample.txt'</param> /// <param name="lpDestFolder">Folder to write the zip file into</param> /// <param name="zipFileName">Name of the zip file to write</param> public static GZipResult Compress(FileInfo[] files, string lpBaseFolder, string lpDestFolder, string zipFileName) { return Compress(files, lpBaseFolder, lpDestFolder, zipFileName, true); } /// <summary> /// Compress /// </summary> /// <param name="files">Array of FileInfo objects to be included in the zip file</param> /// <param name="lpBaseFolder">Base folder to use when creating relative paths for the files /// stored in the zip file. For example, if lpBaseFolder is 'C:\zipTest\Files\', and there is a file /// 'C:\zipTest\Files\folder1\sample.txt' in the 'files' array, the relative path for sample.txt /// will be 'folder1/sample.txt'</param> /// <param name="lpDestFolder">Folder to write the zip file into</param> /// <param name="zipFileName">Name of the zip file to write</param> /// <param name="deleteTempFile">Boolean, true deleted the intermediate temp file, false leaves the temp file in lpDestFolder (for debugging)</param> public static GZipResult Compress(FileInfo[] files, string lpBaseFolder, string lpDestFolder, string zipFileName, bool deleteTempFile) { GZipResult result = new GZipResult(); try { if (!lpDestFolder.EndsWith("\\")) { lpDestFolder += "\\"; } string lpTempFile = lpDestFolder + zipFileName + ".tmp"; string lpZipFile = lpDestFolder + zipFileName; result.TempFile = lpTempFile; result.ZipFile = lpZipFile; if (files != null && files.Length > 0) { CreateTempFile(files, lpBaseFolder, lpTempFile, result); if (result.FileCount > 0) { CreateZipFile(lpTempFile, lpZipFile, result); } // delete the temp file if (deleteTempFile) { File.Delete(lpTempFile); result.TempFileDeleted = true; } } } catch //(Exception ex4) { result.Errors = true; } return result; } private static void CreateZipFile(string lpSourceFile, string lpZipFile, GZipResult result) { byte[] buffer; int count = 0; FileStream fsOut = null; FileStream fsIn = null; GZipStream gzip = null; // compress the file into the zip file try { fsOut = new FileStream(lpZipFile, FileMode.Create, FileAccess.Write, FileShare.None); gzip = new GZipStream(fsOut, CompressionMode.Compress, true); fsIn = new FileStream(lpSourceFile, FileMode.Open, FileAccess.Read, FileShare.Read); buffer = new byte[fsIn.Length]; count = fsIn.Read(buffer, 0, buffer.Length); fsIn.Close(); fsIn = null; // compress to the zip file gzip.Write(buffer, 0, buffer.Length); result.ZipFileSize = fsOut.Length; result.CompressionPercent = GetCompressionPercent(result.TempFileSize, result.ZipFileSize); } catch //(Exception ex1) { result.Errors = true; } finally { if (gzip != null) { gzip.Close(); gzip = null; } if (fsOut != null) { fsOut.Close(); fsOut = null; } if (fsIn != null) { fsIn.Close(); fsIn = null; } } } private static void CreateTempFile(FileInfo[] files, string lpBaseFolder, string lpTempFile, GZipResult result) { byte[] buffer; int count = 0; byte[] header; string fileHeader = null; string fileModDate = null; string lpFolder = null; int fileIndex = 0; string lpSourceFile = null; string vpSourceFile = null; GZipFileInfo gzf = null; FileStream fsOut = null; FileStream fsIn = null; if (files != null && files.Length > 0) { try { result.Files = new GZipFileInfo[files.Length]; // open the temp file for writing fsOut = new FileStream(lpTempFile, FileMode.Create, FileAccess.Write, FileShare.None); foreach (FileInfo fi in files) { lpFolder = fi.DirectoryName + "\\"; try { gzf = new GZipFileInfo(); gzf.Index = fileIndex; // read the source file, get its virtual path within the source folder lpSourceFile = fi.FullName; gzf.LocalPath = lpSourceFile; vpSourceFile = lpSourceFile.Replace(lpBaseFolder, string.Empty); vpSourceFile = vpSourceFile.Replace("\\", "/"); gzf.RelativePath = vpSourceFile; fsIn = new FileStream(lpSourceFile, FileMode.Open, FileAccess.Read, FileShare.Read); buffer = new byte[fsIn.Length]; count = fsIn.Read(buffer, 0, buffer.Length); fsIn.Close(); fsIn = null; fileModDate = fi.LastWriteTimeUtc.ToString(); gzf.ModifiedDate = fi.LastWriteTimeUtc; gzf.Length = buffer.Length; fileHeader = fileIndex.ToString() + "," + vpSourceFile + "," + fileModDate + "," + buffer.Length.ToString() + "\n"; header = Encoding.Default.GetBytes(fileHeader); fsOut.Write(header, 0, header.Length); fsOut.Write(buffer, 0, buffer.Length); fsOut.WriteByte(10); // linefeed gzf.AddedToTempFile = true; // update the result object result.Files[fileIndex] = gzf; // increment the fileIndex fileIndex++; } catch //(Exception ex1) { result.Errors = true; } finally { if (fsIn != null) { fsIn.Close(); fsIn = null; } } if (fsOut != null) { result.TempFileSize = fsOut.Length; } } } catch //(Exception ex2) { result.Errors = true; } finally { if (fsOut != null) { fsOut.Close(); fsOut = null; } } } result.FileCount = fileIndex; } public static GZipResult Decompress(string lpSourceFolder, string lpDestFolder, string zipFileName) { return Decompress(lpSourceFolder, lpDestFolder, zipFileName, true, true, null, null, 4096); } public static GZipResult Decompress(string lpSourceFolder, string lpDestFolder, string zipFileName, bool writeFiles, string addExtension) { return Decompress(lpSourceFolder, lpDestFolder, zipFileName, true, writeFiles, addExtension, null, 4096); } public static GZipResult Decompress(string lpSrcFolder, string lpDestFolder, string zipFileName, bool deleteTempFile, bool writeFiles, string addExtension, Hashtable htFiles, int bufferSize) { GZipResult result = new GZipResult(); if (!lpSrcFolder.EndsWith("\\")) { lpSrcFolder += "\\"; } if (!lpDestFolder.EndsWith("\\")) { lpDestFolder += "\\"; } string lpTempFile = lpSrcFolder + zipFileName + ".tmp"; string lpZipFile = lpSrcFolder + zipFileName; result.TempFile = lpTempFile; result.ZipFile = lpZipFile; string line = null; string lpFilePath = null; string lpFolder = null; GZipFileInfo gzf = null; FileStream fsTemp = null; ArrayList gzfs = new ArrayList(); bool write = false; if (string.IsNullOrEmpty(addExtension)) { addExtension = string.Empty; } else if (!addExtension.StartsWith(".")) { addExtension = "." + addExtension; } // extract the files from the temp file try { fsTemp = UnzipToTempFile(lpZipFile, lpTempFile, result); if (fsTemp != null) { while (fsTemp.Position != fsTemp.Length) { line = null; while (string.IsNullOrEmpty(line) && fsTemp.Position != fsTemp.Length) { line = ReadLine(fsTemp); } if (!string.IsNullOrEmpty(line)) { gzf = new GZipFileInfo(); if (gzf.ParseFileInfo(line) && gzf.Length > 0) { gzfs.Add(gzf); lpFilePath = lpDestFolder + gzf.RelativePath; lpFolder = GetFolder(lpFilePath); gzf.LocalPath = lpFilePath; write = false; if (htFiles == null || htFiles.ContainsKey(gzf.RelativePath)) { gzf.RestoreRequested = true; write = writeFiles; } if (write) { // make sure the folder exists if (!Directory.Exists(lpFolder)) { Directory.CreateDirectory(lpFolder); } // read from fsTemp and write out the file gzf.Restored = WriteFile(fsTemp, gzf.Length, lpFilePath + addExtension, bufferSize); } else { // need to advance fsTemp fsTemp.Position += gzf.Length; } } } } } } catch //(Exception ex3) { result.Errors = true; } finally { if (fsTemp != null) { fsTemp.Close(); fsTemp = null; } } // delete the temp file try { if (deleteTempFile) { File.Delete(lpTempFile); result.TempFileDeleted = true; } } catch //(Exception ex4) { result.Errors = true; } result.FileCount = gzfs.Count; result.Files = new GZipFileInfo[gzfs.Count]; gzfs.CopyTo(result.Files); return result; } private static string ReadLine(FileStream fs) { string line = string.Empty; const int bufferSize = 4096; byte[] buffer = new byte[bufferSize]; byte b = 0; byte lf = 10; int i = 0; while (b != lf) { b = (byte)fs.ReadByte(); buffer[i] = b; i++; } line = System.Text.Encoding.Default.GetString(buffer, 0, i - 1); return line; } private static bool WriteFile(FileStream fs, int fileLength, string lpFile, int bufferSize) { bool success = false; FileStream fsFile = null; if (bufferSize == 0 || fileLength < bufferSize) { bufferSize = fileLength; } int count = 0; int remaining = fileLength; int readSize = 0; try { byte[] buffer = new byte[bufferSize]; fsFile = new FileStream(lpFile, FileMode.Create, FileAccess.Write, FileShare.None); while (remaining > 0) { if (remaining > bufferSize) { readSize = bufferSize; } else { readSize = remaining; } count = fs.Read(buffer, 0, readSize); remaining -= count; if (count == 0) { break; } fsFile.Write(buffer, 0, count); fsFile.Flush(); } fsFile.Flush(); fsFile.Close(); fsFile = null; success = true; } catch //(Exception ex2) { success = false; } finally { if (fsFile != null) { fsFile.Flush(); fsFile.Close(); fsFile = null; } } return success; } private static string GetFolder(string lpFilePath) { string lpFolder = lpFilePath; int index = lpFolder.LastIndexOf("\\"); if (index != -1) { lpFolder = lpFolder.Substring(0, index + 1); } return lpFolder; } private static FileStream UnzipToTempFile(string lpZipFile, string lpTempFile, GZipResult result) { FileStream fsIn = null; GZipStream gzip = null; FileStream fsOut = null; FileStream fsTemp = null; const int bufferSize = 4096; byte[] buffer = new byte[bufferSize]; int count = 0; try { fsIn = new FileStream(lpZipFile, FileMode.Open, FileAccess.Read, FileShare.Read); result.ZipFileSize = fsIn.Length; fsOut = new FileStream(lpTempFile, FileMode.Create, FileAccess.Write, FileShare.None); gzip = new GZipStream(fsIn, CompressionMode.Decompress, true); while (true) { count = gzip.Read(buffer, 0, bufferSize); if (count != 0) { fsOut.Write(buffer, 0, count); } if (count != bufferSize) { break; } } } catch //(Exception ex1) { result.Errors = true; } finally { if (gzip != null) { gzip.Close(); gzip = null; } if (fsOut != null) { fsOut.Close(); fsOut = null; } if (fsIn != null) { fsIn.Close(); fsIn = null; } } fsTemp = new FileStream(lpTempFile, FileMode.Open, FileAccess.Read, FileShare.None); if (fsTemp != null) { result.TempFileSize = fsTemp.Length; } return fsTemp; } private static int GetCompressionPercent(long tempLen, long zipLen) { double tmp = (double)tempLen; double zip = (double)zipLen; double hundred = 100; double ratio = (tmp - zip) / tmp; double pcnt = ratio * hundred; return (int)pcnt; } } public class GZipFileInfo { public int Index = 0; public string RelativePath = null; public DateTime ModifiedDate; public int Length = 0; public bool AddedToTempFile = false; public bool RestoreRequested = false; public bool Restored = false; public string LocalPath = null; public string Folder = null; public bool ParseFileInfo(string fileInfo) { bool success = false; try { if (!string.IsNullOrEmpty(fileInfo)) { // get the file information string[] info = fileInfo.Split(','); if (info != null && info.Length == 4) { this.Index = Convert.ToInt32(info[0]); this.RelativePath = info[1].Replace("/", "\\"); this.ModifiedDate = Convert.ToDateTime(info[2]); this.Length = Convert.ToInt32(info[3]); success = true; } } } catch { success = false; } return success; } } public class GZipResult { public GZipFileInfo[] Files = null; public int FileCount = 0; public long TempFileSize = 0; public long ZipFileSize = 0; public int CompressionPercent = 0; public string TempFile = null; public string ZipFile = null; public bool TempFileDeleted = false; public bool Errors = false; } }
Json.cs
using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Reflection; using System.Reflection.Emit; using System.Text; using System.IO; using System.Globalization; namespace fastJSON { public class SafeDictionary<TKey, TValue> { private readonly object _Padlock = new object(); private readonly Dictionary<TKey, TValue> _Dictionary = new Dictionary<TKey, TValue>(); public bool ContainsKey(TKey key) { return _Dictionary.ContainsKey(key); } public TValue this[TKey key] { get { return _Dictionary[key]; } } public void Add(TKey key, TValue value) { lock (_Padlock) { _Dictionary.Add(key, value); } } } internal class Getters { public string Name; public JSON.GenericGetter Getter; } internal class JSONSerializer { private readonly StringBuilder _output = new StringBuilder(); public static string ToJSON(object obj) { return new JSONSerializer().ConvertToJSON(obj); } internal string ConvertToJSON(object obj) { WriteValue(obj); return _output.ToString(); } private void WriteValue(object obj) { if (obj == null) _output.Append("null"); else if (obj is sbyte || obj is byte || obj is short || obj is ushort || obj is int || obj is uint || obj is long || obj is ulong || obj is decimal || obj is double || obj is float) _output.Append(Convert.ToString(obj, NumberFormatInfo.InvariantInfo)); else if (obj is bool) _output.Append(obj.ToString().ToLower()); // conform to standard else if (obj is char || obj is Enum || obj is Guid || obj is string) WriteString(obj.ToString()); else if (obj is DateTime) { _output.Append("\""); _output.Append(((DateTime)obj).ToString("yyyy-MM-dd HH:mm:ss"));// conform to standard _output.Append("\""); } else if (obj is DataSet) WriteDataset((DataSet)obj); else if (obj is byte[]) WriteByteArray((byte[])obj); else if (obj is IDictionary) WriteDictionary((IDictionary)obj); else if (obj is Array || obj is IList || obj is ICollection) WriteArray((IEnumerable)obj); else WriteObject(obj); } private void WriteByteArray(byte[] bytes) { WriteString(Convert.ToBase64String(bytes)); } //private void WriteHashTable(Hashtable hash) //{ // _output.Append("{"); // bool pendingSeparator = false; // foreach (object entry in hash.Keys) // { // if (pendingSeparator) // _output.Append(","); // WriteValue(entry); // _output.Append(":"); // WriteValue(hash[entry]); // pendingSeparator = true; // } // _output.Append("}"); //} private void WriteDataset(DataSet ds) { _output.Append("{"); WritePair("$schema", ds.GetXmlSchema()); _output.Append(","); foreach (DataTable table in ds.Tables) { _output.Append("\""); _output.Append(table.TableName); _output.Append("\":["); foreach (DataRow row in table.Rows) { _output.Append("{"); foreach (DataColumn column in row.Table.Columns) { WritePair(column.ColumnName, row[column]); } _output.Append("}"); } _output.Append("]"); } // end dataset _output.Append("}"); } private void WriteObject(object obj) { _output.Append("{"); Type t = obj.GetType(); WritePair("$type", t.AssemblyQualifiedName); _output.Append(","); List<Getters> g = JSON.Instance.GetGetters(t); foreach (Getters p in g) { WritePair(p.Name, p.Getter(obj)); } _output.Append("}"); } private void WritePair(string name, string value) { WriteString(name); _output.Append(":"); WriteString(value); } private void WritePair(string name, object value) { WriteString(name); _output.Append(":"); WriteValue(value); } private void WriteArray(IEnumerable array) { _output.Append("["); bool pendingSeperator = false; foreach (object obj in array) { if (pendingSeperator) _output.Append(','); WriteValue(obj); pendingSeperator = true; } _output.Append("]"); } private void WriteDictionary(IDictionary dic) { _output.Append("["); bool pendingSeparator = false; foreach (DictionaryEntry entry in dic) { if (pendingSeparator) _output.Append(","); _output.Append("{"); WritePair("k", entry.Key); _output.Append(","); WritePair("v", entry.Value); _output.Append("}"); pendingSeparator = true; } _output.Append("]"); } private void WriteString(string s) { _output.Append('\"'); foreach (char c in s) { switch (c) { case '\t': _output.Append("\\t"); break; case '\r': _output.Append("\\r"); break; case '\n': _output.Append("\\n"); break; case '"': case '\\': _output.Append("\\"); _output.Append(c); break; default: { if (c >= ' ' && c < 128) _output.Append(c); else { _output.Append("\\u"); _output.Append(((int)c).ToString("X4")); } } break; } } _output.Append('\"'); } } /// <summary> /// This class encodes and decodes JSON strings. /// Spec. details, see http://www.json.org/ /// /// JSON uses Arrays and Objects. These correspond here to the datatypes ArrayList and Hashtable. /// All numbers are parsed to doubles. /// </summary> internal class JsonParser { private const int TOKEN_NONE = 0; private const int TOKEN_CURLY_OPEN = 1; private const int TOKEN_CURLY_CLOSE = 2; private const int TOKEN_SQUARED_OPEN = 3; private const int TOKEN_SQUARED_CLOSE = 4; private const int TOKEN_COLON = 5; private const int TOKEN_COMMA = 6; private const int TOKEN_STRING = 7; private const int TOKEN_NUMBER = 8; private const int TOKEN_TRUE = 9; private const int TOKEN_FALSE = 10; private const int TOKEN_NULL = 11; /// <summary> /// Parses the string json into a value /// </summary> /// <param name="json">A JSON string.</param> /// <returns>An ArrayList, a dictionary, a double, a string, null, true, or false</returns> internal static object JsonDecode(string json) { bool success = true; return JsonDecode(json, ref success); } /// <summary> /// Parses the string json into a value; and fills 'success' with the successfullness of the parse. /// </summary> /// <param name="json">A JSON string.</param> /// <param name="success">Successful parse?</param> /// <returns>An ArrayList, a Hashtable, a double, a string, null, true, or false</returns> private static object JsonDecode(string json, ref bool success) { success = true; if (json != null) { char[] charArray = json.ToCharArray(); int index = 0; object value = ParseValue(charArray, ref index, ref success); return value; } else { return null; } } protected static Dictionary<string, object> ParseObject(char[] json, ref int index, ref bool success) { Dictionary<string, object> table = new Dictionary<string, object>(); int token; // { NextToken(json, ref index); bool done = false; while (!done) { token = LookAhead(json, index); if (token == TOKEN_NONE) { success = false; return null; } else if (token == TOKEN_COMMA) { NextToken(json, ref index); } else if (token == TOKEN_CURLY_CLOSE) { NextToken(json, ref index); return table; } else { // name string name = ParseString(json, ref index, ref success); if (!success) { success = false; return null; } // : token = NextToken(json, ref index); if (token != TOKEN_COLON) { success = false; return null; } // value object value = ParseValue(json, ref index, ref success); if (!success) { success = false; return null; } table[name] = value; } } return table; } protected static ArrayList ParseArray(char[] json, ref int index, ref bool success) { ArrayList array = new ArrayList(); NextToken(json, ref index); bool done = false; while (!done) { int token = LookAhead(json, index); if (token == TOKEN_NONE) { success = false; return null; } else if (token == TOKEN_COMMA) { NextToken(json, ref index); } else if (token == TOKEN_SQUARED_CLOSE) { NextToken(json, ref index); break; } else { object value = ParseValue(json, ref index, ref success); if (!success) { return null; } array.Add(value); } } return array; } protected static object ParseValue(char[] json, ref int index, ref bool success) { switch (LookAhead(json, index)) { case TOKEN_NUMBER: return ParseNumber(json, ref index, ref success); case TOKEN_STRING: return ParseString(json, ref index, ref success); case TOKEN_CURLY_OPEN: return ParseObject(json, ref index, ref success); case TOKEN_SQUARED_OPEN: return ParseArray(json, ref index, ref success); case TOKEN_TRUE: NextToken(json, ref index); return true; case TOKEN_FALSE: NextToken(json, ref index); return false; case TOKEN_NULL: NextToken(json, ref index); return null; case TOKEN_NONE: break; } success = false; return null; } protected static string ParseString(char[] json, ref int index, ref bool success) { StringBuilder s = new StringBuilder(); char c; EatWhitespace(json, ref index); // " c = json[index++]; bool complete = false; while (!complete) { if (index == json.Length) { break; } c = json[index++]; if (c == '"') { complete = true; break; } else if (c == '\\') { if (index == json.Length) { break; } c = json[index++]; if (c == '"') { s.Append('"'); } else if (c == '\\') { s.Append('\\'); } else if (c == '/') { s.Append('/'); } else if (c == 'b') { s.Append('\b'); } else if (c == 'f') { s.Append('\f'); } else if (c == 'n') { s.Append('\n'); } else if (c == 'r') { s.Append('\r'); } else if (c == 't') { s.Append('\t'); } else if (c == 'u') { int remainingLength = json.Length - index; if (remainingLength >= 4) { // parse the 32 bit hex into an integer codepoint uint codePoint; if (!(success = UInt32.TryParse(new string(json, index, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out codePoint))) { return ""; } // convert the integer codepoint to a unicode char and add to string s.Append(Char.ConvertFromUtf32((int)codePoint)); // skip 4 chars index += 4; } else { break; } } } else { s.Append(c); } } if (!complete) { success = false; return null; } return s.ToString(); } protected static string ParseNumber(char[] json, ref int index, ref bool success) { EatWhitespace(json, ref index); int lastIndex = GetLastIndexOfNumber(json, index); int charLength = (lastIndex - index) + 1; string number = new string(json, index, charLength); success = true; index = lastIndex + 1; return number; } protected static int GetLastIndexOfNumber(char[] json, int index) { int lastIndex; for (lastIndex = index; lastIndex < json.Length; lastIndex++) { if ("0123456789+-.eE".IndexOf(json[lastIndex]) == -1) { break; } } return lastIndex - 1; } protected static void EatWhitespace(char[] json, ref int index) { for (; index < json.Length; index++) { if (" \t\n\r".IndexOf(json[index]) == -1) { break; } } } protected static int LookAhead(char[] json, int index) { int saveIndex = index; return NextToken(json, ref saveIndex); } protected static int NextToken(char[] json, ref int index) { EatWhitespace(json, ref index); if (index == json.Length) { return TOKEN_NONE; } char c = json[index]; index++; switch (c) { case '{': return TOKEN_CURLY_OPEN; case '}': return TOKEN_CURLY_CLOSE; case '[': return TOKEN_SQUARED_OPEN; case ']': return TOKEN_SQUARED_CLOSE; case ',': return TOKEN_COMMA; case '"': return TOKEN_STRING; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '-': return TOKEN_NUMBER; case ':': return TOKEN_COLON; } index--; int remainingLength = json.Length - index; // false if (remainingLength >= 5) { if (json[index] == 'f' && json[index + 1] == 'a' && json[index + 2] == 'l' && json[index + 3] == 's' && json[index + 4] == 'e') { index += 5; return TOKEN_FALSE; } } // true if (remainingLength >= 4) { if (json[index] == 't' && json[index + 1] == 'r' && json[index + 2] == 'u' && json[index + 3] == 'e') { index += 4; return TOKEN_TRUE; } } // null if (remainingLength >= 4) { if (json[index] == 'n' && json[index + 1] == 'u' && json[index + 2] == 'l' && json[index + 3] == 'l') { index += 4; return TOKEN_NULL; } } return TOKEN_NONE; } protected static bool SerializeValue(object value, StringBuilder builder) { bool success = true; if (value is string) { success = SerializeString((string)value, builder); } else if (value is Hashtable) { success = SerializeObject((Hashtable)value, builder); } else if (value is ArrayList) { success = SerializeArray((ArrayList)value, builder); } else if (IsNumeric(value)) { success = SerializeNumber(Convert.ToDouble(value), builder); } else if ((value is Boolean) && ((Boolean)value == true)) { builder.Append("true"); } else if ((value is Boolean) && ((Boolean)value == false)) { builder.Append("false"); } else if (value == null) { builder.Append("null"); } else { success = false; } return success; } protected static bool SerializeObject(Hashtable anObject, StringBuilder builder) { builder.Append("{"); IDictionaryEnumerator e = anObject.GetEnumerator(); bool first = true; while (e.MoveNext()) { string key = e.Key.ToString(); object value = e.Value; if (!first) { builder.Append(", "); } SerializeString(key, builder); builder.Append(":"); if (!SerializeValue(value, builder)) { return false; } first = false; } builder.Append("}"); return true; } protected static bool SerializeArray(ArrayList anArray, StringBuilder builder) { builder.Append("["); bool first = true; for (int i = 0; i < anArray.Count; i++) { object value = anArray[i]; if (!first) { builder.Append(", "); } if (!SerializeValue(value, builder)) { return false; } first = false; } builder.Append("]"); return true; } protected static bool SerializeString(string aString, StringBuilder builder) { builder.Append("\""); char[] charArray = aString.ToCharArray(); for (int i = 0; i < charArray.Length; i++) { char c = charArray[i]; if (c == '"') { builder.Append("\\\""); } else if (c == '\\') { builder.Append("\\\\"); } else if (c == '\b') { builder.Append("\\b"); } else if (c == '\f') { builder.Append("\\f"); } else if (c == '\n') { builder.Append("\\n"); } else if (c == '\r') { builder.Append("\\r"); } else if (c == '\t') { builder.Append("\\t"); } else { int codepoint = Convert.ToInt32(c); if ((codepoint >= 32) && (codepoint <= 126)) { builder.Append(c); } else { builder.Append("\\u" + Convert.ToString(codepoint, 16).PadLeft(4, '0')); } } } builder.Append("\""); return true; } protected static bool SerializeNumber(double number, StringBuilder builder) { builder.Append(Convert.ToString(number, CultureInfo.InvariantCulture)); return true; } protected static bool IsNumeric(object o) { double result; return (o == null) ? false : Double.TryParse(o.ToString(), out result); } } public class JSON { public readonly static JSON Instance = new JSON(); private JSON() { } public string ToJSON(object obj) { return new JSONSerializer().ConvertToJSON(obj); } public object ToObject(string json) { Dictionary<string, object> ht = (Dictionary<string, object>)JsonParser.JsonDecode(json); if (ht == null) return null; return ParseDictionary(ht); } #region [ PROPERTY GET SET CACHE ] SafeDictionary<string, Type> _typecache = new SafeDictionary<string, Type>(); private Type GetTypeFromCache(string typename) { if (_typecache.ContainsKey(typename)) return _typecache[typename]; else { Type t = Type.GetType(typename); _typecache.Add(typename, t); return t; } } SafeDictionary<string, PropertyInfo> _propertycache = new SafeDictionary<string, PropertyInfo>(); private PropertyInfo getproperty(Type type, string propertyname) { if (propertyname == "$type") return null; StringBuilder sb = new StringBuilder(); sb.Append(type.Name); sb.Append("|"); sb.Append(propertyname); string n = sb.ToString(); if (_propertycache.ContainsKey(n)) { return _propertycache[n]; } else { PropertyInfo[] pr = type.GetProperties(); foreach (PropertyInfo p in pr) { StringBuilder sbb = new StringBuilder(); sbb.Append(type.Name); sbb.Append("|"); sbb.Append(p.Name); string nn = sbb.ToString(); if (_propertycache.ContainsKey(nn) == false) _propertycache.Add(nn, p); } return _propertycache[n]; } } private delegate void GenericSetter(object target, object value); private static GenericSetter CreateSetMethod(PropertyInfo propertyInfo) { MethodInfo setMethod = propertyInfo.GetSetMethod(); if (setMethod == null) return null; Type[] arguments = new Type[2]; arguments[0] = arguments[1] = typeof(object); DynamicMethod setter = new DynamicMethod( String.Concat("_Set", propertyInfo.Name, "_"), typeof(void), arguments, propertyInfo.DeclaringType); ILGenerator il = setter.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Castclass, propertyInfo.DeclaringType); il.Emit(OpCodes.Ldarg_1); if (propertyInfo.PropertyType.IsClass) il.Emit(OpCodes.Castclass, propertyInfo.PropertyType); else il.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType); il.EmitCall(OpCodes.Callvirt, setMethod, null); il.Emit(OpCodes.Ret); return (GenericSetter)setter.CreateDelegate(typeof(GenericSetter)); } public delegate object GenericGetter(object target); private static GenericGetter CreateGetMethod(PropertyInfo propertyInfo) { MethodInfo getMethod = propertyInfo.GetGetMethod(); if (getMethod == null) return null; Type[] arguments = new Type[1]; arguments[0] = typeof(object); DynamicMethod getter = new DynamicMethod( String.Concat("_Get", propertyInfo.Name, "_"), typeof(object), arguments, propertyInfo.DeclaringType); ILGenerator il = getter.GetILGenerator(); il.DeclareLocal(typeof(object)); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Castclass, propertyInfo.DeclaringType); il.EmitCall(OpCodes.Callvirt, getMethod, null); if (!propertyInfo.PropertyType.IsClass) il.Emit(OpCodes.Box, propertyInfo.PropertyType); il.Emit(OpCodes.Ret); return (GenericGetter)getter.CreateDelegate(typeof(GenericGetter)); } SafeDictionary<Type, List<Getters>> _getterscache = new SafeDictionary<Type, List<Getters>>(); internal List<Getters> GetGetters(Type type) { if (_getterscache.ContainsKey(type)) return _getterscache[type]; else { PropertyInfo[] props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance); List<Getters> getters = new List<Getters>(); foreach (PropertyInfo p in props) { GenericGetter g = CreateGetMethod(p); if (g != null) { Getters gg = new Getters(); gg.Name = p.Name; gg.Getter = g; getters.Add(gg); } } _getterscache.Add(type, getters); return getters; } } SafeDictionary<PropertyInfo, GenericSetter> _settercache = new SafeDictionary<PropertyInfo, GenericSetter>(); private GenericSetter GetSetter(PropertyInfo prop) { if (_settercache.ContainsKey(prop)) return _settercache[prop]; else { GenericSetter s = CreateSetMethod(prop); _settercache.Add(prop, s); return s; } } #endregion private object ParseDictionary(Dictionary<string, object> d) { string tn = "" + d["$type"]; Type type = GetTypeFromCache(tn); object o = Activator.CreateInstance(type); foreach (string name in d.Keys) { PropertyInfo pi = getproperty(type, name); if (pi != null) { object v = d[name]; if (v != null) { object oset = null; GenericSetter setter; Type pt = pi.PropertyType; object dic = pt.GetInterface("IDictionary"); if (pt.IsGenericType && pt.IsValueType == false && dic == null) { IList col = (IList)Activator.CreateInstance(pt); // create an array of objects foreach (object ob in (ArrayList)v) col.Add(ParseDictionary((Dictionary<string, object>)ob)); oset = col; } else if (pt == typeof(byte[])) { oset = Convert.FromBase64String((string)v); } else if (pt.IsArray && pt.IsValueType == false) { ArrayList col = new ArrayList(); // create an array of objects foreach (object ob in (ArrayList)v) col.Add(ParseDictionary((Dictionary<string, object>)ob)); oset = col.ToArray(pi.PropertyType.GetElementType()); } else if (pt == typeof(Guid) || pt == typeof(Guid?)) oset = new Guid("" + v); else if (pt == typeof(DataSet)) oset = CreateDataset((Dictionary<string, object>)v); else if (pt == typeof(Hashtable)) oset = CreateDictionary((ArrayList)v, pt); else if (dic != null) oset = CreateDictionary((ArrayList)v, pt); else oset = ChangeType(v, pt); setter = GetSetter(pi); setter(o, oset); } } } return o; } private object CreateDictionary(ArrayList reader, Type pt) { IDictionary col = (IDictionary)Activator.CreateInstance(pt); Type[] types = col.GetType().GetGenericArguments(); foreach (object o in reader) { Dictionary<string, object> values = (Dictionary<string, object>)o; object key; object val; if (values["k"] is Dictionary<string, object>) key = ParseDictionary((Dictionary<string, object>)values["k"]); else key = ChangeType(values["k"], types[0]); if (values["v"] is Dictionary<string, object>) val = ParseDictionary((Dictionary<string, object>)values["v"]); else val = ChangeType(values["v"], types[1]); col.Add(key, val); } return col; } public object ChangeType(object value, Type conversionType) { if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>))) { System.ComponentModel.NullableConverter nullableConverter = new System.ComponentModel.NullableConverter(conversionType); conversionType = nullableConverter.UnderlyingType; } return Convert.ChangeType(value, conversionType); } private Hashtable CreateHashtable(ArrayList reader) { Hashtable ht = new Hashtable(); foreach (object o in reader) { Dictionary<string, object> values = (Dictionary<string, object>)o; ht.Add( ParseDictionary((Dictionary<string, object>)values["k"]), ParseDictionary((Dictionary<string, object>)values["v"]) ); } return ht; } private DataSet CreateDataset(Dictionary<string, object> reader) { DataSet ds = new DataSet(); // read dataset schema here string s = "" + reader["$schema"]; TextReader tr = new StringReader(s); ds.ReadXmlSchema(tr); foreach (string key in reader.Keys) { if (key == "$type" || key == "$schema") continue; object tb = reader[key]; if (tb != null && tb.GetType() == typeof(ArrayList)) { ArrayList rows = (ArrayList)tb; foreach (Dictionary<string, object> row in rows) { DataRow dr = ds.Tables[key].NewRow(); foreach (string col in row.Keys) { dr[col] = row[col]; } ds.Tables[key].Rows.Add(dr); } } } return ds; } } }
VonFunctions.cs
///////////////////////////////////////////////////////////////////////////// // Copyright (c) 2008 by Jamesvon, Inc. // All Rights Reserved. // // 文件名: VonFunctions.cs // 创建人: James von // 创建日期: 2012-4-1 8:00:00 // 文件功能描述: 通用函数及结构 // // 慎重声明: // // 本软件包含版权资料、商业秘密以及其他财产资料。用户不可,也不能试图对本软件 // 进行修改、反向工程改造、拆解或反编译,也不能抽取或盗取本软件的组成部分用于 // 生成派生产品或其它产品。 // James von 的名字和代表其软件产品的标记、图案等,不能以任何理由、任何方式 // 用于推广基于本软件之上开发的其它产品。 // James von 保留本软件的所有权利、资格、利益以及此处所涉及到的所有知识产权。 // James von 的所有软件和产品的组成部分均受版权法和国际版权公约保护。除了单 // 用户许可证规定的权限以外,用户不能以任何理由任何方式复制或使用James von的 // 程序、代码、组件、图像、影像剪辑、声音样本以及文本。除了明确的书面授权外, // James von保留所有的权利。 // //修订历史记录: // // ///////////////////////////////////////////////////////////////////////////// // VonKeyValueItem 键值对,{key}={value},{string}={string} //--------------------------------------------------------------------------- // 键值对的基本类型,以两个字符串类作为基础信息,存储配对信息。 //=========================================================================== // VonObjectItem 键值单元,{key}={value}+{data},{string}={string}+{object} //--------------------------------------------------------------------------- // 以键值对的基本类型,增加对象存储单元,作为扩展信息使用。 //=========================================================================== // VonLinkerItem 链接单元,作为链结构的基础但愿存在。 //--------------------------------------------------------------------------- // 具有本级内容,和前后单元连接。 //=========================================================================== // VonLinkerCollection 链表结构 //--------------------------------------------------------------------------- // 可以处理链结构的信息处理,支持前后追溯,支持头尾直查。 //=========================================================================== // VonKeyValueCollection 键值对集合(Key=Value),支持文本输出和输入 //--------------------------------------------------------------------------- // 默认文本输出格式为:{key}#3{value}$5...{key}#3{value}$5 //=========================================================================== // VonStringCollection 字符键值集合(含应用对象),支持文本输出和输入 //--------------------------------------------------------------------------- // 可以通过 Delimiter 和 Termination 来定义输出间隔符号。 //=========================================================================== // VonConfigCollection 类型配置信息管理类 //--------------------------------------------------------------------------- // 采用hashtable进行存储,支持段落和 //=========================================================================== // EVonParamDelimiterScheme 参数设置间隔符方案 //--------------------------------------------------------------------------- // 支持几种间隔方式存储: // EVPDS_Custom:用户手动定义的间隔符 // EVPDS_Comma:{section}:{key}={value},...\r // EVPDS_Semicolon:{section}:{key}={value};...\r // EVPDS_Bracket:{section}={key}({value})...\r // EVPDS_Special:{section}#3{key}#4{value}#5...#7 //=========================================================================== // VonParamItem 参数集合支持 //--------------------------------------------------------------------------- // name=key1(value1)key2(value2)..., // 同样也支持name=key1=value1,key2=value2,..., // 或者name#3key1#3value1#3key2#3value2#3...#4 //=========================================================================== // VonParamCollection 含键值的参数集合 //--------------------------------------------------------------------------- // 可以通过 TextScheme(EVonParamDelimiterScheme)来定义存储和输出的文本格式 //=========================================================================== // VonFuns 常用函数集合 //--------------------------------------------------------------------------- // ConvertStrToUrl(string) 将URL信息转换为可传递的参数类型 // ConvertUrlToStr(string) 将参数信息转换为可传递的URL类型 // CurrencyToGB(double) 将金额转换为中文大写 // FindStr(string,string) 查找一个字符串,排除中间的引号内容。 // GetCheckItem(System.Web.UI.WebControls.CheckBoxList) 根据 CheckBoxList 生成字符串(以逗号做间隔符)类型的选择结果 // GetCheckValue(System.Web.UI.WebControls.CheckBoxList) CheckBoxList 选择结果,以二进制方式进行存储 // GetRandomColor() 得到一个序列颜色字符串值 // isNumberic(string) 判断是否为数字字符串 // NumToGB(double) 将数值转换为中文大写 // SetCheckItem(System.Web.UI.WebControls.CheckBoxList,string) 根据字符串(以逗号做间隔符),设置 CheckBoxList 选择结果 // SetCheckValue(System.Web.UI.WebControls.CheckBoxList,int) 根据值,按照二进制位设置 CheckBoxList 选择结果 // SplitString(string,string,string,string) 将字符串转换为数组 // SplitString(string,string,int,int) 将字符串转换为数组(截取时包含起始和截取位置) //=========================================================================== using System; using System.Collections.Specialized; using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Collections; using System.Text; using System.Web.UI.WebControls; using System.ComponentModel; using System.Reflection; namespace VonPortal.Library { /// <summary> /// 备注特性 /// </summary> public class RemarkAttribute : Attribute { /// <summary> /// 备注 /// </summary> public string Remark { get; set; } public RemarkAttribute(string remark) { this.Remark = remark; } } /// <summary> /// 键值对,{key}={value}+{data},{object}={object}+object /// </summary> public class VonObjectItem { /// <summary> /// 主键值 /// </summary> public object Key { get; set; } /// <summary> /// 值 /// </summary> public object Value { get; set; } /// <summary> /// 对象 /// </summary> public object Data { get; set; } /// <summary> /// 构造函数 /// </summary> public VonObjectItem() { } /// <summary> /// 带赋值的构造函数 /// </summary> /// <param name="key">主键</param> /// <param name="value">值</param> public VonObjectItem(object key, object value, object data) { this.Key = key; this.Value = value; this.Data = data; } } /// <summary> /// 键值对,{key}={value},{string}={string} /// </summary> public class VonKeyValueItem { /// <summary> /// 主键值 /// </summary> public string Key { get { return _Key; } set { _Key = value; } } private string _Key; /// <summary> /// 值 /// </summary> public string Value { get { return _Value; } set { _Value = value; } } private string _Value; /// <summary> /// 构造函数 /// </summary> public VonKeyValueItem() { } /// <summary> /// 带赋值的构造函数 /// </summary> /// <param name="key">主键</param> /// <param name="value">值</param> public VonKeyValueItem(string key, string value) { this.Key = key; this.Value = value; } } /// <summary> /// 键值单元,{key}={value}+{data},{string}={string}+{object} /// </summary> public class VonDataItem : VonKeyValueItem { /// <summary> /// 值 /// </summary> public object Data { get { return _Data; } set { _Data = value; } } private object _Data; /// <summary> /// 无参的构造函数 /// </summary> public VonDataItem() { this.Key = ""; this.Value = ""; this.Data = null; } /// <summary> /// 带赋值的构造函数 /// </summary> /// <param name="key">主键</param> /// <param name="value">值</param> /// <param name="data">对象</param> public VonDataItem(string key, string value, object data) { this.Key = key; this.Value = value; this.Data = data; } } /// <summary> /// 链接单元,{key}={value}+{data}+{Prevous}+{Next},{string}={string}+{object}+{linker}+{linker} /// </summary> public class VonLinkerItem { /// <summary> /// 值 /// </summary> public VonDataItem Data { get { return _Data; } set { _Data = value; } } private VonDataItem _Data = null; /// <summary> /// 前一个值 /// </summary> public VonLinkerItem Prevous { get { return _Prevous; } set { _Prevous = value; } } private VonLinkerItem _Prevous = null; /// <summary> /// 后一个值 /// </summary> public VonLinkerItem Next { get { return _Next; } set { _Next = value; } } private VonLinkerItem _Next = null; } /// <summary> /// 链表结构 /// </summary> public class VonLinkerCollection { private VonLinkerItem currentItem = new VonLinkerItem(); private VonLinkerItem first = null; private VonLinkerItem laster = null; #region Location and moving functions /// <summary> /// 回到头 /// </summary> public VonLinkerItem First() { currentItem = first; return currentItem; } /// <summary> /// 移到最后一个节点上 /// </summary> public VonLinkerItem Laster() { currentItem = laster; return currentItem; } /// <summary> /// 向后移动一个节点 /// </summary> /// <returns></returns> public bool Next() { if (!EOF) { currentItem = currentItem.Next; return true; } return false; } /// <summary> /// 向前移动一个节点 /// </summary> /// <returns></returns> public bool Prevous() { if (!BOF) { currentItem = currentItem.Prevous; return true; } return false; } /// <summary> /// 将当前节点向后移动一个节点 /// </summary> public void MoveToNext() { if (currentItem.Data == null) return; if (currentItem.Next == null) return; VonDataItem data = currentItem.Data; currentItem.Data = currentItem.Next.Data; currentItem.Next.Data = data; } /// <summary> /// 将当前节点向前移动一个节点 /// </summary> public void MoveToPrevous() { if (currentItem.Data == null) return; if (currentItem.Prevous == null) return; VonDataItem data = currentItem.Data; currentItem.Data = currentItem.Prevous.Data; currentItem.Prevous.Data = data; } /// <summary> /// 将当前节点移动到头 /// </summary> public void MoveToFirst() { if (currentItem.Data == null) return; while (currentItem.Prevous != null) { VonDataItem data = currentItem.Data; currentItem.Data = currentItem.Prevous.Data; currentItem.Prevous.Data = data; currentItem = currentItem.Prevous; } } /// <summary> /// 将当前节点移动到尾 /// </summary> public void MoveToLaster() { if (currentItem.Data == null) return; while (currentItem.Next != null) { VonDataItem data = currentItem.Data; currentItem.Data = currentItem.Next.Data; currentItem.Next.Data = data; currentItem = currentItem.Next; } } /// <summary> /// 根据键名进行定位 /// </summary> /// <param name="Key">键名</param> /// <param name="fromFirst">是否从头开始</param> /// <returns>定位是否成功</returns> public bool LocateByKey(string Key, bool fromFirst) { if (currentItem.Data == null) return false; if (fromFirst) currentItem = first; do { if (Key.Equals(currentItem.Data.Key, StringComparison.OrdinalIgnoreCase)) return true; } while (Next()); return false; } /// <summary> /// 根据键名进行定位 /// </summary> /// <param name="Key">键名</param> /// <returns>定位是否成功</returns> public bool LocateByKey(string Key) { return LocateByKey(Key, true); } /// <summary> /// 根据键值进行定位 /// </summary> /// <param name="Value">键值</param> /// <param name="fromFirst">是否从头开始</param> /// <returns>定位是否成功</returns> public bool LocateByValue(string Value, bool fromFirst) { if (currentItem.Data == null) return false; if (fromFirst) currentItem = first; do { if (Value.Equals(currentItem.Data.Value, StringComparison.OrdinalIgnoreCase)) return true; } while (Next()); return false; } /// <summary> /// 根据键值从头开始进行定位 /// </summary> /// <param name="Value">键值</param> /// <param name="fromFirst">是否</param> /// <returns>定位是否成功</returns> public bool LocateByValue(string Value) { return LocateByValue(Value, true); } /// <summary> /// 根据对象进行定位 /// </summary> /// <param name="Data">对象</param> /// <param name="fromFirst">是否从头开始</param> /// <returns>定位是否成功</returns> public bool LocateByData(object Data, bool fromFirst) { if (currentItem.Data == null) return false; if (fromFirst) currentItem = first; do { if (Data.Equals(currentItem.Data.Data)) return true; } while (Next()); return false; } /// <summary> /// 根据对象从头开始进行定位 /// </summary> /// <param name="Data">对象</param> /// <param name="fromFirst">是否</param> /// <returns>定位是否成功</returns> public bool LocateByData(object Data) { return LocateByData(Data, true); } #endregion #region Properties /// <summary> /// 数据数量 /// </summary> public int Count { get { return _Count; } } private int _Count = 0; /// <summary> /// 是否处于链表头 /// </summary> public bool BOF { get { if (currentItem.Prevous == null) return true; return false; } } /// <summary> /// 是否处于结尾位置 /// </summary> public bool EOF { get { if (currentItem.Next == null) return true; return false; } } /// <summary> /// 得到当前节点 /// </summary> public VonLinkerItem Current { get { return currentItem; } } /// <summary> /// 得到当前节点的键值 /// </summary> public string CurrentKey { get { if (currentItem.Data == null) return ""; return currentItem.Data.Key; } } /// <summary> /// 得到当前节点的值 /// </summary> public string CurrentValue { get { if (currentItem.Data == null) return ""; return currentItem.Data.Value; } } /// <summary> /// 得到当前节点的对象 /// </summary> public object CurrentData { get { if (currentItem.Data == null) return ""; return currentItem.Data.Data; } } #endregion #region Addition or deletion functions /// <summary> /// 在当前节点后追加一个链接 /// </summary> /// <param name="Key">键名</param> /// <param name="Value">键值</param> /// <param name="Data">对象</param> public void Append(string Key, string Value, object Data) { VonDataItem item = new VonDataItem(Key, Value, Data); if (currentItem.Data == null) { currentItem.Data = item; first = currentItem; laster = currentItem; } else { currentItem = new VonLinkerItem(); currentItem.Data = item; currentItem.Prevous = laster; laster.Next = currentItem; laster = currentItem; } _Count++; } /// <summary> /// 在结束位置追加一个链接 /// </summary> /// <param name="Key">键名</param> /// <param name="Value">键值</param> /// <param name="Data">对象</param> public void AddNext(string Key, string Value, object Data) { VonDataItem item = new VonDataItem(Key, Value, Data); if (currentItem.Data == null) { currentItem.Data = item; first = currentItem; laster = currentItem; } else { VonLinkerItem linker = new VonLinkerItem(); linker.Data = item; linker.Prevous = currentItem; linker.Next = currentItem.Next; if (laster == currentItem) laster = linker; if (currentItem.Next != null) currentItem.Next.Prevous = linker; currentItem.Next = linker; currentItem = linker; } _Count++; } /// <summary> /// 在起始位置插入一个链接 /// </summary> /// <param name="Key">键名</param> /// <param name="Value">键值</param> /// <param name="Data">对象</param> public void AddFirst(string Key, string Value, object Data) { VonDataItem item = new VonDataItem(Key, Value, Data); if (currentItem.Data == null) { currentItem.Data = item; first = currentItem; laster = currentItem; } else { currentItem = new VonLinkerItem(); currentItem.Data = item; currentItem.Next = first; first.Prevous = currentItem; first = currentItem; } _Count++; } /// <summary> /// 在当前节点位置插入一个链接 /// </summary> /// <param name="Key">键名</param> /// <param name="Value">键值</param> /// <param name="Data">对象</param> public void Insert(string Key, string Value, object Data) { VonDataItem item = new VonDataItem(Key, Value, Data); if (currentItem.Data == null) { currentItem.Data = item; first = currentItem; laster = currentItem; } else { VonLinkerItem linker = new VonLinkerItem(); linker.Data = item; linker.Prevous = currentItem.Prevous; linker.Next = currentItem; if (first == currentItem) first = linker; if (currentItem.Prevous != null) currentItem.Prevous.Next = linker; currentItem.Prevous = linker; currentItem = linker; } _Count++; } /// <summary> /// 删除当前节点 /// </summary> public void Delete() { if (currentItem.Data == null) return; VonLinkerItem item = currentItem; if (currentItem == first) first = item.Next; if (currentItem == laster) laster = item.Prevous; if (item.Next != null) { if (item.Prevous != null) item.Prevous.Next = item.Next; item.Next.Prevous = item.Prevous; currentItem = item.Next; } else if (item.Prevous != null) { currentItem = item.Prevous; currentItem.Next = null; } item.Data = null; item.Prevous = null; item.Next = null; _Count--; } #endregion } /// <summary> /// 对象键值集合{key}={value}+{data},{object}={object}+object /// </summary> public class VonObjectCollection : IListSource, IEnumerable { private List<VonObjectItem> datas = new List<VonObjectItem>(); /// <summary> /// 数量 /// </summary> public int Count { get { return datas.Count; } } /// <summary> /// 根据索引得到设定值 /// </summary> /// <param name="Index">索引</param> /// <returns>返回值</returns> public VonObjectItem this[int Index] { get { return datas[Index]; } set { datas[Index] = value; } } /// <summary> /// 根据索引得到设定值 /// </summary> /// <param name="Index">索引</param> /// <returns>返回值</returns> public VonObjectItem this[object Key] { get { int idx = IndexOf(Key); if (idx < 0) return null; else return this[idx]; } set { int idx = IndexOf(Key); if (idx < 0) Add(Key, value.Value, value.Data); else { this[idx].Value = value.Value; this[idx].Data = value.Data; } } } /// <summary> /// 根据索引得到节点键值 /// </summary> /// <param name="Index">索引</param> /// <returns>键值</returns> public object GetKey(int Index) { return datas[Index].Key; } /// <summary> /// 根据键值得到索引 /// </summary> /// <param name="KeyValue">键值</param> /// <returns>索引</returns> public int IndexOf(object Key) { for (int i = 0; i < Count; i++) { if (datas[i].Key == Key) return i; } return -1; } /// <summary> /// 添加一个键值的节点 /// </summary> /// <param name="Key">主键</param> /// <param name="Value">值</param> /// <returns>索引</returns> public int Add(object Key, object Value, object Data) { if (_UniqueKey) { int idx = IndexOf(Key); if (idx >= 0) { datas[idx].Value = Value; datas[idx].Data = Data; return idx; } } datas.Add(new VonObjectItem(Key, Value, Data)); return Count - 1; } /// <summary> /// 添加一个键值的节点 /// </summary> /// <param name="Key">主键</param> /// <param name="Value">值</param> /// <returns>索引</returns> public void Insert(int Index, object Key, object Value, object Data) { if (_UniqueKey) { int idx = IndexOf(Key); if (idx >= 0) { datas[idx].Value = Value; datas[idx].Data = Data; return; } } VonObjectItem item = new VonObjectItem(Key, Value, Data); for (int i = Index; i < Count; i++) { VonObjectItem orgItem = datas[i]; datas[i] = item; item = orgItem; } datas.Add(item); } /// <summary> /// 删除值 /// </summary> /// <param name="Index"></param> public void Delete(int Index) { datas.RemoveAt(Index); } /// <summary> /// 根据主键删除一个节点 /// </summary> /// <param name="Key"></param> public void Delete(string Key) { datas.RemoveAt(IndexOf(Key)); } /// <summary> /// 清除所有数据 /// </summary> public void Clear() { datas = new List<VonObjectItem>(); } /// <summary> /// 移动一个节点 /// </summary> /// <param name="Org">原始位置</param> /// <param name="Dest">目标位置</param> public void Move(int Org, int Dest) { int step = Org > Dest ? -1 : 1; VonObjectItem item = datas[Org]; while (Org != Dest) { datas[Org] = datas[Org + step]; Org += step; } datas[Dest] = item; } /// <summary> /// 主键是否采用唯一机制,默认是唯一,不允许重复 /// </summary> public bool UniqueKey { get { return _UniqueKey; } set { _UniqueKey = value; } } private bool _UniqueKey = true; public bool ContainsListCollection { get { return false; } } public IList GetList() { return datas; } public IEnumerator GetEnumerator() { return new EVonObjectCollection(datas); } } /// <summary> /// 为 VonObjectCollection 支持foreach循环建立的 IEnumerator 接口类 /// </summary> internal class EVonObjectCollection : IEnumerator { public List<VonObjectItem> datas; public EVonObjectCollection(List<VonObjectItem> collection) { this.datas = collection; } int position = -1; public bool MoveNext() { position++; return position < datas.Count; } public void Reset() { position = -1; } public object Current { get { try { return datas[position]; } catch (IndexOutOfRangeException ex) { throw new InvalidOperationException(); } } } } /// <summary> /// 对象键值集合(Key=Value),默认文本输出格式为:{key}#3{value}$5 /// </summary> public class VonKeyValueCollection : IListSource, IEnumerable { private List<VonKeyValueItem> datas = new List<VonKeyValueItem>(); /// <summary> /// 数量 /// </summary> public int Count { get { return datas.Count; } } /// <summary> /// 键值间隔符 /// </summary> public char Delimiter { set { _Delimiter = value; } get { return _Delimiter; } } private char _Delimiter = (char)3; /// <summary> /// 行终止符 /// </summary> public char Termination { get { return _Termination; } set { _Termination = value; } } private char _Termination = (char)5; /// <summary> /// 设置或获取记录内容文本化,默认间隔符是{key}#3{value}#5... /// </summary> public string Text { get { StringBuilder sb = new StringBuilder(); foreach (VonKeyValueItem item in datas) { sb.Append(item.Key + _Delimiter + item.Value + _Termination); } return sb.ToString(); } set { Clear(); string[] lst = value.Split(_Termination); foreach (string s in lst) { int pos = s.IndexOf(_Delimiter); if (pos < 0) continue; else Add(s.Substring(0, pos), s.Substring(pos + 1)); } } } /// <summary> /// 根据索引得到设定值 /// </summary> /// <param name="Index">索引</param> /// <returns>返回值</returns> public VonKeyValueItem this[int Index] { get { return datas[Index]; } set { datas[Index] = value; } } /// <summary> /// 根据索引得到设定值 /// </summary> /// <param name="Index">索引</param> /// <returns>返回值</returns> public string this[string Key] { get { int idx = IndexOf(Key); if (idx < 0) return null; else return this[idx].Value; } set { int idx = IndexOf(Key); if (idx < 0) Add(Key, value); else this[idx].Value = value; } } /// <summary> /// 根据索引得到节点键值 /// </summary> /// <param name="Index">索引</param> /// <returns>键值</returns> public string GetKey(int Index) { return datas[Index].Key; } /// <summary> /// 根据键值得到索引 /// </summary> /// <param name="KeyValue">键值</param> /// <returns>索引</returns> public int IndexOf(string Key) { for (int i = 0; i < Count; i++) { if (datas[i].Key.Equals(Key, StringComparison.OrdinalIgnoreCase)) return i; } return -1; } /// <summary> /// 添加一个键值的节点 /// </summary> /// <param name="Key">主键</param> /// <param name="Value">值</param> /// <returns>索引</returns> public int Add(string Key, string Value) { if (_UniqueKey) { int idx = IndexOf(Key); if (idx >= 0) { datas[idx].Value = Value; return idx; } } datas.Add(new VonKeyValueItem(Key, Value)); return Count - 1; } /// <summary> /// 添加一个键值的节点 /// </summary> /// <param name="Key">主键</param> /// <param name="Value">值</param> /// <returns>索引</returns> public void Insert(int Index, string Key, string Value) { if (_UniqueKey) { int idx = IndexOf(Key); if (idx >= 0) { datas[idx].Value = Value; return; } } VonKeyValueItem item = new VonKeyValueItem(Key, Value); for (int i = Index; i < Count; i++) { VonKeyValueItem orgItem = datas[i]; datas[i] = item; item = orgItem; } datas.Add(item); } /// <summary> /// 删除值 /// </summary> /// <param name="Index"></param> public void Delete(int Index) { datas.RemoveAt(Index); } /// <summary> /// 根据主键删除一个节点 /// </summary> /// <param name="Key"></param> public void Delete(string Key) { datas.RemoveAt(IndexOf(Key)); } /// <summary> /// 清除所有数据 /// </summary> public void Clear() { datas = new List<VonKeyValueItem>(); } /// <summary> /// 移动一个节点 /// </summary> /// <param name="Org">原始位置</param> /// <param name="Dest">目标位置</param> public void Move(int Org, int Dest) { int step = Org > Dest ? -1 : 1; VonKeyValueItem item = datas[Org]; while(Org != Dest) { datas[Org] = datas[Org + step]; Org += step; } datas[Dest] = item; } /// <summary> /// 主键是否采用唯一机制,默认是唯一,不允许重复 /// </summary> public bool UniqueKey { get { return _UniqueKey; } set { _UniqueKey = value; } } private bool _UniqueKey = true; public bool ContainsListCollection { get { return false; } } public IList GetList() { return datas; } public IEnumerator GetEnumerator() { return new EVonKeyValueCollection(datas); } } /// <summary> /// 为 VonKeyValueCollection 支持foreach循环建立的 IEnumerator 接口类 /// </summary> internal class EVonKeyValueCollection : IEnumerator { public List<VonKeyValueItem> datas; public EVonKeyValueCollection(List<VonKeyValueItem> collection) { this.datas = collection; } int position = -1; public bool MoveNext() { position++; return position < datas.Count; } public void Reset() { position = -1; } public object Current { get { try { return datas[position]; } catch (IndexOutOfRangeException ex) { throw new InvalidOperationException(); } } } } /// <summary> /// 字符键值集合(含应用对象) /// </summary> public class VonStringCollection : IListSource { private List<VonDataItem> datas = new List<VonDataItem>(); /// <summary> /// 数量 /// </summary> public int Count { get { return datas.Count; } } /// <summary> /// 根据索引得到设定值 /// </summary> /// <param name="Index">索引</param> /// <returns>返回值</returns> public string this[int Index] { get { return datas[Index].Value; } set { datas[Index].Value = value; } } /// <summary> /// 根据索引得到设定值 /// </summary> /// <param name="Index">索引</param> /// <returns>返回值</returns> public string this[string Key] { get { int idx = IndexOfKey(Key); if (idx < 0) return ""; else return this[idx]; } set { int idx = IndexOfKey(Key); if (idx < 0) Add(Key, value, null); else this[idx] = value; } } /// <summary> /// 根据索引得到索引的键值 /// </summary> /// <param name="Index">索引</param> /// <returns></returns> public string GetKey(int Index) { return datas[Index].Key; } /// <summary> /// 得到存储的对象 /// </summary> /// <param name="Key"></param> /// <returns></returns> public object GetObject(string Key) { int idx = IndexOfKey(Key); if (idx < 0) return null; else return datas[idx].Data; } /// <summary> /// 得到存储的对象 /// </summary> /// <param name="Index"></param> /// <returns></returns> public object GetObject(int Index) { return datas[Index].Data; } /// <summary> /// 设置存储的对象 /// </summary> /// <param name="Index">索引</param> /// <param name="Data">关联对象</param> public void SetObject(int Index, object Data) { datas[Index].Data = Data; } /// <summary> /// 更改键值 /// </summary> /// <param name="Index">索引</param> /// <param name="Key">新键值</param> public void SetKey(int Index, string Key) { datas[Index].Key = Key; } /// <summary> /// 根据存储的对象得到记录索引 /// </summary> /// <param name="Data">对象</param> /// <returns>索引</returns> public int IndexOfObject(object Data) { for (int i = 0; i < Count; i++) { if (datas[i].Data.Equals(Data)) return i; } return -1; } /// <summary> /// 根据存储的值得到记录索引 /// </summary> /// <param name="Value">对象</param> /// <returns>索引</returns> public int IndexOfValue(string Value) { for (int i = 0; i < Count; i++) { if (datas[i].Value.Equals(Value, StringComparison.OrdinalIgnoreCase)) return i; } return -1; } /// <summary> /// 根据键值得到索引 /// </summary> /// <param name="KeyValue">键值</param> /// <returns>索引</returns> public int IndexOfKey(string Key) { for (int i = 0; i < Count; i++) { if (datas[i].Key.Equals(Key, StringComparison.OrdinalIgnoreCase)) return i; } return -1; } /// <summary> /// 添加一个键值 /// </summary> /// <param name="keyValue">键值内容,例如:RED=3453455</param> /// <returns></returns> public int Add(string keyValue) { string[] kv = keyValue.Split(Delimiter); switch (kv.Length) { case 1: return Add(kv[0], "", null); case 2: return Add(kv[0], kv[1], null); default: return 0; } } /// <summary> /// 添加一个键值的节点 /// </summary> /// <param name="Key">主键</param> /// <param name="Value">值</param> /// <returns>索引</returns> public int Add(string Key, string Value) { return Add(Key, Value, null); } /// <summary> /// 添加一个键值的节点 /// </summary> /// <param name="Key">主键</param> /// <param name="Value">值</param> /// <param name="Data">对象</param> /// <returns>索引</returns> public int Add(string Key, string Value, object Data) { int idx = IndexOfKey(Key); VonDataItem Item; if (idx >= 0) { Item = datas[idx]; Item.Value = Value; Item.Data = Data; return idx; } else { Item = new VonDataItem(Key, Value, Data); datas.Add(Item); return Count - 1; } } /// <summary> /// 添加一组键值的节点 /// </summary> /// <param name="lst">键值组</param> public void Add(VonStringCollection lst) { foreach (VonDataItem item in lst.datas) { datas.Add(item); } } /// <summary> /// 保存一个节点信息,如果发现重复键值则替换,没有则添加 /// </summary> /// <param name="Key">键值</param> /// <param name="Value">内容</param> /// <param name="Data">数据</param> /// <returns></returns> public int Save(string Key, string Value, object Data) { int idx = IndexOfKey(Key); if (idx < 0) return Add(Key, Value, Data); datas[idx].Value = Value; datas[idx].Data = Data; return idx; } /// <summary> /// 添加一个键值的节点 /// </summary> /// <param name="Key">主键</param> /// <param name="Value">值</param> /// <returns>索引</returns> public void Insert(int Index, string Key, string Value, object Data) { VonDataItem newItem = new VonDataItem(); newItem.Key = Key; newItem.Value = Value; newItem.Data = Data; VonDataItem item = newItem; VonDataItem orgItem = datas[Index]; for (int i = Index; i < Count; i++) { orgItem = datas[Index]; datas[Index] = item; item = orgItem; } datas.Add(orgItem); } /// <summary> /// 删除值 /// </summary> /// <param name="Index"></param> public void Delete(int Index) { datas.RemoveAt(Index); } /// <summary> /// 根据主键删除一个节点 /// </summary> /// <param name="Key"></param> public void Delete(string Key) { datas.RemoveAt(IndexOfKey(Key)); } /// <summary> /// 文本输出或导入采用时键与值之间的间隔符,默认为“=” /// </summary> public char Delimiter { get { return _Delimiter; } set { _Delimiter = value; } } private char _Delimiter = '='; /// <summary> /// 文本输出或导入采用的间隔符,默认为tab /// </summary> public char Termination { get { return _Termination; } set { _Termination = value; } } private char _Termination = '\t'; /// <summary> /// 转换为文本格式,间隔符号根据Delimiter来定义 /// </summary> public string Text { get { StringBuilder S = new StringBuilder(); foreach (VonDataItem item in datas) { S.Append(_Termination + item.Key + _Delimiter + item.Value); } if (S.Length > 0) return S.Remove(0, 1).ToString(); else return ""; } set { datas.Clear(); string key = ""; string vl = ""; foreach (char c in value) { if (c == _Termination) { VonDataItem item = new VonDataItem(); item.Key = key; item.Value = vl; datas.Add(item); key = ""; vl = ""; } else if (c == _Delimiter) { key = vl; vl = ""; } else { vl += c; } } if (key.Trim() != "") { VonDataItem item = new VonDataItem(); item.Key = key; item.Value = vl; datas.Add(item); } } } /// <summary> /// 获得键值文本,以_Delimiter间隔 /// </summary> public string KeyText { get { StringBuilder S = new StringBuilder(); foreach (VonDataItem item in datas) { S.Append(_Termination + item.Key); } return S.Remove(0, 1).ToString(); } } public bool ContainsListCollection { get { return false; } } public IList GetList() { return datas; } } /// <summary> /// windows ini类型配置信息管理类 /// </summary> public class VonConfigCollection { Hashtable tb = new Hashtable(); private bool modified = false; /// <summary> /// 文件格式,设置后系统完成文件内容读取,释放时,系统完成修改后的存储 /// </summary> public string Filename { get { return _Filename; } set { tb.Clear(); _Filename = Filename; using (StreamReader sr = new StreamReader(Filename, System.Text.Encoding.Default, true)) { String line; NameValueCollection currentTB = null; while ((line = sr.ReadLine()) != null) { line = line.Trim(); if (line == "" || line[0] == ';') continue; if (line[0] == '[') { currentTB = new NameValueCollection(); tb.Add(line.Substring(1, line.Length - 2), currentTB);//line.Substring(2, line.Length - 2) = copy(line, 2, strln(line) - 2) } else { int pos = line.IndexOf('='); string ident = line.Substring(0, pos); string vl = line.Substring(pos + 1, line.Length - pos - 1); currentTB.Add(ident, vl); } } } } } private string _Filename = ""; /// <summary> /// 构造函数 /// </summary> /// <param name="Filename">ini配置文件名称</param> public VonConfigCollection() { } /// <summary> /// 全部配置信息文本 /// </summary> public string Text { get { StringBuilder s = new StringBuilder(); NameValueCollection currentTB = null; foreach (DictionaryEntry de in tb) { currentTB = (NameValueCollection)de.Value; s.AppendLine("[" + de.Key + "]"); for (int i = 0; i < currentTB.Count; i++) s.AppendLine(currentTB.Keys[i] + "=" + currentTB[i]); } return s.ToString(); } set { tb.Clear(); StringBuilder s = new StringBuilder(); string key = null; NameValueCollection currentTB = null; foreach (char c in value) { if (c == '[') { if (key != null) { currentTB.Add(key, s.ToString()); s.Length = 0; key = null; } } else if (c == ']') { currentTB = new NameValueCollection(); tb.Add(s.ToString(), currentTB); s.Length = 0; } else if (c == '=') { if (s[0] != ';') key = s.ToString(); s.Length = 0; } else if (c == '\r' || c == '\n') { if (key != null) { currentTB.Add(key, s.ToString()); key = null; } s.Length = 0; } else s.Append(c); } if (key != null) { currentTB.Add(key, s.ToString()); } } } /// <summary> /// 当前段落数量 /// </summary> public int SectionCount { get { return tb.Count; } } /// <summary> /// 检查段落是否存在 /// </summary> /// <param name="SectionName"></param> /// <returns></returns> public bool ExistSection(string SectionName) { return tb.ContainsKey(SectionName); } /// <summary> /// 检查段落值是否存在 /// </summary> /// <param name="SectionName"></param> /// <returns></returns> public bool ExistIdent(string SectionName, string Ident) { return tb.ContainsKey(SectionName) && ((NameValueCollection)tb[SectionName])[Ident] != null; } /// <summary> /// 段落中内容的数量 /// </summary> /// <param name="SectionName">段落名称</param> /// <returns></returns> public int IdentCount(string SectionName) { NameValueCollection identTable = (NameValueCollection)tb[SectionName]; if (identTable == null) return 0; return identTable.Count; } /// <summary> /// 根据段落名称得到段落内容 /// </summary> /// <param name="SectionName"></param> /// <returns></returns> public NameValueCollection GetSection(string SectionName) { return (NameValueCollection)tb[SectionName]; } /// <summary> /// 得到一个ini文件配置字符值 /// </summary> /// <param name="Section">段落名称</param> /// <param name="Ident">配置名称</param> /// <param name="Value">缺省值</param> /// <returns>配置值</returns> public string ReadString(string Section, string Ident, string Value) { NameValueCollection identTable = (NameValueCollection)tb[Section]; if (identTable == null) return Value; string result = identTable[Ident]; if (result == null) return Value; return result; } /// <summary> /// 得到一个ini文件配置整数值 /// </summary> /// <param name="Section">段落名称</param> /// <param name="Ident">配置名称</param> /// <param name="Value">缺省值</param> /// <returns>配置值</returns> public int ReadInteger(string Section, string Ident, int Value) { return int.Parse(ReadString(Section, Ident, Value.ToString())); } /// <summary> /// 得到一个ini文件配置浮点值 /// </summary> /// <param name="Section">段落名称</param> /// <param name="Ident">配置名称</param> /// <param name="Value">缺省值</param> /// <returns>配置值</returns> public double ReadDouble(string Section, string Ident, double Value) { return double.Parse(ReadString(Section, Ident, Value.ToString())); } /// <summary> /// 得到一个ini文件配置布尔值 /// </summary> /// <param name="Section">段落名称</param> /// <param name="Ident">配置名称</param> /// <param name="Value">缺省值</param> /// <returns>配置值</returns> public bool ReadBoolean(string Section, string Ident, bool Value) { return bool.Parse(ReadString(Section, Ident, Value.ToString())); } /// <summary> /// 得到一个ini文件配置日期值 /// </summary> /// <param name="Section">段落名称</param> /// <param name="Ident">配置名称</param> /// <param name="Value">缺省值</param> /// <returns>配置值</returns> public DateTime ReadBDatetime(string Section, string Ident, DateTime Value) { return DateTime.Parse(ReadString(Section, Ident, Value.ToString())); } /// <summary> /// 得到所有段落名称列表 /// </summary> /// <returns>段落名称列表</returns> public ArrayList ReadSections() { ArrayList result = new ArrayList(); foreach (DictionaryEntry sc in tb) { result.Add(sc.Key); } return result; } /// <summary> /// 到段落中设置项目的名称列表 /// </summary> /// <param name="Section">段落名称</param> /// <returns>项目的名称列表</returns>) public ArrayList ReadSectionIdents(string Section) { ArrayList result = new ArrayList(); NameValueCollection identTable = (NameValueCollection)tb[Section]; if (identTable == null) return result; for (int i = 0; i < identTable.Count; i++) { result.Add(identTable.Keys[i]); } return result; } /// <summary> /// 设置一个ini文件配置字符值 /// </summary> /// <param name="Section">段落名称</param> /// <param name="Ident">配置名称</param> /// <param name="Value">配置值</param> public void WriteString(string Section, string Ident, string Value) { NameValueCollection identTable = (NameValueCollection)tb[Section]; if (identTable == null) { identTable = new NameValueCollection(); tb.Add(Section, identTable); } if (identTable[Ident] == null) { identTable.Add(Ident, Value); } else identTable[Ident] = Value; modified = true; } /// <summary> /// 设置一个ini文件配置整数值 /// </summary> /// <param name="Section">段落名称</param> /// <param name="Ident">配置名称</param> /// <param name="Value">配置值</param> public void WriteInteger(string Section, string Ident, int Value) { WriteString(Section, Ident, Value.ToString()); } /// <summary> /// 设置一个ini文件配置浮点值 /// </summary> /// <param name="Section">段落名称</param> /// <param name="Ident">配置名称</param> /// <param name="Value">配置值</param> public void WriteDouble(string Section, string Ident, double Value) { WriteString(Section, Ident, Value.ToString()); } /// <summary> /// 设置一个ini文件配置日期值 /// </summary> /// <param name="Section">段落名称</param> /// <param name="Ident">配置名称</param> /// <param name="Value">配置值</param> public void WriteDatetime(string Section, string Ident, DateTime Value) { WriteString(Section, Ident, Value.ToString()); } /// <summary> /// 设置一个ini文件配置布尔值 /// </summary> /// <param name="Section">段落名称</param> /// <param name="Ident">配置名称</param> /// <param name="Value">配置值</param> public void WriteBoolean(string Section, string Ident, bool Value) { WriteString(Section, Ident, Value.ToString()); } /// <summary> /// 析构函数,存储修改过的ini配置文件信息 /// </summary> ~VonConfigCollection() { if (_Filename == "") return; if (!modified) return; using (StreamWriter sw = new StreamWriter(_Filename)) { foreach (DictionaryEntry sc in tb) { string sectionName = (string)sc.Key; NameValueCollection identTable = (NameValueCollection)sc.Value; sw.WriteLine("[" + sectionName + "]"); for (int i = 0; i < identTable.Count; i++) { sw.WriteLine(identTable.Keys[i] + "=" + identTable.Get(0)); } } } } } /// <summary> /// 参数设置间隔符方案 /// </summary> /// <example>EVPDS_Custom:用户手动定义的间隔符</example> /// <example>EVPDS_Comma:{section}:{key}={value},...\r</example> /// <example>EVPDS_Semicolon:{section}:{key}={value};...\r</example> /// <example>EVPDS_Bracket:{section}={key}({value})...\r</example> /// <example>EVPDS_Special:{section}#3{key}#4{value}#5...#7</example> public enum EVonParamDelimiterScheme { /// <summary> /// 用户手动定义的间隔符 /// </summary> EVPDS_Custom, /// <summary> /// {section}:{key}={value},...\r /// </summary> EVPDS_Comma, /// <summary> /// {section}:{key}={value};...\r /// </summary> EVPDS_Semicolon, /// <summary> /// {section}={key}({value})...\r /// </summary> EVPDS_Bracket, /// <summary> /// {section}#3{key}#4{value}#5...#7 /// </summary> EVPDS_Special } /// <summary> /// 参数集合支持 name=key1(value1)key2(value2)...,同样也支持name=key1=value1,key2=value2,...,或者name#3key1#3value1#3key2#3value2#3...#4 /// </summary> public class VonParamItem { List<VonKeyValueItem> items = new List<VonKeyValueItem>(); /// <summary> /// 段落名称 /// </summary> public string ParamName { get { return _ParamName; } set { _ParamName = value; } } private string _ParamName; /// <summary> /// 添加一个键值 /// </summary> /// <param name="key">键名</param> /// <param name="value">键值</param> public void Add(string key, string value) { foreach (VonKeyValueItem item in items) { if (item.Key.Equals(key, StringComparison.OrdinalIgnoreCase)) { item.Value = value; return; } } VonKeyValueItem newItem = new VonKeyValueItem(key, value); items.Add(newItem); } /// <summary> /// 删除一个键值 /// </summary> /// <param name="key">键名</param> public void Delete(string key) { foreach (VonKeyValueItem item in items) { if (item.Key.Equals(key, StringComparison.OrdinalIgnoreCase)) { items.Remove(item); return; } } } /// <summary> /// 清除所有键值 /// </summary> public void Clear() { items.Clear(); } /// <summary> /// 读取键值 /// </summary> /// <param name="key">键名</param> /// <returns>键值</returns> public string ReadValue(string key) { foreach (VonKeyValueItem item in items) { if (item.Key.Equals(key, StringComparison.OrdinalIgnoreCase)) { return item.Value; } } return ""; } /// <summary> /// 得到一个参数的文字内容 /// </summary> /// <returns></returns> public string GetText(char NameFlag, char KeyFlag, char ValueFlag) { StringBuilder sb = new StringBuilder(); foreach (VonKeyValueItem item in items) { sb.Append(item.Key + KeyFlag + item.Value + ValueFlag); } //sb.Remove(0, 1); return _ParamName + NameFlag + sb.ToString(); } /// <summary> /// 将一个文字内容反写回本类中 /// </summary> /// <param name="value">文字</param> /// <param name="Idx">开始拾取位置</param> /// <param name="endFlag">结束字符符集,例如:"\r"或是"\n"或是";"等</param> /// <returns></returns> public int SetText(string value, int Idx, char NameFlag, char KeyFlag, char ValueFlag, char endFlag) { // read a name from value _ParamName = ""; while (value[Idx] != NameFlag) { _ParamName += value[Idx]; Idx++; } // read params from value items.Clear(); string szK = ""; string szV = ""; for (int i = Idx + 1; i < value.Length; i++) { if (value[i] == KeyFlag) { szK = szV; szV = ""; continue; } else if (value[i] == ValueFlag) { VonKeyValueItem item = new VonKeyValueItem(szK, szV); items.Add(item); szK = ""; szV = ""; continue; } else if (value[i] == endFlag) { return i + 1; } szV += value[i]; } return value.Length; } } /// <summary> /// 含键值的参数集合,例如: /// </summary> public class VonParamCollection { public List<VonParamItem> keyParams = new List<VonParamItem>(); /// <summary> /// 名称和内容的间隔符 /// </summary> public char NameFlag { get { return _NameFlag; } set { _NameFlag = value; _TextScheme = EVonParamDelimiterScheme.EVPDS_Custom; } } private char _NameFlag = '='; /// <summary> /// 键值对的间隔符 /// </summary> public char KeyFlag { get { return _KeyFlag; } set { _KeyFlag = value; _TextScheme = EVonParamDelimiterScheme.EVPDS_Custom; } } private char _KeyFlag = '('; /// <summary> /// 键值对的结束符 /// </summary> public char ValueFlag { get { return _ValueFlag; } set { _ValueFlag = value; _TextScheme = EVonParamDelimiterScheme.EVPDS_Custom; } } private char _ValueFlag = ')'; /// <summary> /// 段落结束标识 /// </summary> public char EndFlag { get { return _EndFlag; } set { _EndFlag = value; _TextScheme = EVonParamDelimiterScheme.EVPDS_Custom; } } private char _EndFlag = '\r'; public EVonParamDelimiterScheme TextScheme { get { return _TextScheme; } set { _TextScheme = value; switch (_TextScheme) { case EVonParamDelimiterScheme.EVPDS_Comma: _NameFlag = ':'; _KeyFlag = '='; _ValueFlag = ','; _EndFlag = '\r'; break; case EVonParamDelimiterScheme.EVPDS_Semicolon: _NameFlag = ':'; _KeyFlag = '='; _ValueFlag = ';'; _EndFlag = '\r'; break; case EVonParamDelimiterScheme.EVPDS_Bracket: _NameFlag = '='; _KeyFlag = '('; _ValueFlag = ')'; _EndFlag = '\r'; break; case EVonParamDelimiterScheme.EVPDS_Special: _NameFlag = (char)3; _KeyFlag = (char)4; _ValueFlag = (char)5; _EndFlag = (char)7; break; } } } private EVonParamDelimiterScheme _TextScheme = EVonParamDelimiterScheme.EVPDS_Bracket; /// <summary> /// 根据索引得到设定值 /// </summary> /// <param name="Index">索引</param> /// <returns>返回值</returns> public VonParamItem this[int Index] { get { return keyParams[Index]; } set { keyParams[Index] = value; } } /// <summary> /// 根据索引得到设定值 /// </summary> /// <param name="ParamName">段落名称</param> /// <returns>返回值</returns> public VonParamItem this[string ParamName] { get { foreach (VonParamItem param in keyParams) { if (param.ParamName.Equals(ParamName, StringComparison.OrdinalIgnoreCase)) return param; } return null; } set { foreach (VonParamItem param in keyParams) { if (param.ParamName.Equals(ParamName, StringComparison.OrdinalIgnoreCase)) { keyParams.Remove(param); break; } } keyParams.Add(value); } } /// <summary> /// 保存一个参数值 /// </summary> /// <param name="ParamName">段落名称</param> /// <param name="Key">键名</param> /// <param name="Value">键值</param> /// <returns></returns> public void Save(string ParamName, string Key, string Value) { VonParamItem item = null; foreach (VonParamItem param in keyParams) { if (param.ParamName.Equals(ParamName, StringComparison.OrdinalIgnoreCase)) { item = param; break; } } if (item == null) { item = new VonParamItem(); keyParams.Add(item); } item.ParamName = ParamName; item.Add(Key, Value); } /// <summary> /// 提取所有内容中指定段落中键值 /// </summary> /// <param name="ParamName"></param> /// <param name="Key"></param> /// <returns></returns> public string Read(string ParamName, string Key) { foreach (VonParamItem param in keyParams) { if (param.ParamName.Equals(ParamName, StringComparison.OrdinalIgnoreCase)) { return param.ReadValue(Key); } } return ""; } /// <summary> /// 得到该类的存储值 /// </summary> /// <returns></returns> public string GetText() { StringBuilder sb = new StringBuilder(); foreach (VonParamItem item in keyParams) { sb.Append(_EndFlag + item.GetText(_NameFlag, _KeyFlag, _ValueFlag)); } sb.Remove(0, 1); return sb.ToString(); } /// <summary> /// /// </summary> /// <param name="value"></param> /// <param name="idx"></param> /// <returns></returns> public int SetText(string value, int idx) { keyParams.Clear(); while (idx < value.Length && value[idx] != _EndFlag) { VonParamItem newItem = new VonParamItem(); idx = newItem.SetText(value, idx, _NameFlag, _KeyFlag, _ValueFlag, _EndFlag) + 1; keyParams.Add(newItem); } return idx + 1; } } /// <summary> /// /// </summary> public static class VonFuns { /// <summary> /// 将金额转换为中文大写 /// </summary> /// <param name="value">金额值</param> /// <returns>中文表达的金额值</returns> public static string CurrencyToGB(double value) { const string gbValue = "零壹贰叁肆伍陆柒捌玖"; const string gbUnit = "分角元拾佰仟万拾佰仟亿拾佰仟万"; string result = ""; if (value < 0) { result = "负"; value = -value; } string szStr = ((int)(value * 100 + 0.5)).ToString(); for (int i = 0; i < szStr.Length; i++) { result += gbValue[szStr[i] - '0']; result += gbUnit[szStr.Length - i - 1]; } result = result.Replace("零仟", "零"); result = result.Replace("零佰", "零"); result = result.Replace("零拾", "零"); result = result.Replace("零角", "零"); result = result.Replace("零分", "整"); result = result.Replace("零零", "零"); result = result.Replace("零零", "零"); result = result.Replace("零亿", "亿"); result = result.Replace("零万", "万"); result = result.Replace("零元", "元"); if (result == "整") result = "零元整"; else { result = result.Replace("亿万", "亿"); result = result.Replace("零整", "整"); } return result; } /// <summary> /// 将数值转换为中文大写 /// </summary> /// <param name="value">数值</param> /// <returns>中文表达的数值</returns> public static string NumToGB(double value) { const string gbValue = "零壹贰叁肆伍陆柒捌玖"; const string gbUnit = "点拾佰仟万拾佰仟亿拾佰仟万"; string result = ""; if (value < 0) { result = "负"; value = -value; } string szStr = value.ToString(); int zeroPos = szStr.IndexOf('.'); if (zeroPos == 0) zeroPos = szStr.Length; for (int i = 0; i < szStr.Length; i++) { if (szStr[i] != '.') result += gbValue[szStr[i] - '0']; if (zeroPos - i > 0) result += gbUnit[zeroPos - i - 1]; } result = result.Replace("零仟", "零"); result = result.Replace("零佰", "零"); result = result.Replace("零拾", "零"); result = result.Replace("零零", "零"); result = result.Replace("零零", "零"); result = result.Replace("零亿", "亿"); result = result.Replace("零万", "万"); if (result.EndsWith("壹拾")) result.Remove(result.Length - 1); result = result == "零点" ? result = "零" : result = result.Replace("零点", "点"); if (result.EndsWith("点")) result.Remove(result.Length - 1); return result.Replace("亿万", "亿"); } /// <summary> /// 判断是否为数字字符串 /// </summary> /// <param name="message"></param> /// <returns></returns> public static bool isNumberic(string numStr) { for (int i = 0; i < numStr.Length; i++) { if (numStr[i] <= '0' || numStr[i] >= '9') return false; } return true; } /// <summary> /// CheckBoxList 选择结果,以二进制方式进行存储 /// </summary> /// <param name="ckl"></param> /// <returns></returns> public static int GetCheckValue(CheckBoxList ckl) { int result = 0; int pos = 1; foreach (ListItem item in ckl.Items) { result += item.Selected ? pos : 0; pos = pos * 2; } return result; } /// <summary> /// 根据值,按照二进制位设置 CheckBoxList 选择结果 /// </summary> /// <param name="ckl"></param> /// <param name="checkValue"></param> public static void SetCheckValue(CheckBoxList ckl, int checkValue) { int pos = checkValue % 2; checkValue = checkValue / 2; foreach (ListItem item in ckl.Items) { item.Selected = pos == 1; pos = checkValue % 2; checkValue = checkValue / 2; } } /// <summary> /// 根据 CheckBoxList 生成字符串(以逗号做间隔符)类型的选择结果 /// </summary> /// <param name="ckl"></param> /// <returns></returns> public static string GetCheckItem(CheckBoxList ckl) { string result = ""; foreach (ListItem item in ckl.Items) { result += item.Selected ? "," + item.Value : ""; } if (result != "") result.Remove(0, 1); return result; } /// <summary> /// 根据字符串(以逗号做间隔符),设置 CheckBoxList 选择结果 /// </summary> /// <param name="ckl"></param> /// <param name="checkItem"></param> public static void SetCheckItem(CheckBoxList ckl, string checkItem) { checkItem = ',' + checkItem + ','; foreach (ListItem item in ckl.Items) { item.Selected = checkItem.IndexOf(',' + item.Value + ',') >= 0; } } /// <summary> /// 查找一个字符串,排除中间的引号内容。 /// </summary> /// <param name="S">被查找的字符串</param> /// <param name="subStr">要找到的字符串</param> /// <returns>位置,从0开始,未找到为-1</returns> public static int FindStr(string S, string subStr) { if (subStr == "") return 0; string szS = ""; char nextChar = '\x0000'; int idx = 0; foreach (char ch in S) { switch (ch) { case '"': case '\x0027': if (nextChar == ch) nextChar = '\x0000'; else nextChar = ch; szS = ""; break; default: if (nextChar == '\x0000') szS += ch; break; } idx++; if (szS.Length > subStr.Length) szS = szS.Remove(0, 1); if (szS.Equals(subStr, StringComparison.CurrentCultureIgnoreCase)) return idx - subStr.Length; } return -1; } /// <summary> /// 将字符串转换为数组 /// </summary> /// <param name="S">字符串</param> /// <param name="flags">换行标记,例如“&\\?”</param> /// <param name="startFlag">起始字符标记,如果没有可以用""表示</param> /// <param name="endFlag">结束字符标记,如果没有可以用""表示</param> /// <returns>数组</returns> public static List<string> SplitString(string S, string flags, string startFlag, string endFlag) { List<string> result = new List<string>(); string szStart = ""; string szEnd = ""; string szValue = ""; char nextChar = '\x0000'; bool isStart = startFlag == ""; foreach (char ch in S) { switch (ch) { case '"': case '\x0027': if (nextChar == ch) nextChar = '\x0000'; else nextChar = ch; szStart = ""; szEnd = ""; break; default: if (nextChar == '\x0000') { szStart += ch; szEnd += ch; if (szStart.Length > startFlag.Length) szStart = szStart.Remove(0, 1); if (szEnd.Length > endFlag.Length) szEnd = szEnd.Remove(0, 1); } break; } if (isStart) { if (nextChar == '\x0000' && flags.IndexOf(ch) >= 0) { if (!string.IsNullOrEmpty(szValue)) { result.Add(szValue); szValue = ""; } } else szValue += ch; } if (isStart && szEnd != "" && szEnd.Equals(endFlag, StringComparison.CurrentCultureIgnoreCase)) { szValue = szValue.Remove(szValue.Length - endFlag.Length); break; } if (!isStart && szStart.Equals(startFlag, StringComparison.CurrentCultureIgnoreCase)) { szValue = ""; isStart = true; } } if (szValue != "") result.Add(szValue); return result; } /// <summary> /// 将字符串转换为数组(截取时包含起始和截取位置) /// </summary> /// <param name="S">字符串</param> /// <param name="flags">换行标记,例如“&\\?”</param> /// <param name="startIdx">起始位置(包含)从0开始</param> /// <param name="endIdx">结束位置(包含),0表示全部</param> /// <returns>数组</returns> public static List<string> SplitString(string S, string flags, int startIdx, int endIdx) { List<string> result = new List<string>(); if (S.Length <= startIdx) return result; if (endIdx >= S.Length || endIdx == 0) endIdx = S.Length - 1; string szValue = ""; char nextChar = '\x0000'; for (int i = startIdx; i <= endIdx; i++) { char ch = S[i]; switch (ch) { case '"': case '\x0027': if (nextChar == ch) nextChar = '\x0000'; else nextChar = ch; break; } if (nextChar == '\x0000' && flags.IndexOf(ch) >= 0) { result.Add(szValue); szValue = ""; } else szValue += ch; } if (szValue != "") result.Add(szValue); return result; } /// <summary> /// 将URL字符串解码为可读URL内容 /// </summary> /// <param name="url">url地址</param> /// <returns></returns> public static string UrlDecode(string url) { //将Url中的编码转换为简体汉字 return System.Web.HttpUtility.UrlDecode(url, System.Text.Encoding.GetEncoding("GB2312")); } /// <summary> /// 将URL内容加码为可使用的URL字符串 /// </summary> /// <param name="value">参数类型</param> /// <returns>URL信息</returns> public static string UrlEncode(string str) { //将简体汉字转换为Url编码 return System.Web.HttpUtility.UrlEncode(str, System.Text.Encoding.GetEncoding("GB2312")); } static readonly string[] VonColorDefined = new string[] { "#8B0016","#B2001F","#C50023","#DF0029","#E54646","#EE7C6B","#F5A89A","#8E1E20", "#B6292B","#C82E31","#E33539","#EB7153","#F19373","#F6B297","#945305","#BD6B09", "#D0770B","#EC870E","#F09C42","#F5B16D","#FACE9C","#976D00","#C18C00","#D59B00", "#F1AF00","#F3C246","#F9CC76","#FCE0A6","#9C9900","#C7C300","#DCD800","#F9F400", "#FCF54C","#FEF889","#FFFAB3","#367517","#489620","#50A625","#5BBD2B","#83C75D", "#AFD788","#C8E2B1","#006241","#007F54","#008C5E","#00A06B","#00AE72","#67BF7F", "#98D0B9","#00676B","#008489","#009298","#00A6AD","#00B2BF","#6EC3C9","#99D1D3", "#103667","#184785","#1B4F93","#205AA7","#426EB4","#7388C1","#94AAD6","#211551", "#2D1E69","#322275","#3A2885","#511F90","#635BA2","#8273B0","#38044B","#490761", "#52096C","#5D0C7B","#79378B","#8C63A4","#AA87B8","#64004B","#780062","#8F006D", "#A2007C","#AF4A92","#C57CAC","#D2A6C7","#ECECEC","#D7D7D7","#C2C2C2","#B7B7B7", "#A0A0A0","#898989","#707070","#363636"}; static readonly string[] VonColorDefine = new string[]{ "#FFFFCC","#CCFFFF","#FFCCCC","#99CCCC","#FFCC99","#FFCCCC","#FF9999","#996699", //1 "#FFCCCC","#CC9999","#FFFFCC","#CCCC99","#FFCCCC","#FFFF99","#CCCCFF","#0099CC", "#CCCCCC","#FF6666","#FF9966","#FF6666","#FFCCCC","#CC9966","#666666","#CC9999", "#FF6666","#FFFF66","#99CC66","#CC3333","#CCCCCC","#003366","#993333","#CCCC00", "#663366","#CCCC99","#666666","#CC9999","#FF6666","#FFFF00","#0066CC","#CC0033", "#333333","#CCCC00","#336633","#990033","#FFCC99","#993333","#CC9966","#003300", "#FF0033","#333399","#CCCC00","#CC0033","#003399","#99CC00","#CC0033","#999933", "#993333","#333300","#FFCC99","#FFFF99","#99CC99","#FFCC99","#CCFF99","#CCCCCC", "#FFCC99","#FFFFCC","#99CCFF","#FF9966","#FFFFCC","#99CC99","#FF9900","#FFFFCC", "#336699","#CCCC33","#FFFF99","#CC9933","#996600","#FFCC33","#FFFFCC","#FFFFCC", //10 "#CC9933","#336666","#FF9900","#FFFF00","#0099CC","#99CC33","#FF9900","#FFCC00", "#FF9933","#99CC33","#CC6699","#FF9933","#FFFF00","#3366CC","#FF9933","#FFFFCC", "#009966","#FF6600","#FFFF66","#009966","#990033","#CCFF66","#FF9900","#FF9966", "#996600","#CCCC00","#CC6600","#999999","#CCCC33","#CC6600","#CCCC33","#336699", "#FF9933","#999966","#663300","#FF9933","#FFFF66","#FFFFCC","#CCFFFF","#FFCCCC", "#FFFF00","#CCCC00","#99CCFF","#FFCC33","#FFFFCC","#FFFF33","#99CCFF","#CCCCCC", "#FFFF00","#9933FF","#99CCFF","#FFCC33","#FFFF33","#FFCC00","#66CC00","#FFFF99", "#FF9900","#FFFF00","#0099CC","#FFCC00","#0000CC","#FFFF99","#CC9999","#FFFFCC", "#6666CC","#999933","#FFFFCC","#CC99CC","#CCCC00","#666600","#FFFF66","#FF9966", "#FFFFCC","#99CC99","#FFCC33","#FFFFCC","#999966","#FFCC99","#FF6666","#FFFF66", //20 "#FFCC99","#999966","#FFFF00","#FFFF99","#99CC99","#666600","#999966","#FFFF99", "#333333","#006633","#333300","#CCCC99","#006633","#663300","#CCCC66","#33CC33", "#6666CC","#CCCC33","#CCFFCC","#FFCC99","#CCFF99","#CCCCCC","#CCCC00","#999966", "#FFFFCC","#CCCC33","#336699","#CCCC33","#999999","#CCFFFF","#00CC00","#0066CC", "#99CCCC","#99CC33","#FF9900","#FFCC00","#99CC33","#CCCCFF","#663300","#CCCC33", "#993399","#CC6600","#999999","#CCCC33","#CC9933","#FFFF99","#99CC99","#669933", "#CCCC33","#663300","#99CC33","#CCCCCC","#CC6600","#CCCC33","#336699","#666600", "#CCCC66","#CCFFCC","#333366","#99CC33","#336699","#666666","#99CC33","#003366", "#003333","#99CC33","#999999","#996633","#FFFF99","#99CC66","#009966","#FFFF00", "#339933","#9933CC","#339933","#339933","#99CC00","#FFFFCC","#FFFFCC","#CCCC66", //30 "#336666","#99CC33","#FFFF66","#336600","#339933","#CC9900","#666666","#339966", "#CCCCCC","#003366","#669933","#CCCCCC","#339933","#CCCCCC","#6699CC","#006633", "#CCCC33","#CC9933","#339933","#666633","#CCCC66","#339933","#FFCC33","#336699", "#006633","#669933","#99CC99","#336666","#996633","#CCCC33","#003300","#669933", "#CCCC99","#006633","#990033","#FF9900","#006633","#333300","#CCCC99","#006633", "#663300","#CCCC66","#993333","#CC9966","#003300","#CCFF99","#66CCCC","#339999", "#99CCFF","#66CC99","#666699","#009999","#66CCCC","#CCFFFF","#66CCCC","#CCFF66", "#FF99CC","#339999","#FFFF00","#336699","#CC9933","#339999","#FFCC33","#FFCC00", "#009999","#CC3333","#669999","#CCCCCC","#CC99CC","#339999","#CCCCCC","#339999", "#666699","#CCCCCC","#003333","#99CC99","#FFFFCC","#669999","#CCFFCC","#996699", //40 "#996699","#CCCC99","#669999","#999966","#CCCC99","#339999","#336666","#669999", "#CCCC99","#999999","#003366","#669999","#663333","#339999","#CCCC66","#333333", "#339999","#CCFFCC","#336666","#3399CC","#666666","#FFFFCC","#FFFF99","#CCCCFF", "#9999CC","#99CC99","#FFCCCC","#CCCCFF","#CCCC99","#9999CC","#FFFFCC","#FFCCCC", "#FFCCCC","#FF99CC","#CCCCFF","#660066","#663333","#CCCC99","#333333","#9966CC", "#CCCC00","#FF9966","#663399","#996699","#FFCCCC","#CC99CC","#996666","#CC99CC", "#FFCCCC","#FFCC99","#FF9933","#663366","#333399","#CCCCFF","#CC99CC","#663366", "#CCCCCC","#CC99CC","#996699","#9999CC","#CCCCFF","#CC9966","#999999","#663366", "#330033","#666666","#669999","#CCCCCC","#999999","#663366","#FF33CC","#CCCC99", "#663366","#663366","#999999","#CCCCFF","#999966","#993333","#330033","#663366" //50 -> 50*8 = 400 }; private static Int32 currentVonColorIdx = 0; /// <summary> /// 得到一个序列颜色字符串值 /// </summary> /// <returns></returns> public static string GetRandomColor() { //return VonColorDefined[(currentVonColorIdx++ * 3) % 92]; if (++currentVonColorIdx > 399) currentVonColorIdx = 0; return VonColorDefine[currentVonColorIdx]; } /// <summary> /// Crc值计算 /// </summary> /// <param name="crcInfo">准备计算的cec信息</param> /// <returns></returns> public static string CRC(String crcInfo) { System.Security.Cryptography.SHA1 sha = System.Security.Cryptography.SHA1.Create(); string strResult = ""; byte[] bytResult = sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes(crcInfo)); for (int i = 0; i < bytResult.Length; i++) { strResult = strResult + bytResult[i].ToString("X2"); } return strResult; } /// <summary> /// Crc值计算 /// </summary> /// <param name="crcValue">准备计算的cec信息</param> /// <returns></returns> public static byte[] CRC(byte[] crcValue) { System.Security.Cryptography.SHA1 sha = System.Security.Cryptography.SHA1.Create(); return sha.ComputeHash(crcValue); } /// <summary> /// 将 byte 数组转换为可视文字,采用 64 进制转换 /// </summary> /// <param name="Value">byte 数组</param> /// <returns>可视文字,长度为数组长度的 4/3,余数加 1 </returns> public static string BytesToStr(byte[] Value) { const string CryptValue = "ABCDEFGHIJKLMNOPQRSTUVWXYZ@1234567890@abcdefghijklmnopqrstuvwxyz"; string strResult = ""; int idx = 0, val = 0; /*----+---------+---------+---------+RTN+----- |1111 11 | | | 1 | |0000 0011|1111 | | 2 | |0000 0000|0000 1111|11 | 3 | |0000 0000|0000 0000|0011 1111| 4 | --BYTE|1--------+2--------+3--------+---+----- */ do { switch (idx % 3) { case 0: strResult += CryptValue[Value[idx] & 0x3F]; //1111 11 1 val = Value[idx] >> 6; //---- --VV break; case 1: strResult += CryptValue[val + (Value[idx] << 2) & 0x3F]; //0000 0011 1111 2 val = Value[idx] >> 4; // VV(----VVVV) break; //0 1 2 case 2: strResult += CryptValue[val + (Value[idx] << 4) & 0x003F]; // 1111 11 3 strResult += CryptValue[(Value[idx] >> 2) & 0x003F]; //0000 0000 0000 0000 0011 1111 4 val = 0; // VVVV--,-- ---- break; //0 1 2 } } while (++idx < Value.Length); if (idx % 3 > 0) strResult += CryptValue[val]; return strResult; } /// <summary> /// 压缩一个文件 /// </summary> /// <param name="srcFile">原始文件</param> /// <param name="zipFile">压缩到的目标文件</param> public static void compressionFile(string srcFile, string zipFile) { FileInfo fileToCompress = new FileInfo(srcFile); if ((File.GetAttributes(fileToCompress.FullName) & FileAttributes.Hidden) != FileAttributes.Hidden) { using (FileStream originalFileStream = fileToCompress.OpenRead()) { using (FileStream compressedFileStream = File.Create(zipFile)) { using (GZipStream compressionStream = new GZipStream(compressedFileStream, CompressionMode.Compress)) { originalFileStream.CopyTo(compressionStream); } } } } } /// <summary> /// 解压缩一个文件 /// </summary> /// <param name="srcFile">压缩过的zip文件</param> /// <param name="orgFile">解压成的目标文件</param> public static void decompressionFile(string srcFile, string orgFile) { FileInfo fileToDecompress = new FileInfo(srcFile); using (FileStream originalFileStream = fileToDecompress.OpenRead()) { string currentFileName = fileToDecompress.FullName; using (FileStream decompressedFileStream = File.Create(orgFile)) { using (GZipStream decompressionStream = new GZipStream(originalFileStream, CompressionMode.Decompress)) { decompressionStream.CopyTo(decompressedFileStream); } } } } /// <summary> /// 获取枚举描述特性值 /// </summary> /// <typeparam name="TEnum"></typeparam> /// <param name="enumerationValue">枚举值</param> /// <returns>枚举值的描述/returns> public static string GetRemark<TEnum>(this TEnum enumValue) where TEnum : struct, IComparable, IFormattable, IConvertible { Type type = enumValue.GetType(); if (!type.IsEnum) { throw new ArgumentException("EnumerationValue必须是一个枚举值", "enumerationValue"); } MemberInfo[] memberInfo = type.GetMember(enumValue.ToString()); if (memberInfo != null && memberInfo.Length > 0) { RemarkAttribute attr = (RemarkAttribute)memberInfo[0].GetCustomAttribute(typeof(RemarkAttribute), false); if (attr != null) return attr.Remark; } return enumValue.ToString(); } } }
VonGraphic.cs
using System; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; namespace VonPortal.Library { /// <summary> /// 关于图像处理的静态类 /// </summary> public static class VonGraphic { public static string info = ""; #region "ZOOM" /// <summary> /// 图形缩放类型 /// </summary> public enum EImgZoomKind { /// <summary> /// 变形缩放,按指定列宽直接缩放 /// </summary> IZK_FIX = 0, /// <summary> /// 固定宽缩放,从顶部截取 /// </summary> IZK_FIX_W_T = 10, /// <summary> /// 固定宽缩放,中心截取 /// </summary> IZK_FIX_W_C = 11, /// <summary> /// 固定宽缩放,从底部截取 /// </summary> IZK_FIX_W_B = 12, /// <summary> /// 固定高缩放,从左边截取 /// </summary> IZK_FIX_H_L = 20, /// <summary> /// 固定高缩放,中心截取 /// </summary> IZK_FIX_H_C = 21, /// <summary> /// 固定高缩放,从右边截取 /// </summary> IZK_FIX_H_R = 22, /// <summary> /// 自适应缩放,即以最短边为基础缩放,部分展示 /// </summary> IZK_FIX_MAX = 30, /// <summary> /// 自适应缩放,即以最长边为基础缩放,全图展示 /// </summary> IZK_FIX_FULL = 31, /// <summary> /// 智能缩放(是宽高比例,按比例的变化率决定用哪种方式展示) /// </summary> IZK_FIX_AUTO = 40, } /// <summary> /// 缩放图形文件 /// </summary> /// <param name="orgFilename">原始图形文件</param> /// <param name="destFilename">目标图形文件</param> /// <param name="newWidth">目标宽</param> /// <param name="newHeight">目标高</param> public static void Zoom(string orgFilename, string destFilename, EImgZoomKind kind, int newWidth, int newHeight) { Image img = System.Drawing.Image.FromFile(orgFilename); Image newImg = Zoom(img, kind, newWidth, newHeight); newImg.Save(destFilename, System.Drawing.Imaging.ImageFormat.Jpeg); newImg.Dispose(); } /// <summary> /// 不变形放缩 /// </summary> /// <param name="kind">图形缩放类型</param> /// <param name="orgImg">原始图</param> /// <param name="newWidth">目标宽</param> /// <param name="newHeight">目标高</param> /// <returns></returns> public static Image Zoom(Image orgImg, EImgZoomKind kind, int newWidth, int newHeight) { switch (kind) { case EImgZoomKind.IZK_FIX: return new Bitmap(orgImg, newWidth, newHeight); case EImgZoomKind.IZK_FIX_W_T: case EImgZoomKind.IZK_FIX_W_C: case EImgZoomKind.IZK_FIX_W_B: return widthZoom(orgImg, kind, newWidth, newHeight); case EImgZoomKind.IZK_FIX_H_L: case EImgZoomKind.IZK_FIX_H_C: case EImgZoomKind.IZK_FIX_H_R: return heightZoom(orgImg, kind, newWidth, newHeight); case EImgZoomKind.IZK_FIX_MAX: if (newHeight - orgImg.Height > newWidth - orgImg.Width) return heightZoom(orgImg, EImgZoomKind.IZK_FIX_H_C, newWidth, newHeight); return widthZoom(orgImg, EImgZoomKind.IZK_FIX_W_C, newWidth, newHeight); case EImgZoomKind.IZK_FIX_FULL: if (newHeight - orgImg.Height > newWidth - orgImg.Width) return widthZoom(orgImg, EImgZoomKind.IZK_FIX_W_C, newWidth, newHeight); return heightZoom(orgImg, EImgZoomKind.IZK_FIX_H_C, newWidth, newHeight); case EImgZoomKind.IZK_FIX_AUTO: //double rateW = Convert.ToDouble(decimal.Divide(Math.Abs(newHeight - orgImg.Height), orgImg.Height)); //double rateH = Convert.ToDouble(decimal.Divide(Math.Abs(newWidth - orgImg.Width), orgImg.Width)); double rate = Convert.ToDouble(decimal.Divide(newHeight * orgImg.Width, orgImg.Height * newWidth)); //if ((rate > 1 && newHeight > orgImg.Height) || (rate < 1 && newHeight < orgImg.Height)) //高度变化比较大的放大,以高为主的截取,宽度变化比较大缩小,以高度为主 // if (Math.Abs(newHeight - orgImg.Height) > Math.Abs(newWidth - orgImg.Width)) if (rate > 1.5 || rate < 0.666) { if (orgImg.Height > orgImg.Width) return widthZoom(orgImg, EImgZoomKind.IZK_FIX_W_C, newWidth, newHeight); else return heightZoom(orgImg, EImgZoomKind.IZK_FIX_H_C, newWidth, newHeight); } if (orgImg.Height > orgImg.Width) return heightZoom(orgImg, EImgZoomKind.IZK_FIX_H_C, newWidth, newHeight); return widthZoom(orgImg, EImgZoomKind.IZK_FIX_W_C, newWidth, newHeight); } return null; } /// <summary> /// 定宽截取 /// </summary> /// <param name="orgImg">原始图片</param> /// <param name="kind">定宽类型</param> /// <param name="newWidth">新宽度</param> /// <param name="newHeight">新高度</param> /// <returns></returns> private static Image widthZoom(Image orgImg, EImgZoomKind kind, int newWidth, int newHeight) { int szHeight = orgImg.Height * newWidth / orgImg.Width; Bitmap szBmp = new Bitmap(orgImg, newWidth, szHeight); Bitmap result = new Bitmap(newWidth, newHeight); Rectangle orgRect; int szInt = szHeight > newHeight ? 0 : (newHeight - szHeight) / 2; Rectangle destRect = new Rectangle(0, szInt, newWidth, newHeight - szInt); switch (kind) { case EImgZoomKind.IZK_FIX_W_T: szInt = 0; break; case EImgZoomKind.IZK_FIX_W_C: szInt = szHeight > newHeight ? (szHeight - newHeight) / 2 : 0; break; default: szInt = szHeight > newHeight ? szHeight - newHeight : 0; break; } orgRect = new Rectangle(0, szInt, newWidth, destRect.Height); Graphics g = Graphics.FromImage(result); g.DrawImage(szBmp, destRect, orgRect, GraphicsUnit.Pixel); return result; } /// <summary> /// 定高截取 /// </summary> /// <param name="orgImg">原始图片</param> /// <param name="kind">定高类型</param> /// <param name="newWidth">新宽度</param> /// <param name="newHeight">新高度</param> /// <returns></returns> private static Image heightZoom(Image orgImg, EImgZoomKind kind, int newWidth, int newHeight) { int szWidth = (int)(1.00000 * orgImg.Width * newHeight / orgImg.Height); Bitmap szBmp = new Bitmap(orgImg, szWidth, newHeight); Bitmap result = new Bitmap(newWidth, newHeight); Rectangle orgRect; int szInt = szWidth > newWidth ? 0 : (newWidth - szWidth) / 2; Rectangle destRect = new Rectangle(szInt, 0, newWidth - szInt, newHeight); switch (kind) { case EImgZoomKind.IZK_FIX_H_L: szInt = 0; break; case EImgZoomKind.IZK_FIX_H_C: szInt = szWidth > newWidth ? (szWidth - newWidth) / 2 : 0; break; default: szInt = szWidth > newWidth ? szWidth - newWidth : 0; break; } orgRect = new Rectangle(szInt, 0, destRect.Width, newHeight); Graphics g = Graphics.FromImage(result); g.DrawImage(szBmp, destRect, orgRect, GraphicsUnit.Pixel); return result; } #endregion #region "Rotation" /// <summary> /// /// </summary> /// <param name="img">图像</param> /// <param name="angle">旋转角度</param> /// <param name="hFlip">水平翻转</param> /// <param name="vFlip">垂直翻转</param> /// <returns></returns> public static Image Rotation(Image img, float angle, bool hFlip, bool vFlip) { RotateFlipType[,] arrRTF = new RotateFlipType[,] { // 不进行翻转的 水平翻转 垂直翻转 水平翻转和垂直翻转 { RotateFlipType.RotateNoneFlipNone, RotateFlipType.RotateNoneFlipX, RotateFlipType.RotateNoneFlipY, RotateFlipType.RotateNoneFlipXY }, // 0 度旋转 { RotateFlipType.Rotate90FlipNone, RotateFlipType.Rotate90FlipX, RotateFlipType.Rotate90FlipY, RotateFlipType.Rotate90FlipXY }, //90 度旋转 { RotateFlipType.Rotate180FlipNone, RotateFlipType.Rotate180FlipX, RotateFlipType.Rotate180FlipY, RotateFlipType.Rotate180FlipXY }, //180度旋转 { RotateFlipType.Rotate270FlipNone, RotateFlipType.Rotate270FlipX, RotateFlipType.Rotate270FlipY, RotateFlipType.Rotate270FlipXY }};//270度旋转 int dimAngle = -1; if (angle == 0) dimAngle = 0; else if (angle == 90) dimAngle = 1; else if (angle == 180) dimAngle = 2; else if (angle == 270) dimAngle = 3; if (dimAngle >= 0) { img.RotateFlip(arrRTF[dimAngle, (hFlip ? 1 : 0) + (vFlip ? 2 : 0)]); return img; } else { int w = img.Width + 2; int h = img.Height + 2; PixelFormat pf = PixelFormat.Format32bppArgb; Bitmap tmp = new Bitmap(w, h, pf); Graphics g = Graphics.FromImage(tmp); g.Clear(Color.Transparent); g.DrawImageUnscaled(img, 1, 1); g.Dispose(); GraphicsPath path = new GraphicsPath(); path.AddRectangle(new RectangleF(0f, 0f, w, h)); Matrix mtrx = new Matrix(); mtrx.Rotate(angle); RectangleF rct = path.GetBounds(mtrx); Bitmap dst = new Bitmap((int)rct.Width, (int)rct.Height, pf); g = Graphics.FromImage(dst); g.Clear(Color.Transparent); g.TranslateTransform(-rct.X, -rct.Y); g.RotateTransform(angle); g.InterpolationMode = InterpolationMode.HighQualityBilinear; g.DrawImageUnscaled(tmp, 0, 0); g.Dispose(); tmp.Dispose(); return dst; } } #endregion #region "Color change" /// <summary> /// 灰度化一个图片 /// </summary> /// <param name="img"></param> /// <returns></returns> public static Image Gray(Image img) { Bitmap result = img.Clone() as Bitmap; Rectangle rect = new Rectangle(0, 0, result.Width, result.Height); BitmapData bmpdata = result.LockBits(rect, ImageLockMode.ReadWrite, result.PixelFormat); byte temp; unsafe { byte* ptr = (byte*)(bmpdata.Scan0); for (int x = 0; x < bmpdata.Width; x++) { for (int y = 0; y < bmpdata.Height; y++) { temp = (byte)(0.299 * ptr[2] + 0.587 * ptr[1] + 0.114 * ptr[0]); ptr[0] = ptr[1] = ptr[2] = temp; ptr += 3; } ptr += bmpdata.Stride - bmpdata.Width * 3; } } result.UnlockBits(bmpdata); return result as Image; } /// <summary> /// 本函数完成的功能是图像颜色的翻转,实现的方法即用255减去图像中的每个象素点的值,并将所得值设置为原象素点处的值,对每个象素点进行如此的操作,只到整幅图像都处理完毕。 /// </summary> /// <param name="bmp"></param> /// <returns>函数执行成功,最后返回true值</returns> public static Image Invert(Image img) { Bitmap bmp = new Bitmap(img); BitmapData bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); int stride = bmData.Stride; System.IntPtr Scan0 = bmData.Scan0; unsafe { byte* p = (byte*)(void*)Scan0; int nOffset = stride - bmp.Width * 3; int nWidth = bmp.Width * 3; for (int y = 0; y < bmp.Height; ++y) { for (int x = 0; x < nWidth; ++x) { p[0] = (byte)(255 - p[0]); ++p; } p += nOffset; } } bmp.UnlockBits(bmData); return bmp; } /// <summary> /// 本函数完成的功能是对图像进行增亮处理。在取得了增亮参数后,函数的unsafe代码部分对每个象素点的不同颜色成分进行逐个处理,即在原来值的基础上加上一个增亮参数以获得新的值。同时代码中还有一个防止成分值越界的操作,因为RGB成分值的范围为0~255,一旦超过了这个范围就要重新设置。 /// </summary> /// <param name="bmp"></param> /// <param name="nBrightness">增亮参数,范围为-255~255</param> /// <returns>函数最后执行成功后,同样得返回true值。</returns> public static Image Brightness(Image img, int nBrightness) { Bitmap bmp = new Bitmap(img); if (nBrightness < -255 || nBrightness > 255) return img; BitmapData bmData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); int stride = bmData.Stride; System.IntPtr Scan0 = bmData.Scan0; int nVal = 0; unsafe { byte* p = (byte*)(void*)Scan0; int nOffset = stride - bmp.Width * 3; int nWidth = bmp.Width * 3; for (int y = 0; y < bmp.Height; ++y) { for (int x = 0; x < nWidth; ++x) { nVal = (int)(p[0] + nBrightness); if (nVal < 0) nVal = 0; if (nVal > 255) nVal = 255; p[0] = (byte)nVal; ++p; } p += nOffset; } } bmp.UnlockBits(bmData); return bmp; } /// <summary> /// 以浮雕效果显示图像 /// </summary> /// <param name="img"></param> /// <returns></returns> public static Image Anaglyph(Image img) { Bitmap newBitmap = new Bitmap(img); Bitmap oldBitmap = (Bitmap)img; Color pixel1, pixel2; for (int x = 0; x < img.Width - 1; x++) { for (int y = 0; y < img.Height - 1; y++) { int r = 0, g = 0, b = 0; pixel1 = oldBitmap.GetPixel(x, y); pixel2 = oldBitmap.GetPixel(x + 1, y + 1); r = Math.Abs(pixel1.R - pixel2.R + 128); g = Math.Abs(pixel1.G - pixel2.G + 128); b = Math.Abs(pixel1.B - pixel2.B + 128); if (r > 255) r = 255; if (r < 0) r = 0; if (g > 255) g = 255; if (g < 0) g = 0; if (b > 255) b = 255; if (b < 0) b = 0; newBitmap.SetPixel(x, y, Color.FromArgb(r, g, b)); } } return newBitmap; } /// <summary> /// 以柔化效果显示图像 /// </summary> /// <param name="img"></param> /// <returns></returns> public static Image Soften(Image img) { Bitmap bitmap = new Bitmap(img); Bitmap MyBitmap = (Bitmap)img; Color pixel; //高斯模板 int[] Gauss = { 1, 2, 1, 2, 4, 2, 1, 2, 1 }; for (int x = 1; x < img.Width - 1; x++) for (int y = 1; y < img.Height - 1; y++) { int r = 0, g = 0, b = 0; int Index = 0; for (int col = -1; col <= 1; col++) for (int row = -1; row <= 1; row++) { pixel = MyBitmap.GetPixel(x + row, y + col); r += pixel.R * Gauss[Index]; g += pixel.G * Gauss[Index]; b += pixel.B * Gauss[Index]; Index++; } r /= 16; g /= 16; b /= 16; //处理颜色值溢出 r = r > 255 ? 255 : r; r = r < 0 ? 0 : r; g = g > 255 ? 255 : g; g = g < 0 ? 0 : g; b = b > 255 ? 255 : b; b = b < 0 ? 0 : b; bitmap.SetPixel(x - 1, y - 1, Color.FromArgb(r, g, b)); } return bitmap; } /// <summary> /// 以锐化效果显示图像 /// </summary> /// <param name="img"></param> /// <returns></returns> public static Image Sharpen(Image img) { Bitmap newBitmap = new Bitmap(img); Bitmap oldBitmap = (Bitmap)img; Color pixel; //拉普拉斯模板 int[] Laplacian = { -1, -1, -1, -1, 9, -1, -1, -1, -1 }; for (int x = 1; x < img.Width - 1; x++) for (int y = 1; y < img.Height - 1; y++) { int r = 0, g = 0, b = 0; int Index = 0; for (int col = -1; col <= 1; col++) for (int row = -1; row <= 1; row++) { pixel = oldBitmap.GetPixel(x + row, y + col); r += pixel.R * Laplacian[Index]; g += pixel.G * Laplacian[Index]; b += pixel.B * Laplacian[Index]; Index++; } //处理颜色值溢出 r = r > 255 ? 255 : r; r = r < 0 ? 0 : r; g = g > 255 ? 255 : g; g = g < 0 ? 0 : g; b = b > 255 ? 255 : b; b = b < 0 ? 0 : b; newBitmap.SetPixel(x - 1, y - 1, Color.FromArgb(r, g, b)); } return newBitmap; } #endregion #region "水印处理" /// <summary> /// 添加文字行水印,位置在1/3处,横向铺满 /// </summary> /// <param name="img">图像</param> /// <param name="watermarkText">水印文字</param> /// <param name="fontName">水印字体,为null或空时默认为“宋体”</param> /// <param name="fontSize">水印字体大小,小于零时,默认大小为50</param> /// <returns></returns> public static Image WaterMark(Image img, string watermarkText, string fontName, int fontSize) { Bitmap bmp = new Bitmap(img); using (System.Drawing.Graphics gWater = System.Drawing.Graphics.FromImage(bmp)) { if (fontName == null || fontName == "") fontName = "宋体"; if (fontSize < 1) fontSize = 50; System.Drawing.Font fontWater = new Font(fontName, 50); System.Drawing.Brush brushWater = new SolidBrush(Color.FromArgb(50, Color.Gray)); string waterStr = watermarkText + " "; SizeF sz = gWater.MeasureString(waterStr, fontWater); for (int i = 0; i < img.Width / sz.Width; i++) waterStr += watermarkText + " "; gWater.DrawString(waterStr, fontWater, brushWater, 0, img.Height/3); gWater.Dispose(); } return bmp; } /// <summary> /// 添加图像水印,中间区域横向铺满 /// </summary> /// <param name="img">原图像</param> /// <param name="waterImage">水印图像</param> /// <returns></returns> public static Image WaterMark(Image img, Image waterImage) { Bitmap bmp = new Bitmap(img); Graphics gWater = Graphics.FromImage(bmp); //透明属性 ImageAttributes imgAttributes = new ImageAttributes(); ColorMap colorMap = new ColorMap(); colorMap.OldColor = Color.FromArgb(255, 0, 255, 0); colorMap.NewColor = Color.FromArgb(0, 0, 0, 0); ColorMap[] remapTable = { colorMap }; imgAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap); float[][] colorMatrixElements = { new float[] {1.0f, 0.0f, 0.0f, 0.0f, 0.0f}, new float[] {0.0f, 1.0f, 0.0f, 0.0f, 0.0f}, new float[] {0.0f, 0.0f, 1.0f, 0.0f, 0.0f}, new float[] {0.0f, 0.0f, 0.0f, 0.3f, 0.0f},//透明度:0.5 new float[] {0.0f, 0.0f, 0.0f, 0.0f, 1.0f} }; ColorMatrix wmColorMatrix = new ColorMatrix(colorMatrixElements); imgAttributes.SetColorMatrix(wmColorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); int xOffset = 0; do { gWater.DrawImage(waterImage, new Rectangle(xOffset, (bmp.Height - waterImage.Height)/2, waterImage.Width, waterImage.Height), 0, 0, waterImage.Width, waterImage.Height, GraphicsUnit.Pixel, imgAttributes); xOffset += waterImage.Width; } while (bmp.Width > xOffset); gWater.Dispose(); return bmp; } #endregion } }