日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C#通用模块专题

發布時間:2023/12/20 C# 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#通用模块专题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

開源

程序設計

常用組件

  加載圖片,播放音樂、視頻,攝像頭拍照

  文件讀寫(txt、xml、自定義文件格式(后綴名))

?

串口通信

穩定的串口讀寫:http://blog.csdn.net/kolvin2008/article/details/52833480

窗口通信類SerialPort:https://www.cnblogs.com/BookCode/p/5583853.html

用C#一步步寫串口通信:http://blog.csdn.net/kasama1953/article/details/51434295

?

在win10環境下開發uwp程序,在調用bluetooth的API的時候出現問題

原帖地址:https://bbs.csdn.net/topics/392034336?locationNum=13&fps=1

藍牙開發

用C#在windows上操控電腦自帶藍牙(入道指南)

原文地址:http://blog.csdn.net/yssjz960427031/article/details/50990372

前言

如題,如果你也想用C#在windows上操控電腦自帶藍牙,但是,不知從何下手,那就該看看這篇文章——這篇文章將帶領你入道。也正是這樣,這篇文章的主要內容是介紹操控藍牙所需的支持庫,以及從哪里下載最新版的支持庫,并教你如何自學與藍牙開發相關的更多知識等。本文涵蓋了經典藍牙(藍牙2.0版本)和低功耗藍牙(即BLE,藍牙4.0版本)。


正文

有過一定編程經驗的人都知道,要想操控某個平臺上的一個硬件,第一件事就是搞清楚這個系統平臺提供了哪些與該硬件相關的API給開發者用,或者,操控該硬件的第三方支持庫有哪些。找到這些是第一步,也是最關鍵的一步。就像治病,首先要找到能治這個病的藥,然后找到藥的說明書,照著說明書“按時按量吃藥治病”——做了個比較形象的比喻。之于開發人員,在找到支持庫后,就該去找支持庫作者提供的使用指南,然后按照使用指南學習使用這個支持庫。那么,針對“不知道如何操控Windows上的藍牙”這個病該用哪味藥呢?——藥就是這篇文章啦。現在就來按照說明書吃藥啦。?
下面分別介紹經典藍牙和BLE相關的支持庫。


經典藍牙

稍微用諸如“C# 藍牙”這樣的關鍵詞百度、Google下,就會發現InTheHand.Net.Personal.dll這個支持庫,對!操控經典藍牙就用這個。

簡要介紹

InTheHand.Net.Personal.dll這個支持庫是In The Hand公司下32FEET.NET這個項目的成果。該公司由Peter Foot創辦,注冊在英國。下文貼一張摘自官網的照片——看!就是這么帥,這才是男神級別的人物!?

可通過如下鏈接了解更多的信息:

  • In The Hand官網
  • 官網中對32FEET.NET項目的介紹
  • 32FEET.NET項目的源碼托管地址

當給出了如上三個鏈接后,尤其是第三個,這部分的重點內容基本都講完了。因為在“32FEET.NET項目的源碼托管地址”這個頁面中,就可以下載到最新版本的InTheHand.Net.Personal.dll這個支持庫,也有這個庫的使用指南,如下圖所示:?

下載支持庫

說了這么多,這有個重點:生活在天朝,由于墻的存在,我們錯過了很多人間的精彩。所以,你懂了……我為大家下載了最新的(2016.3.20下載) .Net 3.5和 .Net 3.7版本的InTheHand.Net.Personal.dll,你可從如下地址下載,里面附有簡要的使用說明,使用零門檻:

  • CSDN下載:C#藍牙編程開源庫_InTheHand.Net.Personal.dll
  • 百度云盤下載:InTheHand.Net.Personal

使用示例

具體使用可參照官方的指導文檔,也可以看看相關的博客,下面僅以我寫過的控制筆記本電腦藍牙來開門的代碼演示下,要特別注意我在下邊代碼的注釋中提到的3個注意——我是從這些坑中爬出來的有經驗的人。

using System; using System.IO; using System.Net.Sockets; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; // [注意1]:要添加如下三個命名空間 using InTheHand.Net; using InTheHand.Net.Bluetooth; using InTheHand.Net.Sockets; namespace TestBluetooth { class Program { static void Main(string[] args) { BluetoothRadio bluetoothRadio = BluetoothRadio.PrimaryRadio; if (bluetoothRadio == null) { Console.WriteLine("沒有找到本機藍牙設備!"); } else { Program p = new Program(); p.localAdapterInfo(bluetoothRadio); p.openDoor(); } } /** * 連接目標藍牙設備發送開門指令 * **/ private void openDoor() { BluetoothClient cli = new BluetoothClient(); BluetoothAddress addr = null; BluetoothEndPoint ep = null; try { // [注意2]:要注意MAC地址中字節的對應關系,直接來看順序是相反的,例如 // 如下對應的MAC地址為——12:34:56:78:9a:bc addr = new BluetoothAddress(new byte[] { 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12 }); ep = new BluetoothEndPoint(addr, BluetoothService.SerialPort); cli.Connect(ep); // 連接藍牙 if (cli.Connected) { Stream peerStream = cli.GetStream(); peerStream.WriteByte(0xBB); // 發送開門指令 } } catch (SocketException e) { Console.WriteLine(e.Message); } finally { if (cli != null) { // [注意3]:要延遲一定時間(例如1000毫秒) //避免因連接后又迅速斷開而導致藍牙進入異常(傻逼)狀態 Thread.Sleep(1000); cli.Close(); } } } /** * * 顯示本地藍牙的信息 * * **/ private void localAdapterInfo(BluetoothRadio bluetoothRadio) { Console.WriteLine("ClassOfDevice: " + bluetoothRadio.ClassOfDevice); Console.WriteLine("HardwareStatus: " + bluetoothRadio.HardwareStatus); Console.WriteLine("HciRevision: " + bluetoothRadio.HciRevision); Console.WriteLine("HciVersion: " + bluetoothRadio.HciVersion); Console.WriteLine("LmpSubversion: " + bluetoothRadio.LmpSubversion); Console.WriteLine("LmpVersion: " + bluetoothRadio.LmpVersion); Console.WriteLine("LocalAddress: " + bluetoothRadio.LocalAddress); Console.WriteLine("Manufacturer: " + bluetoothRadio.Manufacturer); Console.WriteLine("Mode: " + bluetoothRadio.Mode); Console.WriteLine("Name: " + bluetoothRadio.Name); Console.WriteLine("Remote:" + bluetoothRadio.Remote); Console.WriteLine("SoftwareManufacturer: " + bluetoothRadio.SoftwareManufacturer); Console.WriteLine("StackFactory: " + bluetoothRadio.StackFactory); } } }


BLE

(PS:以下所述,都是假設你的筆記本上的藍牙是支持BLE特性的)?
畢竟智能硬件興起,還玩經典藍牙顯得有點Low。那么,問題來了,在電腦上可不可以使用BLE呢?答案是——可以!?
但是,有條件限制:只能在Windows 8、Windows 8.1、Windows 10上玩。這個消息也不算太壞哈。?
Q:為什么Windows 7上不能玩呢??
A:因為Windows 7及其以下的Windows操作系統中的藍牙協議棧不支持BLE特性。這就比如,你分明在你的筆記本上接了一臺帶掃描功能的打印機,但是你只能打印卻用不了掃描功能,因為你裝的驅動不支持掃描功能。電腦面對的是一臺既可以打印又可以掃描的的機器,但是就是不知道如何去控制它來進行掃描。同理,如果硬件支持了BLE(即藍牙4.0)特性,但是藍牙協議棧里缺少一些支持這些特性的內容,就沒得玩了。?
Q:那么,我可以裝個強大點的“驅動”么??
A:不可以,這個協議棧不同于一般的驅動,Windows的源碼是微軟老大哥一手掌控的,沒有源碼,我們裝不進去!?
Q:那么,真的就沒得完了么??
A:換系統唄,換成8及其以上的,一切妥妥的!?
想知道Windows系統對藍牙的具體支持情況,請點擊:General Bluetooth Support in Windows

BLE支持庫

  • 首先,InTheHand.Net.Personal.dll這個庫不支持BLE,因為,Windows系統有與BLE相關的API了,作者表示暫時沒有考慮在Windows的API上再包一層,詳情可見論壇的帖子:Bluetooth Low Energy Support,男神是這么回復的:?

    不過回復時間是2013.5.15,有點久遠了,最新的情況,有興趣的可以繼續一探究竟。
  • 使用Windows的提供API:詳情見Windows.Devices.Bluetooth.GenericAttributeProfile namespace?
    與Windows開發相關的“說明書”,可以從Windows開發者中心獲得。沿著這條路,你也可以直接走到與藍牙開發相關的部分:?
    Windows 開發者中心—>文檔—>應用—>API參考—>Windows運行時API?
    —> Windows.Devices.Bluetooth.GenericAttributeProfile namespace

溫馨提示

學習GATT協議是進行BLE開發的基礎,BLE的通訊方式和經典藍牙的通訊方式有很大的區別,要注意思維轉換,如果還是從Socket通訊的方式來學習BLE的話,可能會遇到麻煩。

結語

我用C#操作筆記本電腦的藍牙來開門也是出于興趣,上文正是記錄了我從當初的無處下爪到最后有成果這個過程中的經驗所得,記錄并將其分享出來,希望能夠給大家一些幫助、鼓勵甚至啟發,如果能通過我的文字讓別人不要走我走過的彎路,哪怕只有一個,也甚是欣慰了。

?

C#開發藍牙服務端,自動配對以及收發消息

地址:http://blog.csdn.net/oqzuser12345678923/article/details/51252545

目前.Net平臺最好用的藍牙庫是InTheHand.net,是由32feet.net提供的shared-source項目,提供短距離領域(personal area networking technologie)的通信功能,支持bluetooth,Infrared(IrDA)紅外等.

//啟動一個監聽線程 Thread listenThread = new Thread(ReceiveData); listenThread.IsBackground = true; listenThread.Start();//監聽方法 public void ReceiveData() { while (1 == 1) { try { Guid mGUID = Guid.Parse("db764ac8-4b08-7f25-aafe-59d03c27bae3"); bluetoothListener = new BluetoothListener(mGUID); bluetoothListener.Start(); bluetoothClient = bluetoothListener.AcceptBluetoothClient(); isConnected = true; while (isConnected) { if (bluetoothClient != null && bluetoothClient.Connected) { peerStream = bluetoothClient.GetStream(); } else { break; } byte[] buffer = new byte[100]; peerStream.Read(buffer, 0, 100); receive = Encoding.UTF8.GetString(buffer).ToString(); if (receive == temp) { isConnected = false; } Console.WriteLine(receive + "receiveMsg"); } bluetoothListener.Stop(); bluetoothClient = null; } catch (Exception ex) { Console.Write(ex.Message); } } }

?

兩個while循環是因為我的安卓app沒法修改,沒有做斷開處理,所以強行在服務端斷開了。?
如果你藍牙連接著的,并且和電腦配對上了,那用這個方法是可以接受消息的。

那么現在問題來了。

我的windows主機是沒有輸出設備的,木有顯示器,而藍牙配對有3中方法,其中justwork表示不驗證,直接配對,但是客戶端代碼動不了,inTheHand.net也沒有找到怎么設置配對模式。

最后找到藍牙配對PING碼確認的事件,直接把事件注冊后,響應通過就行了。

EventHandler<BluetoothWin32AuthenticationEventArgs> handler = new EventHandler<BluetoothWin32AuthenticationEventArgs>(this.handleRequests);BluetoothWin32Authentication authenticator = new BluetoothWin32Authentication(handler);public void handleRequests(Object thing, BluetoothWin32AuthenticationEventArgs args) { args.Confirm = true; }

?

?

異步回調

下面是一個異步回調的例子,主要是發出Post請求,等收到Post請求結果后調用回調方法Done顯示收到的結果。

命名空間

?

using System.Runtime.Remoting.Messaging;

?

public delegate string PostHandler(string url, string parame);private void SendPost(string url, string fileName){try{string paramData = string.Empty;if (!string.IsNullOrEmpty(fileName)){using (StreamReader sr = new StreamReader(fileName, Encoding.Default)){paramData = sr.ReadToEnd().Trim();}}PostHandler postHandler = new PostHandler(Post);IAsyncResult result = postHandler.BeginInvoke(url, paramData, new AsyncCallback(Done), postHandler);}catch (Exception ex){MessageBox.Show("出錯!異常為:" + ex.Message);}}public void Done(IAsyncResult result) {PostHandler handler = (PostHandler)((AsyncResult)result).AsyncDelegate;string resultStr = handler.EndInvoke(result);if (!string.IsNullOrEmpty(resultStr)){DisplayResult(resultStr);}else{DisplayResult("未收到結果,請重新發送!");}MessageBox.Show("收到結果!");}private void DisplayResult(string result){if (this.InvokeRequired){this.Invoke(new MethodInvoker(delegate(){DisplayResult(result);}));}else{textBox_Result.Text = result;}}//public CookieContainer CookieContainer { get; set; }private string Post(string postUrl, string paramData){string result = string.Empty;Stream stream = null;StreamReader sr = null;HttpWebResponse response = null;try{byte[] byteArray = Encoding.UTF8.GetBytes(paramData);HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(new Uri(postUrl));webReq.Method = "POST";webReq.ContentType = "application/json; charset=utf-8";//webReq.ContentType = "application/x-www-form-urlencoded";webReq.Accept = "text/json"; //"image/jpeg, application/x-ms-application, image/gif, application/xaml+xml, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*";webReq.UserAgent = "valwell.com/1.0";webReq.ContentLength = byteArray.Length;webReq.ServicePoint.Expect100Continue = false;//webReq.CookieContainer = CookieContainer;stream = webReq.GetRequestStream();stream.Write(byteArray, 0, byteArray.Length);response = (HttpWebResponse)webReq.GetResponse();if (response.StatusCode == HttpStatusCode.OK){//response.Cookies = CookieContainer.GetCookies(webReq.RequestUri);sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);result = sr.ReadToEnd();}else{Debug.WriteLine(response.StatusCode);}}catch (Exception ex){string exMessage = ex.Message;}finally{if (sr != null){sr.Close();}if (response != null){response.Close();}if (stream != null){stream.Close();}}return result;}/// <summary>/// 設置是否允許不安全的連接/// </summary>/// <param name="useUnsafe"></param>/// <returns></returns>public static bool SetAllowUnsafeHeaderParsing20(bool useUnsafe){//Get the assembly that contains the internal classSystem.Reflection.Assembly aNetAssembly = System.Reflection.Assembly.GetAssembly(typeof(System.Net.Configuration.SettingsSection));if (aNetAssembly != null){//Use the assembly in order to get the internal type for the internal classType aSettingsType = aNetAssembly.GetType("System.Net.Configuration.SettingsSectionInternal");if (aSettingsType != null){//Use the internal static property to get an instance of the internal settings class.//If the static instance isn't created allready the property will create it for us.object anInstance = aSettingsType.InvokeMember("Section",System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.GetProperty | System.Reflection.BindingFlags.NonPublic, null, null, new object[] { });if (anInstance != null){//Locate the private bool field that tells the framework is unsafe header parsing should be allowed or notSystem.Reflection.FieldInfo aUseUnsafeHeaderParsing = aSettingsType.GetField("useUnsafeHeaderParsing", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);if (aUseUnsafeHeaderParsing != null){aUseUnsafeHeaderParsing.SetValue(anInstance, useUnsafe);return true;}}}}return false;}

?

?

C#使用Log4Net記錄日志

參考文檔網址:

1、http://www.cnblogs.com/wangsaiming/archive/2013/01/11/2856253.html

2、http://www.cnblogs.com/jys509/p/4569874.html

3、http://zhoufoxcn.blog.51cto.com/792419/429988/

4、http://blog.csdn.net/suixufeng/article/details/50259617

有時間自己再寫一篇專門的文檔

?

?

?

文件讀寫

一、獲取路徑

1.獲取和設置當前目錄的完全限定路徑。 string str = System.Environment.CurrentDirectory;?
Result: C:\xxx\xxx

2.獲取啟動了應用程序的可執行文件的路徑,不包括可執行文件的名稱。 string str = System.Windows.Forms.Application.StartupPath; Result: C:\xxx\xxx

3.獲取新的 Process 組件并將其與當前活動的進程關聯的主模塊的完整路徑,包含文件名。 string str = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName; Result: C:\xxx\xxx\xxx.exe

4.獲取當前 Thread 的當前應用程序域的基目錄,它由程序集沖突解決程序用來探測程序集。 string str = System.AppDomain.CurrentDomain.BaseDirectory; Result: C:\xxx\xxx\

5.獲取應用程序的當前工作目錄。 string str = System.IO.Directory.GetCurrentDirectory();?
Result: C:\xxx\xxx

6.獲取和設置包含該應用程序的目錄的名稱。 string str = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase; Result: C:\xxx\xxx\

7.獲取當前進程的完整路徑,包含文件名。 string str = this.GetType().Assembly.Location;?
Result: C:\xxx\xxx\xxx.exe

8.獲取啟動了應用程序的可執行文件的路徑,包括可執行文件的名稱。 string str = System.Windows.Forms.Application.ExecutablePath; Result: C:\xxx\xxx\xxx.exe

?

二、目錄與文件(Directory類和File類)

下面是一個例子,原文地址http://www.cnblogs.com/szytwo/archive/2012/03/22/2411703.html

protected void Button1_Click(object sender, EventArgs e)
{

if (Directory.Exists(Server.MapPath("~/upimg/hufu")) == false)//如果不存在就創建file文件夾
{
Directory.CreateDirectory(Server.MapPath("~/upimg/hufu"));
}

//Directory.Delete(Server.MapPath("~/upimg/hufu"), true);//刪除文件夾以及文件夾中的子目錄,文件

//判斷文件的存在

if (File.Exists(Server.MapPath("~/upimg/Data.html")))
{
Response.Write("Yes");

//存在文件

}

else
{
Response.Write("No");
//不存在文件
File.Create(MapPath("~/upimg/Data.html"));//創建該文件

}

string name = GetFiles.FileName;//獲取已上傳文件的名字
string size = GetFiles.PostedFile.ContentLength.ToString();//獲取已上傳文件的大小
string type = GetFiles.PostedFile.ContentType;//獲取已上傳文件的MIME
string postfix = name.Substring(name.LastIndexOf(".") + 1);//獲取已上傳文件的后綴
string ipath = Server.MapPath("upimg") +"\\"+ name;//獲取文件的實際路徑
string fpath = Server.MapPath("upfile") + "\\" + name;
string dpath = "upimg\\" + name;//判斷寫入數據庫的虛擬路徑

ShowPic.Visible = true;//激活
ShowText.Visible = true;//激活

//判斷文件格式
if (name == "") {
Response.Write("<script>alert('上傳文件不能為空')</script>");
}

else{

if (postfix == "jpg" || postfix == "gif" || postfix == "bmp" || postfix == "png")
{
GetFiles.SaveAs(ipath);
ShowPic.ImageUrl = dpath;
ShowText.Text = "你上傳的圖片名稱是:" + name + "<br>" + "文件大小:" + size + "KB" + "<br>" + "文件類型:" + type + "<br>" + "存放的實際路徑為:" + ipath;

}

else
{
ShowPic.Visible = false;//隱藏圖片
GetFiles.SaveAs(fpath);//由于不是圖片文件,因此轉存在upfile這個文件夾
ShowText.Text = "你上傳的文件名稱是:" + name + "<br>" + "文件大小:" + size + "KB" + "<br>" + "文件類型:" + type + "<br>" + "存放的實際路徑為:" + fpath;

}

?

三、文件的讀寫

C#對文本文件的幾張讀寫方法總結,原文地址http://www.cr173.com/html/18141_1.html

? ? ? 計算機在最初只支持ASCII編碼,但是后來為了支持其他語言中的字符(比如漢字)以及一些特殊字符(比如€),就引入了Unicode字符集。基于Unicode字符集的編碼方式有很多,比如UTF-7、UTF-8、Unicode以及UTF-32。在Windows操作系統中,一個文本文件的前幾個字節是用來指定該文件的編碼方式的。

如果你使用NotePad或WordPad來打開一個文本文件,你并不用擔心該文件的編碼方式,因為這些應用程序會先讀取文件的前幾個字節來確定該文件的編碼方式,然后用正確的編碼將文本中的每個字符顯示出來。下面的圖中,可以看到當用NotePad記事本保存一個文檔時,可以選擇的編碼(Encoding)方式有哪些。

用.Net讀取文本文件或寫入文本文件,你都不須要擔心編碼方式。.Net已經將這些封裝好了。在讀取一個文本文件的時候,如果你已經知道文本使用的是什么編碼方式,你可以指定使用哪種編碼方式讀取文本,否則如果不指定編碼方式,.Net會讀取文本的前幾個字節來確定使用哪種編碼方式讀取文件內容的。在寫入文本文件的時候,你也可以指定你想使用的編碼方式。如果你沒有指定編碼,.Net會根據寫入的文本是否含有特殊字符來決定編碼方式。如果沒有特殊字符,就采用ASCII編碼,如果有特殊字符,就采用UTF-8編碼。

(一) 讀取文件

如果你要讀取的文件內容不是很多,可以使用 File.ReadAllText(FilePath) 或指定編碼方式 File.ReadAllText(FilePath, Encoding)的方法。

它們都一次將文本內容全部讀完,并返回一個包含全部文本內容的字符串
string str = File.ReadAllText(@"c:\temp\ascii.txt");

// 也可以指定編碼方式?
string str2 = File.ReadAllText(@"c:\temp\ascii.txt", Encoding.ASCII);

也可以使用方法File.ReadAllLines。該方法返回一個字符串數組。每一行都是一個數組元素。

string[] strs = File.ReadAllLines(@"c:\temp\ascii.txt");?

// 也可以指定編碼方式?
string[] strs2 = File.ReadAllLines(@"c:\temp\ascii.txt", Encoding.ASCII);

當文本的內容比較大時,我們就不要將文本內容一次讀完,而應該采用流(Stream)的方式來讀取內容。.Net為我們封裝了StreamReader類。初始化StreamReader類有很多種方式。下面我羅列出幾種

StreamReader sr1 = new StreamReader(@"c:\temp\utf-8.txt");?
// 同樣也可以指定編碼方式?
StreamReader sr2 = new StreamReader(@"c:\temp\utf-8.txt", Encoding.UTF8);

FileStream fs = new FileStream(@"C:\temp\utf-8.txt", FileMode.Open, FileAccess.Read, FileShare.None);?
StreamReader sr3 = new StreamReader(fs);?
StreamReader sr4 = new StreamReader(fs, Encoding.UTF8);

FileInfo myFile = new FileInfo(@"C:\temp\utf-8.txt");?
// OpenText 創建一個UTF-8 編碼的StreamReader對象?
StreamReader sr5 = myFile.OpenText();

// OpenText 創建一個UTF-8 編碼的StreamReader對象?
StreamReader sr6 = File.OpenText(@"C:\temp\utf-8.txt");

初始化完成之后,你可以每次讀一行,也可以每次讀一個字符 ,還可以每次讀幾個字符,甚至也可以一次將所有內容讀完。

// 讀一行?
string nextLine = sr.ReadLine();

// 讀一個字符?
int nextChar = sr.Read();

// 讀100個字符?
int nChars = 100;?
char[] charArray = new char[nChars];?
int nCharsRead = sr.Read(charArray, 0, nChars);??????
??????
// 全部讀完?
string restOfStream = sr.ReadToEnd();

使用完StreamReader之后,不要忘記關閉它: sr.Closee();

假如我們需要一行一行的讀,將整個文本文件讀完,下面看一個完整的例子:

StreamReader sr = File.OpenText(@"C:\temp\ascii.txt");?
string nextLine;?
while ((nextLine = sr.ReadLine()) != null)?
{?
??? Console.WriteLine(nextLine);?
}?
sr.Close();

(二) 寫入文件

寫文件和讀文件一樣,如果你要寫入的內容不是很多,可以使用File.WriteAllText方法來一次將內容全部寫如文件。如果你要將一個字符串的內容寫入文件,可以用File.WriteAllText(FilePath) 或指定編碼方式 File.WriteAllText(FilePath, Encoding)方法。

string str1 = "Good Morning!"; File.WriteAllText(@"c:\temp\test\ascii.txt", str1); // 也可以指定編碼方式 File.WriteAllText(@"c:\temp\test\ascii-2.txt", str1, Encoding.ASCII);

如果你有一個字符串數組,你要將每個字符串元素都寫入文件中,可以用File.WriteAllLines方法:

string[] strs = { "Good Morning!", "Good Afternoon!" }; File.WriteAllLines(@"c:\temp\ascii.txt", strs); File.WriteAllLines(@"c:\temp\ascii-2.txt", strs, Encoding.ASCII);

使用File.WriteAllText或File.WriteAllLines方法時,如果指定的文件路徑不存在,會創建一個新文件;如果文件已經存在,則會覆蓋原文件。

當要寫入的內容比較多時,同樣也要使用流(Stream)的方式寫入。.Net封裝的類是StreamWriter。初始化StreamWriter類同樣有很多方式:

// 如果文件不存在,創建文件; 如果存在,覆蓋文件?
StreamWriter sw1 = new StreamWriter(@"c:\temp\utf-8.txt");?

// 也可以指定編碼方式?
// true 是 append text, false 為覆蓋原文件?
StreamWriter sw2 = new StreamWriter(@"c:\temp\utf-8.txt", true, Encoding.UTF8);

// FileMode.CreateNew: 如果文件不存在,創建文件;如果文件已經存在,拋出異常?
FileStream fs = new FileStream(@"C:\temp\utf-8.txt", FileMode.CreateNew, FileAccess.Write, FileShare.Read);?
// UTF-8 為默認編碼?
StreamWriter sw3 = new StreamWriter(fs);?
StreamWriter sw4 = new StreamWriter(fs, Encoding.UTF8);

// 如果文件不存在,創建文件; 如果存在,覆蓋文件?
FileInfo myFile = new FileInfo(@"C:\temp\utf-8.txt");?
StreamWriter sw5 = myFile.CreateText();

初始化完成后,可以用StreamWriter對象一次寫入一行,一個字符,一個字符數組,甚至一個字符數組的一部分。

// 寫一個字符????????????
sw.Write('a');

// 寫一個字符數組?
char[] charArray = new char[100];?
// initialize these characters?
sw.Write(charArray);

// 寫一個字符數組的一部分?
sw.Write(charArray, 10, 15);

同樣,StreamWriter對象使用完后,不要忘記關閉。sw.Close(); 最后來看一個完整的使用StreamWriter一次寫入一行的例子:

FileInfo myFile = new FileInfo(@"C:\temp\utf-8.txt");?
StreamWriter sw = myFile.CreateText();

string[] strs = { "早上好", "下午好" };????????????
foreach (var s in strs)?
{?
??? sw.WriteLine(s);?
}?
sw.Close();

?

寫入文本文件例子

class WriteTextFile
{
static void Main()
{
//如果文件不存在,則創建;存在則覆蓋
//該方法寫入字符數組換行顯示
string[] lines = { "first line", "second line", "third line","第四行" };
System.IO.File.WriteAllLines(@"C:\testDir\test.txt", lines, Encoding.UTF8);

//如果文件不存在,則創建;存在則覆蓋
string strTest = "該例子測試一個字符串寫入文本文件。";
System.IO.File.WriteAllText(@"C:\testDir\test1.txt", strTest, Encoding.UTF8);

//在將文本寫入文件前,處理文本行
//StreamWriter一個參數默認覆蓋
//StreamWriter第二個參數為false覆蓋現有文件,為true則把文本追加到文件末尾
using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\testDir\test2.txt",true))
{
foreach (string line in lines)
{
if (!line.Contains("second"))
{
file.Write(line);//直接追加文件末尾,不換行
file.WriteLine(line);// 直接追加文件末尾,換行?
}
}
}
}
}

讀取文本文件例子

class ReadTextFile
{
static void Main()
{
//直接讀取出字符串
string text = System.IO.File.ReadAllText(@"C:\testDir\test1.txt");
Console.WriteLine(text);

//按行讀取為字符串數組
string[] lines = System.IO.File.ReadAllLines(@"C:\testDir\test.txt");
foreach (string line in lines)
{
Console.WriteLine(line);
}

//從頭到尾以流的方式讀出文本文件
//該方法會一行一行讀出文本
using (System.IO.StreamReader sr = new System.IO.StreamReader(@"C:\testDir\test.txt"))
{
string str;
while ((str = sr.ReadLine()) != null)
{
Console.WriteLine(str);
}
}
Console.Read();
}
}

?

四、注冊自定義文件類型

原文地址:http://blog.csdn.net/jiutao_tang/article/details/6563646

事實上有三種方式可以實現文件類型的注冊,筆者在網上看到的都是手動實現的或程序實現的,其實也可以直接在工程屬性里進行設置。

1. 工程屬性定義

項目--->工程屬性--->發布--->選項--->文件關聯--->設置擴展名、說明、ProgID(自定義)、圖標即可。

?

2. 手工實現文件類型關聯

每一個文件類型的信息被保存在注冊表中的 'HKEY_CLASSES_ROOT'下面。假設我們自定義的文件類型的后綴為.hyp,文件名為Test_File_Hype (中間不能有空格).

首先在HKEY_CLASSES_ROOT下創建 .hyp
HKEY_CLASSES_ROOT/.hyp

?

將[默認]鍵值改為"Test_File_Hype"。然后在HKEY_CLASSES_ROOT下添加主鍵 Test_File_Hype
HKEY_CLASSES_ROOT/Test_File_Hype

按照下面的路徑添加新的主鍵?
HKEY_CLASSES_ROOT/Test_File_Hype/Shell
HKEY_CLASSES_ROOT/Test_File_Hype/Shell/Open
HKEY_CLASSES_ROOT/Test_File_Hype/Shell/Open/Command

將下面的字符作為Command的鍵值
???? your application path.exe %1
???? (例如 C:/WINDOWS/HYP/HYP.EXE %1)

或許你還想為自己的文件類型加上同自己的執行文件一樣的圖標,很簡單,照下面的方法添加就行了。
HKEY_CLASSES_ROOT/Test_File_Hype/DefaultIcon
輸入鍵值:
???? your application path.EXE,0
后面的零表示文件的圖標同程序的主圖標一致,如果你的程序有很多圖標,換一換數字就可改變文件顯

參考:http://www.codesky.net/article/doc/200308/2003082482622669.htm

?

3.? C#編程實現自定義文件類型關聯應用程序

在我們自己編寫的應用中,經常會用自定義類型的文件的來保存與應用相關的數據,比如.xcf文件就是XCodeFactory應用程序的項目文件。如果沒 有向Windows注冊表注冊該文件類型,那么.xcf文件的圖標將是windows的文件默認圖標,并且你雙擊一個a.xcf文件,也不會自動啟動 XCodeFactory應用程序來加載a.xcf文件。如何使.xcf文件的圖標變成我自己喜愛的圖標、如何完成像點擊.doc文件就自動打開word 程序的功能,下面將告訴你解決方案。?
????我們可以通過手動修改注冊表來完成上述任務,更好的方式是,通過程序來實現。這樣,在安裝應用程序時,就可以自動的注冊自定義文件類型 了。我通過FileTypeRegister靜態類來完成這些功能。首先,將注冊需要用到的信息封裝成FileTypeRegInfo,定義如下:

public class FileTypeRegInfo
{
/// <summary>
/// 目標類型文件的擴展名
/// </summary>
public string ExtendName; //".xcf"
/// <summary>
/// 目標文件類型說明
/// </summary>
public string Description; //"XCodeFactory項目文件"
/// <summary>
/// 目標類型文件關聯的圖標
/// </summary>
public string IcoPath;
/// <summary>
/// 打開目標類型文件的應用程序
/// </summary>
public string ExePath;
public FileTypeRegInfo()
{
}
public FileTypeRegInfo(string extendName)
{
this.ExtendName = extendName;
}
}

FileTypeRegister類主要是操作注冊表中的內容,實現如下:

/// <summary>
/// FileTypeRegister 用于注冊自定義的文件類型。
/// zhuweisky 2005.08.31
/// </summary>
public class FileTypeRegister
{
#region RegisterFileType
/// <summary>
/// RegisterFileType 使文件類型與對應的圖標及應用程序關聯起來。
/// </summary>?
public static void RegisterFileType(FileTypeRegInfo regInfo)
{
if (FileTypeRegistered(regInfo.ExtendName))
{
return;
}
string relationName = regInfo.ExtendName.Substring(1, regInfo.ExtendName.Length - 1).ToUpper() + "_FileType";
RegistryKey fileTypeKey = Registry.ClassesRoot.CreateSubKey(regInfo.ExtendName);
fileTypeKey.SetValue("", relationName);
fileTypeKey.Close();
RegistryKey relationKey = Registry.ClassesRoot.CreateSubKey(relationName);
relationKey.SetValue("", regInfo.Description);
RegistryKey iconKey = relationKey.CreateSubKey("DefaultIcon");
iconKey.SetValue("", regInfo.IcoPath);
RegistryKey shellKey = relationKey.CreateSubKey("Shell");
RegistryKey openKey = shellKey.CreateSubKey("Open");
RegistryKey commandKey = openKey.CreateSubKey("Command");
commandKey.SetValue("", regInfo.ExePath + " %1");
relationKey.Close();
}
/// <summary>
/// GetFileTypeRegInfo 得到指定文件類型關聯信息
/// </summary>?
public static FileTypeRegInfo GetFileTypeRegInfo(string extendName)
{
if (!FileTypeRegistered(extendName))
{
return null;
}
FileTypeRegInfo regInfo = new FileTypeRegInfo(extendName);
string relationName = extendName.Substring(1, extendName.Length - 1).ToUpper() + "_FileType";
RegistryKey relationKey = Registry.ClassesRoot.OpenSubKey(relationName);
regInfo.Description = relationKey.GetValue("").ToString();
RegistryKey iconKey = relationKey.OpenSubKey("DefaultIcon");
regInfo.IcoPath = iconKey.GetValue("").ToString();
RegistryKey shellKey = relationKey.OpenSubKey("Shell");
RegistryKey openKey = shellKey.OpenSubKey("Open");
RegistryKey commandKey = openKey.OpenSubKey("Command");
string temp = commandKey.GetValue("").ToString();
regInfo.ExePath = temp.Substring(0, temp.Length - 3);
return regInfo;
}
/// <summary>
/// UpdateFileTypeRegInfo 更新指定文件類型關聯信息
/// </summary>?
public static bool UpdateFileTypeRegInfo(FileTypeRegInfo regInfo)
{
if (!FileTypeRegistered(regInfo.ExtendName))
{
return false;
}

string extendName = regInfo.ExtendName;
string relationName = extendName.Substring(1, extendName.Length - 1).ToUpper() + "_FileType";
RegistryKey relationKey = Registry.ClassesRoot.OpenSubKey(relationName, true);
relationKey.SetValue("", regInfo.Description);
RegistryKey iconKey = relationKey.OpenSubKey("DefaultIcon", true);
iconKey.SetValue("", regInfo.IcoPath);
RegistryKey shellKey = relationKey.OpenSubKey("Shell");
RegistryKey openKey = shellKey.OpenSubKey("Open");
RegistryKey commandKey = openKey.OpenSubKey("Command", true);
commandKey.SetValue("", regInfo.ExePath + " %1");
relationKey.Close();
return true;
}
/// <summary>
/// FileTypeRegistered 指定文件類型是否已經注冊
/// </summary>?
public static bool FileTypeRegistered(string extendName)
{
RegistryKey softwareKey = Registry.ClassesRoot.OpenSubKey(extendName);
if (softwareKey != null)
{
return true;
}
return false;
}
#endregion
}

要注意的是commandKey.SetValue(""?,regInfo.ExePath?+?"?%1")?;其中"?%1"表示將被雙擊的文件的路徑傳給目標應用程序,這樣在雙擊a.xcf文件時,XCodeFactory才知道要打開哪個文件,所以應用程序的Main方法要被改寫為帶有參數的形式,就像下面的樣子:

[STAThread]
static void Main(string[] args)
{
if ((args != null) && (args.Length > 0))
{
string filePath = "";
for (int i = 0; i < args.Length; i++)
{
filePath += " " + args[i];
}
MainForm.XcfFilePath = filePath.Trim();
}
Application.Run(new MainForm());
}

關于自定義文件類型的注冊,本文實現的是最基本的功能,如果需要更多的高級功能,也可以類推實現之。

注:

(1)應用程序的Main方法在Program.cs文件中,可以把原來無參的main方法注釋掉;

(2)MainForm就是應用程序的啟動窗體,可以改為自己的

(3)filePath.Trim() 就是獲取的文件路徑了

(4)using Microsoft.Win32;? //RegistryKey 位于 Microsoft.Win32 命名空間

(5)注冊文件類型后,文件圖標可能并不會立即生效(需注銷登錄或重啟Explorer進程)。我們可以采取重啟Explorer進程的方式使之立即生效,可參考示例程序中的代碼。

?

我的一個實例:在Form_load事件中進行注冊:

private void Form1_Load(object sender, EventArgs e)
{
action = true;
if (!FileTypeRegister.FileTypeRegistered(".hd")) //如果文件類型沒有注冊,則進行注冊
{
FileTypeRegInfo fileTypeRegInfo = new FileTypeRegInfo(".hd"); //文件類型信息
fileTypeRegInfo.Description = "巷道支護系統工程文件";
fileTypeRegInfo.ExePath = Application.ExecutablePath;
fileTypeRegInfo.ExtendName = ".hd";
fileTypeRegInfo.IcoPath = Application.ExecutablePath; //文件圖標使用應用程序的
FileTypeRegister fileTypeRegister = new FileTypeRegister(); //注冊
FileTypeRegister.RegisterFileType(fileTypeRegInfo);

Process[] process = Process.GetProcesses(); //重啟Explorer進程,使更新立即生效
var p = (from proc in process
where proc.ProcessName.Equals("explorer")
select proc).FirstOrDefault();
p.Kill();
}
}

?

?

一、Random 生成不重復隨機數

轉自:http://www.cnblogs.com/huangfr/archive/2012/03/27/2420464.html

Random?類

命名空間:System

表示偽隨機數生成器,一種能夠產生滿足某些隨機性統計要求的數字序列的設備。

偽隨機數是以相同的概率從一組有限的數字中選取的。所選數字并不具有完全的隨機性,因為它們是用一種確定的數學算法選擇的,但是從實用的角度而言,其隨機程度已足夠了。

偽隨機數的生成是從種子值開始。如果反復使用同一個種子,就會生成相同的數字系列。產生不同序列的一種方法是使種子值與時間相關,從而對于 Random 的每個新實例,都會產生不同的系列。默認情況下,Random 類的無參數構造函數使用系統時鐘生成其種子值,而參數化構造函數可根據當前時間的計時周期數采用 Int32 值。但是,因為時鐘的分辨率有限,所以,如果使用無參數構造函數連續創建不同的 Random 對象,就會創建生成相同隨機數序列的隨機數生成器。

通過創建單個而不是多個 Random 對象可以避免此問題。

若要提高性能,請創建一個隨時間推移能生成多個隨機數的 Random 對象,而不要反復新建會生成同一個隨機數的 Random 對象。

?

Random?成員

名稱 ● 說明

Equals ● 確定指定的 Object 是否等于當前的 Object。(繼承自 Object。)?
Finalize ● 允許 Object 在“垃圾回收”回收 Object 之前嘗試釋放資源并執行其他清理操作。(繼承自 Object。)?
GetHashCode ● 用作特定類型的哈希函數。(繼承自 Object。)?
GetType ● 獲取當前實例的 Type。(繼承自 Object。)?
MemberwiseClone ● 創建當前 Object 的淺表副本。(繼承自 Object。)?
Next ● 已重載。 返回隨機數。?
NextBytes ● 用隨機數填充指定字節數組的元素。?
NextDouble ● 返回一個介于 0.0 和 1.0 之間的隨機數。?
Sample ● 返回一個介于 0.0 和 1.0 之間的隨機數。?
ToString ● 返回表示當前 Object 的 String。(繼承自 Object。)

?

?

用?C#?生成不重復的隨機數

?

我們可以使用兩種方式初始化一個隨機數發生器:

第一種方法不指定隨機種子,系統自動選取當前時間作為隨機種子:

Random ro = new Random();

第二種方法可以指定一個int型參數作為隨機種子:

int iSeed=10;?
Random ro = new Random(10);?
long tick = DateTime.Now.Ticks;?
Random ran = new Random((int)(tick & 0xffffffffL) | (int) (tick >> 32));

這樣可以保證99%不是一樣。

之后,我們就可以使用這個Random類的對象來產生隨機數,這時候要用到Random.Next()方法。這個方法使用相當靈活,你甚至可以指定產生的隨機數的上下限。

不指定上下限的使用如下:?
int iResult;?
iResult=ro.Next();

下面的代碼指定返回小于100的隨機數:?
int iResult;?
int iUp=100;?
iResult=ro.Next(iUp);

而下面這段代碼則指定返回值必須在50-100的范圍之內:?
int iResult;?
int iUp=100;?
int iDown=50;?
iResult=ro.Next(iDown,iUp);

除了Random.Next()方法之外,Random類還提供了Random.NextDouble()方法產生一個范圍在0.0-1.0之間的隨機的雙精度浮點數:?
double dResult;?
dResult=ro.NextDouble();

?

但是用Random類生成題號,會出現重復,特別是在數量較小的題目中要生成不重復的的題目是很難的。

參考了網上的一些方法,找到兩類解決方法,一類是通過隨機種子入手,使每一次的隨機種子不同,來保證不重復;第二類是使用一些數據結構和算法。

下面主要就第二類介紹幾個方法:

方法1:思想是用一個數組來保存索引號,先隨機生成一個數組位置,然后把隨機抽取到的位置的索引號取出來,并把最后一個索引號復制到當前的數組位置,然后使隨機數的上限減一,具體如:先把這100個數放在一個數組內,每次隨機取一個位置(第一次是1-100,第二次是1-99,...),將該位置的數用最后的數代替。

?

?

int[] index = new int[15];?
for (int i = 0; i < 15; i++)?
index = i;?
Random r = new Random();?
//用來保存隨機生成的不重復的10個數?
int[] result = new int[10];?
int site = 15;//設置上限?
int id;?
for (int j = 0; j < 10; j++)?
{?
id = r.Next(1, site - 1);?
//在隨機位置取出一個數,保存到結果數組?
result[j] = index[id];?
//最后一個數復制到當前位置?
index[id] = index[site - 1];?
//位置的上限減少一?
site--;?
}

?

方法2:利用Hashtable。

?

Hashtable hashtable = new Hashtable();?
Random rm = new Random();?
int RmNum = 10;?
for (int i = 0; hashtable.Count < RmNum; i++)?
{?
?? int nValue = rm.Next(100);?
if (!hashtable.ContainsValue(nValue) && nValue != 0)?
{?
??? hashtable.Add(nValue, nValue);?
??? Console.WriteLine(nValue.ToString());?
}?
}

?

方法3:遞歸,用它來檢測生成的隨機數是否有重復,如果取出來的數字和已取得的數字有重復就重新隨機獲取。

?

Random ra=new Random(unchecked((int)DateTime.Now.Ticks));?
int[] arrNum=new int[10];?
int tmp=0;?
int minValue=1;?
int maxValue=10;?
for (int i=0;i<10;i++)?
{?
tmp=ra.Next(minValue,maxValue); //隨機取數?
arrNum=getNum(arrNum,tmp,minValue,maxValue,ra); //取出值賦到數組中?
}?
.........?
.........?
public int getNum(int[] arrNum,int tmp,int minValue,int maxValue,Random ra)?
{?
int n=0;?
while (n<=arrNum.Length-1)?
{?
if (arrNum[n]==tmp) //利用循環判斷是否有重復?
{?
tmp=ra.Next(minValue,maxValue); //重新隨機獲取。?
getNum(arrNum,tmp,minValue,maxValue,ra);//遞歸:如果取出來的數字和已取得的數字有重復就重新隨機獲取。?
}?
n++;?
}?
return tmp;?
}

?

silverlight 2 Random?隨機數解決方案

來源:我和未來有約會?
2008-06-17 01:21 by nasa

using System;?
using System.Security.Cryptography;

??? public class RNG?
??? {?
??????? private static RNGCryptoServiceProvider rngp = new RNGCryptoServiceProvider();?
??????? private static byte[] rb = new byte[4];

??????? /// <summary>?
????????/// 產生一個非負數的亂數?
??????? /// </summary>?
??????? public static int Next()?
??????? {?
??????????? rngp.GetBytes(rb);?
??????????? int value = BitConverter.ToInt32(rb, 0);?
??????????? if (value < 0) value = -value;?
??????????? return value;?
??????? }?
??????? /// <summary>?
????????/// 產生一個非負數且最大值在 max 以下的亂數?
??????? /// </summary>?
??????? /// <param name="max">最大值</param>?
??????? public static int Next(int max)?
??????? {?
??????????? rngp.GetBytes(rb);?
??????????? int value = BitConverter.ToInt32(rb, 0);?
??????????? value = value % (max + 1);?
??????????? if (value < 0) value = -value;?
??????????? return value;?
??????? }?
??????? /// <summary>?
????????/// 產生一個非負數且最小值在 min 以上最大值在 max 以下的亂數?
??????? /// </summary>?
??????? /// <param name="min">最小值</param>?
??????? /// <param name="max">最大值</param>?
??????? public static int Next(int min, int max)?
??????? {?
??????????? int value = Next(max - min) + min;?
??????????? return value;?
??????? }?
??? }

?

二、線程安全的單例模式

原文地址:http://www.oschina.net/code/snippet_111708_25417

線程安全的單例模式實現有幾種思路,個人認為第2種方案最優雅:
1、餓漢式
2、借助內部類
3、普通加鎖解決
4、雙重檢測,但要注意寫法
如果單體模式繼續擴展為N元單體模式,那就是對象池模式了

餓漢式單例 ?

public?class?Singleton { ???private?final?static?Singleton INSTANCE =?new?Singleton(); ???private?Singleton() { } ???public?static?Singleton getInstance() { ??????return?INSTANCE; ???} }

借助內部類

public?class?Singleton { ???? ???private?Singleton() { } ???private?static?class?SingletonHolder { ??????private?final?static?Singleton INSTANCE =?new?Singleton(); ???} ???public?static?Singleton getInstance() { ??????return?SingletonHolder.INSTANCE; ???} } 屬于懶漢式單例,因為Java機制規定,內部類SingletonHolder只有在getInstance()方法第一次調用的時候才會被加載(實現了lazy),而且其加載過程是線程安全的。內部類加載的時候實例化一次instance。

普通加鎖解決

public?class?Singleton { ???private?static?Singleton instance =?null; ???private?Singleton() { } ???? ???public?static?synchronized?Singleton getInstance() { ??????if(instance ==?null) { ?????????instance =?new?Singleton(); ??????} ??????return?instance; ???} } 雖然解決了線程安全問題,但是每個線程調用getInstance都要加鎖,我們想要只在第一次調用getInstance時加鎖,請看下面的雙重檢測方案

雙重檢測方案?

public?class?Singleton { ???private?static?Singleton instance =?null; ???private?Singleton() { } ???public?static?Singleton getInstance() { ??????if(instance ==?null) { ?????????synchronzied(Singleton.class) { ????????????Singleton temp = instance; ????????????if(temp ==?null) { ???????????????temp =?new?Singleton(); ???????????????instance = temp ????????????} ?????????} ??????} ??????return?instance; ???} } 由于指令重排序問題,所以不可以直接寫成下面這樣: public?class?Singleton { ???private?static?Singleton instance =?null; ???private?Singleton() { } ???public?static?Singleton getInstance() { ??????if(instance ==?null) { ?????????synchronzied(Singleton.class) { ????????????if(instance ==?null) { ???????????????instance =?new?Singleton(); ????????????} ?????????} ??????} ??????return?instance; ???} } 但是如果instance實例變量用volatile修飾就可以了,volatile修飾的話就可以確保instance =?new?Singleton();對應的指令不會重排序,如下的單例代碼也是線程安全的: public?class?Singleton { ???private?static?volatile?Singleton instance =?null; ???private?Singleton() { } ???public?static?Singleton getInstance() { ??????if(instance ==?null) { ?????????synchronzied(Singleton.class) { ????????????if(instance ==?null) { ???????????????instance =?new?Singleton(); ????????????} ?????????} ??????} ??????return?instance; ???} }

?以下轉自:http://www.cnblogs.com/akwwl/p/3240813.html

C#讀寫txt文件的兩種方法介紹

1.添加命名空間

  System.IO;

  System.Text;

2.文件的讀取

  (1).使用FileStream類進行文件的讀取,并將它轉換成char數組,然后輸出。

byte[] byData = new byte[100];char[] charData = new char[1000];public void Read(){try{FileStream file = new FileStream("E:\\test.txt", FileMode.Open);file.Seek(0, SeekOrigin.Begin);file.Read(byData, 0, 100); //byData傳進來的字節數組,用以接受FileStream對象中的數據,第2個參數是字節數組中開始寫入數據的位置,它通常是0,表示從數組的開端文件中向數組寫數據,最后一個參數規定從文件讀多少字符.Decoder d = Encoding.Default.GetDecoder();d.GetChars(byData, 0, byData.Length, charData, 0);Console.WriteLine(charData);file.Close();}catch (IOException e){Console.WriteLine(e.ToString());}}

  (2).使用StreamReader讀取文件,然后一行一行的輸出。

public void Read(string path){StreamReader sr = new StreamReader(path,Encoding.Default);String line;while ((line = sr.ReadLine()) != null) {Console.WriteLine(line.ToString());}}

3.文件的寫入
  (1).使用FileStream類創建文件,然后將數據寫入到文件里。

public void Write(){FileStream fs = new FileStream("E:\\ak.txt", FileMode.Create);//獲得字節數組byte[] data = System.Text.Encoding.Default.GetBytes("Hello World!"); //開始寫入fs.Write(data, 0, data.Length);//清空緩沖區、關閉流fs.Flush();fs.Close();}

  (2).使用FileStream類創建文件,使用StreamWriter類,將數據寫入到文件。

public void Write(string path){FileStream fs = new FileStream(path, FileMode.Create);StreamWriter sw = new StreamWriter(fs);//開始寫入sw.Write("Hello World!!!!");//清空緩沖區sw.Flush();//關閉流sw.Close();fs.Close();}

  以上就完成了,txt文本文檔的數據讀取與寫入。

[轉]C#獲取本機IP搜集整理7種方法

1 private void GetIP() 2 { 3 string hostName = Dns.GetHostName();//本機名 4 //System.Net.IPAddress[] addressList = Dns.GetHostByName(hostName).AddressList;//會警告GetHostByName()已過期,我運行時且只返回了一個IPv4的地址 5 System.Net.IPAddress[] addressList = Dns.GetHostAddresses(hostName);//會返回所有地址,包括IPv4和IPv6 6 foreach (IPAddress ip in addressList) 7 { 8 listBox1.Items.Add(ip.ToString()); 9 } 10 }

?

?

②使用IPHostEntry獲取本機局域網地址

?

1 static string GetLocalIp() 2 { 3 string hostname = Dns.GetHostName();//得到本機名 4 //IPHostEntry localhost = Dns.GetHostByName(hostname);//方法已過期,只得到IPv4的地址 5 <SPAN style="WHITE-SPACE: pre"> </SPAN> IPHostEntry localhost = Dns.GetHostEntry(hostname); 6 IPAddress localaddr = localhost.AddressList[0]; 7 return localaddr.ToString(); 8 }

?

?方法時通過向網站向一些提供IP查詢的網站發送webrequest,然后分析返回的數據流?

1 string strUrl = "提供IP查詢的網站的鏈接"; 2 Uri uri = new Uri(strUrl); 3 WebRequest webreq = WebRequest.Create(uri); 4 Stream s = webreq .GetResponse().GetResponseStream(); 5 StreamReader sr = new StreamReader(s, Encoding.Default); 6 string all = sr.ReadToEnd(); 7 int i = all.IndexOf("[") + 1; 8 //分析字符串得到IP 9 return ip; 10 /* 11 我用的是http://www.ip.cn/getip.php?action=getip&ip_url=&from=web 12 (這種鏈接很容易找的,百度“IP”得到一些網站,分析一下網站的鏈接就能得到) 13 返回的數據是: 14 <div class="well"><p>當前 IP:<code>0.0.0.0</code>&nbsp;來自:XX省XX市 電信</p><p>GeoIP: Beijing, China</p></div> 15 解析這段就行 16 */

?

⑥通過獲取CMD里ipconfig命令的結果來得到IP?????

1 private void GetIP6() 2 { 3 Process cmd = new Process(); 4 cmd.StartInfo.FileName = "ipconfig.exe";//設置程序名 5 cmd.StartInfo.Arguments = "/all"; //參數 6 //重定向標準輸出 7 cmd.StartInfo.RedirectStandardOutput = true; 8 cmd.StartInfo.RedirectStandardInput = true; 9 cmd.StartInfo.UseShellExecute = false; 10 cmd.StartInfo.CreateNoWindow = true;//不顯示窗口(控制臺程序是黑屏) 11 //cmd.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;//暫時不明白什么意思 12 /* 13 收集一下 有備無患 14 關于:ProcessWindowStyle.Hidden隱藏后如何再顯示? 15 hwndWin32Host = Win32Native.FindWindow(null, win32Exinfo.windowsName); 16 Win32Native.ShowWindow(hwndWin32Host, 1); //先FindWindow找到窗口后再ShowWindow 17 */ 18 cmd.Start(); 19 string info = cmd.StandardOutput.ReadToEnd(); 20 cmd.WaitForExit(); 21 cmd.Close(); 22 textBox1.AppendText(info); 23 }

?

?

⑦NetworkInformation?

?

以下轉自:http://www.cnblogs.com/huashanlin/archive/2007/07/07/809305.html

[STAThread]的含義

Posted on?2007-07-07 10:06?樺林?閱讀(32335) 評論(10)?編輯?收藏

[STAThread]
STAThread:Single???? Thread???? Apartment Thread.(單一線程單元線程)
[]是用來表示Attributes;

[STAThread]
是一種線程模型,用在程序的入口方法上(在C#和VB.NET里是Main()方法),來指定當前線程的ApartmentState 是STA。用在其他方法上不產生影響。在aspx頁面上可以使用AspCompat = "true"?來達到同樣的效果。這個屬性只在? Com? Interop? 有用,如果全部是? managed? code? 則無用。簡單的說法:[STAThread]指示應用程序的默認線程模型是單線程單元 (STA)。啟動線程模型可設置為單線程單元或多線程單元。如果未對其進行設置,則該線程不被初始化。也就是說如果你用的.NET Framework,并且沒有使用COM Interop,一般不需要這個Attribute。其它的還有MTA(多線程套間)、Free? Thread(自由線程)。?

[STAThread] attribute指示應用程序的 COM 線程模型是單線程單元。
而于此對應的多線程單元則是 [MTAThread] (多線程單元線程)

COM 線程模型只適用于使用 COM interop 的應用程序。如果將此屬性應用到不使用 COM interop 的應用程序,將沒有任何效果。

COM 線程模型可設置為單線程單元或多線程單元。如果應用程序線程實際調用了 COM 組件,則僅為 COM interop 初始化該線程。如果沒有使用 COM interop,則不初始化該線程。

以下是找到的一個資料介紹:
Q. When I create a c# project from scratch in VS.NET, the generated code always have a [STAThread] attribute above the main routine. What does the STAThread attribute really do? Can I change it to MTAThread instead? I have searched website and books, no one seems to explain this well.

Asked by anon. Answered by the Wonk on February 17, 2003

?

A.

The STAThreadAttribute marks a thread to use the Single-Threaded COM Apartment if COM is needed. By default, .NET won't initialize COM at all. It's only when COM is needed, like when a COM object or COM Control is created or when drag 'n' drop is needed, that COM is initialized. When that happens, .NET calls the underlying CoInitializeEx function, which takes a flag indicating whether to join the thread to a multi-threaded or single-threaded apartment.

A multi-threaded apartment (MTA) in COM is more efficient, since any of a number of RPC threads from a pool can be used to handle a request. However, an object on the MTA thread needs to protect itself from multiple threads accessing it at the same time, so that efficiency comes at a cost.

The single-thread apartment (STA) in COM is inherently single-threaded and therefore no additional thread synchronization is needed. The STA is implemented using the thread's Windows message queue, which is how requests to objects on an STA are serialized. Because of how the STA thread is implemented, calls to objects on that thread are serialized with Windows message handling on that thread, making sure that everything, both the COM objects and the underlying windowing objects, e.g. HWNDs, are all synchronized. This is necessary for UI-oriented COM objects, like controls and drag 'n' drop, which must also be synchronized together with the UI.

When COM is needed .NET will call CoInitializeEx, picking the MTA by default because it's more efficient. However, to get the synchronization needed for controls, windows and drag 'n' drop, you need to mark a thread's entry point with the STAThreadAttribute to let .NET know to initialize the UI thread on the STA. All of the VS.NET project templates put that attribute in to make sure you don't forget:
大致意思是:由于很多COM在.NET環境下如果使用多線程的話,會導致引用的COM不能正常運行,而如果不聲明程序為STAThread的話,.NET就會自動使用多線程來提高效率,這樣就會導致不可預知的后果。




以下引用另一同輩的發言:http://blog.csdn.net/qilang/archive/2006/06/06/775605.aspx
STA不是單線程的意思.英文為single?threaded?apartment.是一種套間(或譯為公寓)線程模式.

sta?thread并不表明應用程式的類型,和應用程序不搭界,恰相反,一個應用程序可以有多個線程.每個線程也可以有多個組件或對象.以前win16位系統的組件線程模式才真正是單線程.這是一種被淘汰了的模式.
線程模式用于處理組件在多線程的環境里并行與并互的方式.比如套間線程(STAThread)模式中接口跨線程傳遞必須被調度(Marshal),不調度直傳肯定會失敗!而MTA或FreeThread模式中的接口可以不經調度直接傳遞.
這種調度在特定的環境中非常影響性能(可有幾百倍之差).如VB里只支持STAThread模式.FreeThread模式的組件會在里面表現成和跨進程一樣慢!
線程模式是微軟的COM基礎中的極其重要的概念.一定要吃透!
我對.net真是一竅不通(沒空去弄,對不起微軟去年的獎賞).但我可以肯定,C#中的[STAThread]屬性是應用程序的套間初始化代碼.可以直接理解成SDK里的
CoInitialize(NULL);?
初始一個STA套間實際上是相當于開了一個消息窗口,所有調用經此窗口過程調度到組件內.
同理[MTAThread](不知有沒有這個屬性,自已去查)
可以理解成
CoInitializeEx(NULL,COINIT_MULTITHREADED?)
這經常是一個對初入com大門的人來說,有一定難度但必須過的一道關.

轉載于:https://www.cnblogs.com/cheng2015/p/5257364.html

總結

以上是生活随笔為你收集整理的C#通用模块专题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。