java程序

This XML file does not appear to have any style information associated with it. The document tree is shown below.博客園_首頁代碼改變世界uuid:5de59c50-a92f-4447-96ed-ab86451ed183;id=61182014-07-27T11:59:08Zfeed.cnblogs.comhttp://www.cnblogs.com/jianyus/p/3865670.htmlSharePoint 2013 Designer系列之數據視圖篩選 - 霖雨 在SharePoint中,咱們常常須要對列表進行簡單的篩選,這時,數據視圖就有做用了,咱們能夠定製對於字段的篩選,來進行展現;特別的,篩選不一樣於搜索,並無對於附件或者文檔的全文檢索,若是須要全文檢索,能夠使用列表的垂直搜索功能。 一、新建一個測試頁面,而後右鍵在高級模式下編輯,以下圖: 2...2014-07-27T11:22:00Z2014-07-27T11:22:00Z霖雨http://www.cnblogs.com/jianyus/javascript

  在SharePoint中,咱們常常須要對列表進行簡單的篩選,這時,數據視圖就有做用了,咱們能夠定製對於字段的篩選,來進行展現;特別的,篩選不一樣於搜索,並無對於附件或者文檔的全文檢索,若是須要全文檢索,能夠使用列表的垂直搜索功能。php

  一、新建一個測試頁面,而後右鍵在高級模式下編輯,以下圖:css

clip_image002

  二、在PlaceHolderMain節點裏,加入webpartzone,用來添加數據視圖;html

clip_image004

  三、數據視圖選擇News列表,以下圖:前端

clip_image006

  四、列表視圖就選擇第一個就能夠了,以下圖:html5

clip_image008

  五、查看測試頁面,以下圖:java

clip_image010

  六、在ribbon上點擊篩選,以下圖:python

clip_image012

  七、選擇篩選的域名Title,而後新建值,以下圖:linux

clip_image014

  八、新建參數爲k,參數源是查詢字符串,以下圖:android

clip_image016

  九、建好的篩選條件,Title裏包好參數k的值,以下圖:

clip_image018

  十、添加腳本和html,以下圖:

clip_image020

  十一、測試數據視圖的篩選,很簡單吧,在有些場景下,數據視圖的篩選,仍是頗有用的!

clip_image022

總 結

  這裏只是介紹了單一字段的篩選,咱們經過數據視圖,還能夠製做更復雜的篩選,而後利用分組,能夠作出很是漂亮和霸氣的展現頁面。

本文連接:SharePoint 2013 Designer系列之數據視圖篩選,轉載請註明。

http://www.cnblogs.com/jacksu-tencent/p/3871755.html我的github blog環境設置 - jack(小保) 每一個人都想擁有本身的網站,可是大部分比較屌絲,不想花錢租賃服務器,哈哈,屌絲有屌絲辦法。github應該都據說過吧,github.io提供了此功能,並且使用github來管理本身的代碼,若是你有域名,還能夠綁定你本身的域名歐。我在github的博客終於搗鼓好了,也給你們介紹一下建站步驟。2014-07-27T11:14:00Z2014-07-27T11:14:00Zjack(小保)http://www.cnblogs.com/jacksu-tencent/

每一個人都想擁有本身的網站,可是大部分比較屌絲,不想花錢租賃服務器,哈哈,屌絲有屌絲辦法。github應該都據說過吧,github.io提供了此功能,並且使用github來管理本身的代碼,若是你有域名,還能夠綁定你本身的域名歐。我在github的博客(jacksu blog)終於搗鼓好了,也給你們介紹一下建站步驟。

軟件安裝

大致須要如下幾個東東,個性化的就須要本身去搜尋。

pelican

安裝

咱們須要網站的管理工具pelican,pelican能夠把markdown的文件生成html和pdf,pelican又依賴於pipe,安裝命令以下:

sudo easy_install pipe

sudo pip install pelican

檢查是否安裝成功

執行以下命令:

pelican -h或者
pelican .md所在目錄

Markdown包

pelican不能夠識別markdown,須要下載markdown包,markdown的下載方式爲:

sudo pip install Markdown

主題

沒有主題,你的網站太難看了,那麼下載一個主題:

git clone https://github.com/farseerfc/pelican-themes


設置

github上的設置

在github上創建username.github.io的項目(如何在github創建項目,我就不說了,應該不少人會),參考官方文檔設置,過十分鐘左右你就能夠經過username.github.io訪問了。

settings.py設置

settings.py的內容大致以下,我也是參考mx的blog的.

# -*- coding: utf-8 -*-
import sys

TIMEZONE = 'Asia/Shanghai'

DEFAULT_LANG = 'zhs'

SITENAME = "X. Wei's Blog"
AUTHOR = 'X.Wei'

DISQUS_SITENAME = 'xweisblog'
GITHUB_URL = '<https://github.com/X-Wei>'#github連接
SITEURL = '<http://x-wei.github.com>'
GOOGLE_ANALYTICS = 'UA-30756331-1'#谷歌站點分析
TAG_FEED = 'feeds/%s.atom.xml'

DEFAULT_PAGINATION = 4#默認每一頁有多少篇文章

DEFAULT_CATEGORY ='misc'
OUTPUT_PATH = '.'
#須要把輸出路徑從默認的'output'改爲根目錄(your_id.github.com目錄), 由於githubpage須要把index.html上傳到repo的master分支的根目錄才能夠!
PATH = 'posts'#這個是指定放置.md/.rst文件的目錄

LINKS = (('dofine', '<http://www.dofine.me>'),
('farseerfc', "<http://farseerfc.github.com/>"),
)#友情連接~

SOCIAL = (
('github', '<https://github.com/x-wei>'),
)#社交網絡連接
#~ ('twitter', '<http://twitter.com/farseerfc>'),
#~ ('facebook', '<http://www.facebook.com/farseerfc>'),
#~ ('weibo', '<http://weibo.com/farseerfc>'),
#~ ('renren', '<http://www.renren.com/farseer>'),

#這個是farseerfc同窗本身加的, 能夠顯示他的新浪微博內容, 有微博的話能夠把這些加上~
#~ TWITTER_USERNAME = 'farseerfc'
#~ SIDEBAR_CUSTOM = r"""
#~ <li class="nav-header"><h4><i class="icon-list-alt"></i>Weibo</h4></li>
#~ <iframe width="100%" height="550" class="share_self" frameborder="0" scrolling="no"
#~ src="<http://widget.weibo.com/weiboshow/index.php?language=&width=0&height=550&fansRow=1&ptype=1&speed=0&skin=2&isTitle=1&noborder=1&isWeibo=1&isFans=1&uid=1862842353&verifier=b193b9de&dpc=1>">
#~ </iframe>
#~ """

#google自定義搜索(大概是站內搜索吧)
#~ GOOGLE_CUSTOM_SEARCH_SIDEBAR = "001578481551708017171:axpo6yvtdyg"
#~ GOOGLE_CUSTOM_SEARCH_NAVBAR = "001578481551708017171:hxkva69brmg"

個人settings.py

md頭

每一個md文件必須包含下面相關內容,各個字段含義應該經過英文意思就能夠看出來。

Title: 我的github blog環境設置

Date: 2014-7-27 00:20

Modified: 2014-7-27 00:20

Category: env_set

Tags: github

Slug: my-github-blog-set

Author: jacksu

Summary: 每一個人都想擁有本身的網站,可是大部分比較屌絲,不想花錢租賃服務器,哈哈,屌絲有屌絲辦法。github應該都據說過吧,github.io提供了此功能,並且使用github來管理本身的代碼,若是你有域名,還能夠綁定你本身的域名歐。我在github的博客終於搗鼓好了,也給你們介紹一下建站步驟。


建站

把剛纔github的項目拉到本地,執行以下命令:

git clone https://github.com/username/username.github.io

pelican -s settings.py -t ../pelican-themes/bootstrap2/ posts/

其中-t後面是你的主題目錄,posts是md所在的目錄。再執行以下命令:

git add .

git commit -m "add"

git push

咱們的我的網站建成了,能夠訪問usrname.github.io了.


jacksu blog

本文連接:我的github blog環境設置,轉載請註明。

http://www.cnblogs.com/yangjunhua/p/3871763.htmljQuery.lazyload使用及源碼分析 - 華子yjh 前言:貌似之前本身也寫過圖片懶加載插件,可是新公司使用的是jQuery.lazyload插件,爲了更好的運用,本身仍是把源碼看了遍,分別記錄瞭如何使用,插件原理,各個配置屬性的完整解釋,demo實例,源碼分析(較簡短),源碼分析能夠配合使用,配置屬性,原理進行閱讀,如需轉載,請註明出處博客園 華子y...2014-07-27T10:56:00Z2014-07-27T10:56:00Z華子yjhhttp://www.cnblogs.com/yangjunhua/

前言:

貌似之前本身也寫過圖片懶加載插件,可是新公司使用的是jQuery.lazyload插件,爲了更好的運用,本身仍是把源碼看了遍,分別記錄瞭如何使用,

插件原理,各個配置屬性的完整解釋,demo實例,源碼分析(較簡短),源碼分析能夠配合使用,配置屬性,原理進行閱讀,如需轉載,請註明出處

博客園 華子yjh

 

1、如何使用

// 最簡單的使用,不帶參數
$('img' ).lazyload();


// 帶參數(配置對象),下面配置對象中的各個屬性值都是默認的
$('img' ).lazyload({
threshold :
0 ,
failure_limit :
0 ,
event :
"scroll" ,
effect :
"show" ,
container : window,
data_attribute :
"original" ,
skip_invisible :
true ,
appear :
null ,
load :
null ,
placeholder :
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC"
});

 

2、內部原理

首先選中的img元素都綁定了一個appear事件(處理img顯示真實的圖片地址),方便之後知足條件時觸發該事件;
在配置對象中有一個container屬性配置,默認爲window,若是img元素在該container容器視口中,則觸發appear事件;
爲了判斷img元素是否在container容器視口範圍中,造了以下四個輪子:

$.belowthefold = function(element, settings) {}; // 在視口下方
$.rightoffold = function(element, settings) {}; // 在視口右方
$.abovethetop = function(element, settings) {}; // 在視口上方
$.leftofbegin = function(element, settings) {}; // 在視口左方

看看源碼中是如何利用這四個輪子:

if ($.abovethetop( this, settings) || $.leftofbegin( this , settings)) {
/* Nothing. */
}
// 不知足在上方,左方;也不知足在下方,右方; 則觸發appear事件
else if (!$.belowthefold( this, settings) && !$.rightoffold( this , settings)) {
$
this.trigger("appear" );
}


3、配置對象中的其餘屬性

臨界值,這個值是針對container容器的,即距離container容器視口的臨界值

{
threshold:
0
}

 

事件,container容器默認綁定這個事件,在這個事件被觸發時,會不斷的判斷img元素是否知足觸發appear的條件,
所以當瀏覽器不停的滾動下來時,若是知足條件,則顯示圖片;

另外還有一點,若是這個事件不是scroll事件,則選中的img元素都會綁定這個事件,綁定的這個事件中一樣會觸發內部appear事件;

{
event:
'scroll'
}

 

顯示方法,默認爲show,也能夠設置爲fadeIn,API中隱藏了一個配置屬性effectspeed,動畫運行的時間

{
effect:
"show"
}

 

img元素的一個data屬性,用於存放圖片的真實地址

{
data_attribute:
"original" ,
}

 

忽略隱藏的img元素

{
skip_invisible:
true
}

 

圖片佔位符,img元素默認src屬性爲1*1像素的透明圖片

{
placeholder:
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC"
}

 

在img觸發appear事件時執行的回調

{
appear:
null
}

 

在img觸發load事件時執行的回調

{
load:
null
}

 

最後一個配置屬性failure_limit

{
failure_limit:
0
}

爲了便於理解,咱們先來看一段與其有關的源碼:

var counter = 0 ;

elements.each(
function () {
if ($.abovethetop( this, settings) || $.leftofbegin( this , settings)) {
// ...
} else if (!$.belowthefold( this, settings) && !$.rightoffold( this , settings)) {
// ...
} else {
if (++counter > settings.failure_limit) {
return false ;
}
}
});

什麼意思呢,若是找到的是第 failure_limit 個img元素,且不在container視口上方,左方及視口內(能夠容許在視口下方,右方),則中斷循環

 

3、demo

看完原理和配置屬性,是否以爲很簡單呢,來看看幾個demo吧

demo1 下拉滾動: http://jsfiddle.net/ddEPL/
demo2 Tab切換: http://jsfiddle.net/ddEPL/1/

 

4、源碼分析

/*
* Lazy Load - jQuery plugin for lazy loading images
*
* Copyright (c) 2007-2013 Mika Tuupola
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/mit-license.php
*
* Project home:
* http://www.appelsiini.net/projects/lazyload
*
* Version: 1.9.3
*
*/

(
function ($, window, document, undefined) {
var $window = $(window);

$.fn.lazyload
= function (options) {
var elements = this ;
var $container;
var settings = {
threshold :
0 ,
failure_limit :
0 ,
event :
"scroll" ,
effect :
"show" ,
container : window,
data_attribute :
"original" ,
skip_invisible :
true ,
appear :
null ,
load :
null ,
placeholder :
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC"
};

function update() {
var counter = 0 ;

elements.each(
function () {
var $ this = $( this );
// 若是圖片隱藏,且忽略隱藏,則中斷循環
if (settings.skip_invisible && !$ this.is(":visible" )) {
return ;
}
if ($.abovethetop( this, settings) || $.leftofbegin( this , settings)) {
/* Nothing. */
}
// img知足在container視口中,則顯示
else if (!$.belowthefold( this, settings) && !$.rightoffold( this , settings)) {
$
this.trigger("appear" );
/* if we found an image we'll load, reset the counter */
counter
= 0 ;
}
// 若是找到的是第(failure_limit + 1)個img元素,且不在container視口上方,左方及視口內(能夠容許在視口下方,右方),
// 則中斷循環
else {
if (++counter > settings.failure_limit) {
return false ;
}
}
});

}

if (options) {
/* Maintain BC for a couple of versions. */
if (undefined !== options.failurelimit) {
options.failure_limit
= options.failurelimit;
delete options.failurelimit;
}
if (undefined !== options.effectspeed) {
options.effect_speed
= options.effectspeed;
delete options.effectspeed;
}

$.extend(settings, options);
}

/* Cache container as jQuery as object. */
$container
= (settings.container === undefined ||
settings.container
=== window) ? $window : $(settings.container);

/* Fire one scroll event per scroll. Not one scroll event per image. */
// 爲container綁定scroll事件
if (0 === settings.event.indexOf("scroll" )) {
$container.bind(settings.event,
function () {
return update();
});
}

this.each( function () {
var self = this ;
var $self = $(self);

self.loaded
= false ;

/* If no src attribute given use data:uri. */
// 設置佔位符
if ($self.attr("src") === undefined || $self.attr("src") === false ) {
if ($self.is("img" )) {
$self.attr(
"src" , settings.placeholder);
}
}

/* When appear is triggered load original image. */
// one綁定appear,觸發後則移除該事件
$self.one("appear", function () {
if (! this .loaded) {
// 存在回調則觸發
if (settings.appear) {
var elements_left = elements.length;
settings.appear.call(self, elements_left, settings);
}
$(
"<img />" )
.bind(
"load", function () {

var original = $self.attr("data-" + settings.data_attribute);
$self.hide();
if ($self.is("img" )) {
$self.attr(
"src" , original);
}
else {
$self.css(
"background-image", "url('" + original + "')" );
}
$self[settings.effect](settings.effect_speed);

self.loaded
= true ;

/* Remove image from array so it is not looped next time. */
// 更新elements,過濾掉已經加載的img元素,避免下次在update中輪循
var temp = $.grep(elements, function (element) {
return ! element.loaded;
});
elements
= $(temp);

// 存在回調則觸發
if (settings.load) {
var elements_left = elements.length;
settings.load.call(self, elements_left, settings);
}
})
.attr(
"src", $self.attr("data-" + settings.data_attribute));
}
});

/* When wanted event is triggered load original image */
/* by triggering appear. */
// 綁定不是scroll的事件,用於觸發appear事件
if (0 !== settings.event.indexOf("scroll" )) {
$self.bind(settings.event,
function () {
if (! self.loaded) {
$self.trigger(
"appear" );
}
});
}
});

/* Check if something appears when window is resized. */
$window.bind(
"resize", function () {
update();
});

/* With IOS5 force loading images when navigating with back button. */
/* Non optimal workaround. */
if ((/(?:iphone|ipod|ipad).*os 5/ gi).test(navigator.appVersion)) {
$window.bind(
"pageshow", function (event) {
if (event.originalEvent && event.originalEvent.persisted) {
elements.each(
function () {
$(
this).trigger("appear" );
});
}
});
}

/* Force initial check if images should appear. */
$(document).ready(
function () {
update();
});

return this ;
};

/* Convenience methods in jQuery namespace. */
/* Use as $.belowthefold(element, {threshold : 100, container : window}) */

$.belowthefold
= function (element, settings) {
var fold;

if (settings.container === undefined || settings.container === window) {
fold
= (window.innerHeight ? window.innerHeight : $window.height()) + $window.scrollTop();
}
else {
fold
= $(settings.container).offset().top + $(settings.container).height();
}

return fold <= $(element).offset().top - settings.threshold;
};

$.rightoffold
= function (element, settings) {
var fold;

if (settings.container === undefined || settings.container === window) {
fold
= $window.width() + $window.scrollLeft();
}
else {
fold
= $(settings.container).offset().left + $(settings.container).width();
}

return fold <= $(element).offset().left - settings.threshold;
};

$.abovethetop
= function (element, settings) {
var fold;

if (settings.container === undefined || settings.container === window) {
fold
= $window.scrollTop();
}
else {
fold
= $(settings.container).offset().top;
}

return fold >= $(element).offset().top + settings.threshold + $(element).height();
};

$.leftofbegin
= function (element, settings) {
var fold;

if (settings.container === undefined || settings.container === window) {
fold
= $window.scrollLeft();
}
else {
fold
= $(settings.container).offset().left;
}

return fold >= $(element).offset().left + settings.threshold + $(element).width();
};

$.inviewport
= function (element, settings) {
return !$.rightoffold(element, settings) && !$.leftofbegin(element, settings) &&
!$.belowthefold(element, settings) && ! $.abovethetop(element, settings);
};

/* Custom selectors for your convenience. */
/* Use as $("img:below-the-fold").something() or */
/* $("img").filter(":below-the-fold").something() which is faster */

$.extend($.expr[
":" ], {
"below-the-fold" : function(a) { return $.belowthefold(a, {threshold : 0 }); },
"above-the-top" : function(a) { return !$.belowthefold(a, {threshold : 0 }); },
"right-of-screen": function(a) { return $.rightoffold(a, {threshold : 0 }); },
"left-of-screen" : function(a) { return !$.rightoffold(a, {threshold : 0 }); },
"in-viewport" : function(a) { return $.inviewport(a, {threshold : 0 }); },
/* Maintain BC for couple of versions. */
"above-the-fold" : function(a) { return !$.belowthefold(a, {threshold : 0 }); },
"right-of-fold" : function(a) { return $.rightoffold(a, {threshold : 0 }); },
"left-of-fold" : function(a) { return !$.rightoffold(a, {threshold : 0 }); }
});

})(jQuery, window, document);

 

本文連接:jQuery.lazyload使用及源碼分析,轉載請註明。

http://www.cnblogs.com/stoneniqiu/p/3871754.htmlSpeechLib 語音播報 - stoneniqiu SpeechLib這的dll專門用來播放語音,可以識別英語、簡體和繁體。而且能夠播放聲音文件,支持WAV格式,但不支持MP3。在報警場合下已經夠用了。 基本播放語音及文件。支持異步。using System;using System.Threading;using SpeechLib;namesp....2014-07-27T10:50:00Z2014-07-27T10:50:00Zstoneniqiuhttp://www.cnblogs.com/stoneniqiu/

    SpeechLib這的dll專門用來播放語音,可以識別英語、簡體和繁體。而且能夠播放聲音文件,支持WAV格式,但不支持MP3。在報警場合下已經夠用了。

   基本播放語音及文件。支持異步。

using System;
using System.Threading;
using SpeechLib;

namespace Model.AlarmHandle
{

/// <summary>
/// 語音播報
/// </summary>
public class SpeechVoice
{
/// <summary>
/// The _voice
/// </summary>
private SpVoice _voice;
private SpVoiceClass spVoice;
private readonly SpFileStreamClass spFile;



/// <summary>
/// Initializes a new instance of the <see cref="SpeechVoice"/> class.
/// </summary>
public SpeechVoice()
{
_voice
= new SpVoice();
spVoice
= new SpVoiceClass();
spFile
= new SpFileStreamClass();
}



/// <summary>
/// 播放
/// </summary>
/// <param name="text"> The text. </param>
/// <param name="speakFlag"> The speak flag. </param>
public void Speak( string text, SpeechVoiceSpeakFlags speakFlag = SpeechVoiceSpeakFlags.SVSFDefault)
{
_voice.Speak(
string .Empty); _voice.Speak(text, speakFlag);
}


/// <summary>
/// 異步播放
/// </summary>
/// <param name="text"> The text. </param>
public void SpeakAsync( string text)
{
_voice.Speak(text, SpeechVoiceSpeakFlags.SVSFlagsAsync);
}

/// <summary>
/// Plays the sound.
/// </summary>
/// <param name="fileName"> Name of the file. </param>
public void PlaySound( string fileName)
{
// 要加載COM組件:Microsoft speech object Library
if (!System.IO.File.Exists(fileName)) return ;
spFile.Open(fileName, SpeechStreamFileMode.SSFMOpenForRead,
true );
var istream = spFile as ISpeechBaseStream;
spVoice.SpeakStream(istream, SpeechVoiceSpeakFlags.SVSFIsFilename);
spFile.Close();
}

/// <summary>
/// 暫停
/// </summary>
public void Pause()
{
if (_voice != null )
_voice.Pause();
}

/// <summary>
/// Stops the voice.
/// </summary>
public void StopVoice()
{
_voice.Pause();
_voice.Speak(
string .Empty, SpeechVoiceSpeakFlags.SVSFPurgeBeforeSpeak);
}

/// <summary>
/// Pauses the file.
/// </summary>
public void StopFile()
{
try
{
spFile.ISpStream_Close();
}
catch (Exception)
{
}
}

/// <summary>
/// 恢復
/// </summary>
public void Resume()
{
if (_voice != null )
_voice.Resume();
}


}
/// <summary>
/// 語音播報狀態
/// </summary>
public enum VoiceStatus
{
/// <summary>
/// The play
/// </summary>
Play,
/// <summary>
/// The ready
/// </summary>
Ready,
/// <summary>
/// The pause
/// </summary>
Pause,
}

}

   但真的運用時,還須要支持循環播放,以及播放狀態。

   

private SpeechVoice _speaker;
private bool _isLoopAudioFile; // 是否循環播放聲音文件
private bool _isLoopSpeech; // 循環語音
private VoiceStatus speakStatus= VoiceStatus.Ready;
private bool IsStopPlayFile; // 是否中止
private bool IsStopPlayVoice;

/// <summary>
/// 播放文件結束
/// </summary>
public event EventHandler PlayFileComplete;
/// <summary>
/// 播放文件開始
/// </summary>
public event EventHandler PlayFileStart;

/// <summary>
/// 播放文件結束
/// </summary>
public event EventHandler PlayAudioComplete;
/// <summary>
/// 播放文件開始
/// </summary>
public event EventHandler PlayAudioStart;

/// <summary>
/// 播放語言
/// </summary>
/// <param name="voiceContent"> Content of the voice. </param>
public void SpeechVoice( string voiceContent)
{
IsStopPlayVoice
= false ;
if (speakStatus == VoiceStatus.Play) return; // 正在播放就返回
Speaker.Resume();
Action invoke
= () =>
{
OnPlayAudioStart();
// 觸發開始播放事件
speakStatus = VoiceStatus.Play;
Speaker.Speak(voiceContent);
};
invoke.BeginInvoke(VoiceCallback, invoke);
}
private void VoiceCallback(IAsyncResult ar)
{
var ac = ar.AsyncState as Action;
if (ac != null )
{
try // 原dll不能屢次中止 因此加了try catch 和狀態判斷
{
if ((IsLoopSpeech) && ! IsStopPlayVoice)
{
// 一次播放結束以後若是是循環播放 就繼續播放
ac.BeginInvoke(VoiceCallback, ac);
}
else
{
speakStatus
= VoiceStatus.Pause;
// 觸發中止事件
OnPlayAudioComplete( this, new EventArgs());
ac.EndInvoke(ar);
}
}
catch (Exception)
{

}
}
}

// 如下同理
/// <summary>
/// 暫停播放
/// </summary>
public void StopSpeechVoice()
{
if (IsStopPlayVoice) return ;
IsStopPlayVoice
= true ;
speakStatus
= VoiceStatus.Pause;
Action invoke
= () => Speaker.StopVoice();
invoke.BeginInvoke(
null , invoke);
OnPlayAudioComplete(
this, new EventArgs());
}
/// <summary>
/// 中止播放聲音文件
/// </summary>
public void StopPlayer()
{
if (IsStopPlayVoice) return ;
IsStopPlayFile
= true ;
speakStatus
= VoiceStatus.Pause;
Speaker.PauseFile();
OnPlayFileComplete(
this, new EventArgs());
}

/// <summary>
/// 播放聲音文件
/// </summary>
public void PlayAudioFile()
{
player
= new SoundPlayer { SoundLocation = _audioFile.FilePath };
if(speakStatus==VoiceStatus.Play) return ;
IsStopPlayFile
= false ;
if (File.Exists(_audioFile.FilePath))
{
Action invoke
= () =>
{
OnPlayFileStart();
speakStatus
= VoiceStatus.Play;
Speaker.PlaySound(_audioFile.FilePath);
};
invoke.BeginInvoke(Callback, invoke);
}
}

/// <summary>
/// Called when [play start].
/// </summary>
public void OnPlayFileStart()
{
var handler = PlayFileStart;
if (handler != null) handler( this , EventArgs.Empty);
}

/// <summary>
/// Called when [play start].
/// </summary>
public void OnPlayAudioStart()
{
var handler = PlayAudioStart;
if (handler != null) handler( this , EventArgs.Empty);
}

/// <summary>
/// Called when [play complete].
/// </summary>
/// <param name="sender"> The sender. </param>
/// <param name="e"> The <see cref="EventArgs"/> instance containing the event data. </param>
public void OnPlayAudioComplete( object sender, EventArgs e)
{
EventHandler handler
= PlayAudioComplete;
if (handler != null) handler( this , EventArgs.Empty);
}


/// <summary>
/// Called when [play complete].
/// </summary>
/// <param name="sender"> The sender. </param>
/// <param name="e"> The <see cref="EventArgs"/> instance containing the event data. </param>
public void OnPlayFileComplete ( object sender, EventArgs e)
{
EventHandler handler
= PlayFileComplete;
if (handler != null) handler( this , EventArgs.Empty);
}

/// <summary>
/// Callbacks the specified ar.
/// </summary>
/// <param name="ar"> The ar. </param>
private void Callback(IAsyncResult ar)
{
var ac = ar.AsyncState as Action;
if (ac != null )
{
OnPlayFileComplete(
this, new EventArgs());
try
{
if ((IsLoopAudioFile)&& ! IsStopPlayFile)
{
ac.BeginInvoke(Callback, ac);
}
else
{
speakStatus
= VoiceStatus.Pause;
ac.EndInvoke(ar);
}
}
catch (Exception)
{

}
}
}

語音播放小Demo:SpeechVoice

本文連接:SpeechLib 語音播報,轉載請註明。

http://www.cnblogs.com/yydcdut/p/3860460.html排序(選擇、希爾、二分插入) - 我愛物聯網 選擇排序法 第1趟,在待排序記錄r[1]~r[n]中選出最小的記錄,將它與r[1]交換;第2趟,在待排序記錄r[2]~r[n]中選出最小的記錄,將它與r[2]交換;以此類推,第i趟在待排序記錄r[i]~r[n]中選出最小的記錄,將它與r[i]交換,使有序序列不斷增加直到所有排序完畢。初始序列:{ 4...2014-07-27T10:42:00Z2014-07-27T10:42:00Z我愛物聯網http://www.cnblogs.com/yydcdut/

選擇排序法                                                                                   

第1趟,在待排序記錄r[1]~r[n]中選出最小的記錄,將它與r[1]交換;第2趟,在待排序記錄r[2]~r[n]中選出最小的記錄,將它與r[2]交換;以此類推,第i趟在待排序記錄r[i]~r[n]中選出最小的記錄,將它與r[i]交換,使有序序列不斷增加直到所有排序完畢。

初始序列:{ 49 27 65 97 76 12 38 }

第1趟:12與49交換:12 { 27 65 97 76 49 38 }

第2趟:27不動:12 27 { 65 97 76 49 38 }

第3趟:65與38交換:12 27 38 { 97 76 49 65 }

第4趟:97與49交換:12 27 38 49 { 76 97 65 }

第5趟:65與76交換:12 27 38 49 65 { 97 76 }

第6趟:97與76交換:12 27 38 49 65 76 97 完成

代碼                                                                                            

public class Sort {
public static void main(String[] args) {
int[] i = { 1, 5, 6, 12, 4, 9, 3, 23, 39, 403, 596, 87 };
System.out.println(
"結果:" );
xuanZe(i);
System.out.println();
}
// 選擇排序算法
public static void xuanZe( int [] x) {
for ( int i = 0; i < x.length; i++ ) {
int lowerIndex = i;
// 找出最小的一個索引
for ( int j = i + 1; j < x.length; j++ ) {
if (x[j] < x[lowerIndex]) {
lowerIndex
= j;
}
}

// 交換
int temp = x[i];
x[i]
= x[lowerIndex];
x[lowerIndex]
= temp;
}
for ( int i : x) {
System.out.print(i
+ " " );
}
}
}

 

時間複雜度爲O(N2)

希爾排序                                                                                      

對於n個元素的數組,假設增量爲 h:

第一趟  :  從第1個元素開始,每隔h取一個元素,那麼最後能夠獲得n/h個元素,一邊取,一邊經過直接插入將這h個元素排序

第二趟  :  從第2個元素開始,每隔h取一個元素,跟第一趟同樣。  

...

第h趟   :  從第h個元素開始,每隔h取一個元素,跟第一趟同樣。

(此時,整個數組還不是有序的)

而後,減小h的值,重複上面的操做,直到h減少爲1,排序完成。

1

代碼                                                                                          

public static void sort( int [] nums) {
int len = nums.length / 2 ;
while (len >=1 ) {
for ( int i = 0; i < len; i++ ) {
// 直接插入排序對分組進行排序
for ( int k = i; k < nums.length-len; k += len) {
int j = k + len;
int temp = nums[j];

while (k >= 0 && nums[k] > temp) {
nums[j]
= nums[k];
k
-= len;
j
-= len;
}

nums[j]
= temp;
}
}
len
= len/2 ;
}
}

時間複雜度是O(N*lgN)

二分插入排序                                                                               

二分查找插入排序的原理:是直接插入排序的一個變種,區別是:在有序區中查找新元素插入位置時,爲了減小元素比較次數提升效率,採用二分查找算法進行插入位置的肯定。

代碼                                                                                           

public class BinarySearch1 {
public static void main(String args[])
{
int array[]={49,38,65,97,76,13,27 };
binarySort(array,array.length);
System.out.println(Arrays.toString(array));
}

// 二分查找
public static int binarySearch( int array[], int low, int high, int temp)
{
int mid=0 ;
while(low<= high)
{
mid
=(low+high)/2 ;
if(array[mid]<temp&&temp<=array[mid+1 ])
return (mid+1 );
else if(array[mid]< temp)
low
= mid + 1 ;
else
high
= mid -1 ;
}
return high;
}

// 二分排序
public static void binarySort( int array[], int size)
{
int i,j,k,temp;
for(i=1;i<size;i++ )
{
temp
= array[i];
if(array[i]<array[0 ])
k
=0 ;
else
k
= binarySearch(array,0 ,i,temp);

for(j=i;j>k;j-- )
{
array[j]
=array[j-1 ];
}
array[k]
= temp;
System.out.println(Arrays.toString(array));
}
}
}

時間複雜度爲O(N2) ;空間複雜度爲O(1)

我是天王蓋地虎的分割線                                                               

1

本文連接:排序(選擇、希爾、二分插入),轉載請註明。

http://www.cnblogs.com/fnng/p/3871712.htmlRobot Framework自動化測試(一)---第一個腳本 - 蟲師 最近工具中用Robot Framework框架來作自動化,。學習記錄是個人習慣,因此,這裏記錄總結,編寫第一個腳本。2014-07-27T10:18:00Z2014-07-27T10:18:00Z蟲師http://www.cnblogs.com/fnng/

 

  最近工具中用Robot Framework框架來作自動化,因此,花時間學習了一下。

 

=======所需環境===================

Python:

https://www.python.org/

RF框架是基於python 的,因此必定要有python環境。

 

Robot framework :

https://pypi.python.org/pypi/robotframework/2.8.5

  這個不是解釋了,RF框架。雖然在作基於UI的自動化時,它展示出來的很像QTP,我以前也覺得它和QTP差很少,仔細瞭解你會發展它能作的事情仍是不少的。就像初學selenium 者,會誤覺得selenium 就是selenium IDE

 

wxPython :

http://www.wxpython.org/download.php

  Wxpython python 很是有名的一個GUI庫,由於RIDE 是基於這個庫開發的,因此這個必須安裝。

 

Robot framework-ride

https://pypi.python.org/pypi/robotframework-ride

  RIDE就是一個圖形界面的用於建立、組織、運行測試的軟件。

 

Robot framework-selenium2library:

https://pypi.python.org/pypi/robotframework-selenium2library/1.5.0

  RF-seleniumlibrary 能夠看作RF版的selenium 庫,selenium webdriver)能夠認爲是一套基於web的規範(API),因此,RF appium 等測試工具均可以基於這套API進行頁面的定位與操做。

----------------------

能夠經過python pip工具包進行安裝:

>pip install robotframework-selenium2library

 

若是初次接觸上面的東西的話,以爲裝的東西有點多。 若是以前有了解過python selenium的話就不會有這樣的感受。

 ================================================

  在你安裝好RF-ride以後,桌面就會生成一個RIDE圖標。雙擊啓動,界面以下:

  

 下面咱們就一步一步的建立第一條用例,至於細節很少解釋,只是對RF框架寫用例有個感性的認識。

 

 

建立測試項目                                          

 選擇菜單欄file----->new Project

Name 輸入項目名稱。

Type 選擇Directory

 

 

建立測試套件                                            

  右鍵點擊「測試項目」選擇new Suite 選項

Name 輸入項目名稱。

Type 選擇File

 

 

建立測試用例                                                  

     右鍵點擊「測試項目」選擇new Test Case 

用例只須要輸入用例name ,點擊OK便可。

 

 

導入selenium2library庫                         

      由於RF框架編寫基於web 的測試用例,因此,咱們須要selenium 的庫支持。因此,咱們在使用的過程當中須要加載selenium2library庫。

在「測試套件」的Edit標籤頁,點擊「Library」按鈕,彈出輸入框,Name輸入:Selenium2Library 點擊OK 完。

若是導入的庫顯示爲紅色,表示導入的庫不存在。若是是黑色則表示導入成功。

 

 

編寫用例                                                      

   下面就能夠開始寫咱們的用例了,但是怎麼寫呢?咱們能夠經過按F5 快捷鍵來查詢腳本的關鍵字。若是你接觸過QTP 或 selenium IDE 等自動化工具的話,應該會有一些思路。

   如上圖,自動化腳本從打開瀏覽器開發,如上圖,我想打開一個瀏覽器,想的是「open」爲關鍵字進行搜索,結果找到了一個「Open Browser」的關鍵字,點擊這個關鍵字,想顯示它的用法和說明。

根聽說明,咱們來嘗試建立這個打開瀏覽器的操做吧:

  「Open Browser」變藍了,說明它是一個合法的關鍵字,後面有一個方框是紅色的,表示這個參數不能缺省的。經過說明信息中,我發現它須要一個url 地址是必填的,固然還須要指定browser (默認不填爲 friefox

  更多關鍵的使用,請參考相關API 文檔。這裏不過多介紹。按照上面的方法。建立百度搜索用例以下:

 

 

運行測試用例                                                

  勾選當前須要運行的測試用例,點擊工具欄運行按鈕,若是隻運行單個用例的話,也能夠切換到用例的Run標籤頁,點擊「start」按鈕。

 

運行信息:

  運行信息顯示會生成三個文件:Output.xmlLog.htmlReport.html

  咱們重點查看Log.htmlReport.html Log.html更關注腳本的執行過程的記錄,Report.html更關注腳本的執行結果的展現。

趕快打開你的測試報告看看效果吧!

 

 

================================================================================

錯誤:

command: pybot.bat --argumentfile c:\users\keikei\appdata\local\temp\RIDEama2ym.d\argfile.txt --listener D:\Python27\lib\site-packages\robotide\contrib\testrunner\TestRunnerAgent.py:52418 E:robot\測試項目

解決:

將「C:\Python27\Scripts 」添加到PATH環境變量中。命令提示符號查看,RF版本。提示pybot 不是內部命令,說明環境變量設置有問題。

 

本文連接:Robot Framework自動化測試(一)---第一個腳本,轉載請註明。

http://www.cnblogs.com/pbendan/p/3871695.html如何創建一個子程序 - pBendan 首先咱們要理解這裏面的「子程序」指的是什麼?在這裏,「子程序」理解爲一個函數比較合適,能夠是一個執行特定功能的全局函數、能夠是一個類裏面的成員函數(注:《代碼大全》裏面之因此用「子程序」來表述,是由於它所講述的規則與方法是與語言無關的,咱們應該根據本身實際編程中所使用的語言來自行定義「子程序」),....2014-07-27T09:56:00Z2014-07-27T09:56:00ZpBendanhttp://www.cnblogs.com/pbendan/

    首先咱們要理解這裏面的「子程序」指的是什麼?在這裏,「子程序」理解爲一個函數比較合適,能夠是一個執行特定功能的全局函數、能夠是一個類裏面的成員函數(注:《代碼大全》裏面之因此用「子程序」來表述,是由於它所講述的規則與方法是與語言無關的,咱們應該根據本身實際編程中所使用的語言來自行定義「子程序」),也能夠這樣理解「子程序」,它是完成某一特定功能的一個小單元,其粒度比模塊要小,而比數據類型、結構控制語句要大。

    綜合《代碼大全》裏面的介紹和本身的理解,將「如何創建一個子程序」分爲三個步驟:1. 之間的準備工做;2. 創建操做;3. 檢查及測試。(其實這是放之四海而皆準的廣泛規則,作任何事情只要遵照這三條都不會有太大問題的,在這裏算是投機取巧了,主要是爲了方便理解和記憶)

  1. 以前的準備工做

問題引起設計,若是沒有需求咱們就不須要去設計一個「子程序」啦。那麼咱們首先就要明確地定義出這個「問題」啦,通常狀況下,這個「問題」在整個的程序框架中會有所說起,而如何那時問題定義比較清晰的話,咱們的準備工做能夠幾乎省去。無論怎麼樣,咱們都要明確幾個問題:

  •  將要設計的「子程序」要完成什麼任務;
  • 「子程序」主要應該在哪些場合,是爲某個模塊定義的功能,仍是適用於整個系統;
  • 「子程序」的輸入、輸出分別是什麼;
  •  創建這個「子程序」須要與系統其餘哪些部分發生關係,須要創建新的數據類型和算法麼;

明確這些之後,咱們的準備工做就作完了,那麼最後爲咱們的「子程序」起一個清晰、直觀、簡介的名字吧!

  2. 創建操做

創建操做的第一步,也是大部分程序員忽視的一個步驟(《代碼大全》裏面這樣說的啊!)——使用PDL(program design language)語言來精確描述「子程序」所執行的操做。

    這一操做是相對於使用具體程序語言編寫「子程序」更抽象、更上一層的操做步驟,抽象並不意味着複雜,反而會更加簡單清晰,以便使後續的編碼、檢查、調試操做更容易。由於使用PDL語言會帶來如下好處:

  • 使用天然語言而不是編程語言來描述「子程序」操做,使程序員沒必要受具體編程語言的語法約束,而將精力放在設計上;
  • 容易查找錯誤,即便查找出錯誤,修改的代價也比較小;
  • 若是PDL語言描述得比較得當,那麼編碼工做就是一個簡單的翻譯工做;
  • 維護起來比較方便,PDL語言爲「子程序」提供了清晰的註釋信息;

    確認PDL描述沒有問題後,能夠着手編寫程序代碼了,若是PDL語言對於「子程序」描述的足夠準確並得當的話,那麼編寫代碼的過程多是一個簡單、機械的工做,程序員應該很快能完成「子程序「設計。

    可是,並非說設計出一個行爲良好的PDL描述就晚上大吉了,有些狀況下,PDL描述看似完美,但將它轉化爲代碼時會出現不少錯誤,因此這是要不檢查是否是代碼自己出錯,或者是PDL語言描述還存在不足,若是是的話,從新用PDL語言描述。

  3. 檢查及測試

在編譯「子程序」以前,程序員有必要進行一些檢查工做:

  1. 「子程序」是否是按照最初的需求?
  2. 完成的任務是否是明確?
  3. 能夠能現的意外狀況?如何解決?
  4. 「子程序」接口設計、實現得合適麼?
  5. 「子程序」會不會有明顯的語法錯誤?

    確認檢查無誤之後,程序員能夠對「子程序」實施測試了,《代碼大全》裏面建議咱們不要急於對「子程序」實施編譯,並試圖經過編譯來查找程序中的錯誤,若是某次編譯出現了錯誤,那麼程序員每每急切萬分得修改以試下次編譯不要出錯,這並非發現並排除錯誤的正確方法。《大碼大全》推薦咱們這樣作:

  1. 本身在內心逐行執行「子程序」,經過本身的「計算機系統」將程序執行一下,試圖找出錯誤並更正;
  2. 編譯「子程序」,消除全部錯誤和警告;
  3. 逐行調試程序,監視程序運行結果,必要狀況下編寫一些輔助代碼幫助程序測試;

 

總結:

    閱讀《代碼大全》關於「子程序」創建這部分,確實對程序員的編程工做有必定啓發,也確實指出了一些有效的方法和容易忽略的問題。下面結合書中介紹的內容和本身的理解談一下自已的認識:

  1. 首先,咱們應該清楚地認識到,書中所談應該是大而全的方法論,實際執行的時候能夠根據具體狀況作酌情取捨。書中所列出的條條目目加起來總共得幾十條,若是咱們所寫的「子程序」是一個功能簡單、邏輯清晰的操做,確實沒有必要按照書中所寫的來逐步進行,這樣反而會下降效率。
  2. 書中介紹使用PDL語言說要使用天然語言,避免設計具體編程語言的引入,這點我認爲過於刻板,PDL語言之因此沒有肯定語法格式,就是爲了能夠抽象地、明瞭地描述「子程序」操做,因此加入具體編程語言的風格、語法何嘗不可,畢竟最終咱們是要使用具體的編程語言來實現功能,加入這些具體編程語言的語法、風格反而使描述效果更貼切。

本文連接:如何創建一個子程序,轉載請註明。

http://www.cnblogs.com/insus/p/3869575.htmlASP.NET開發,簡化與封裝 - Insus.NET 微軟的ASP.NET的開發,就是面向對象的編程,固然前端也能體驗至面向對象的話,使用Web控件也必須的。任一控件,咱們都可以在後端.aspx.cs或.aspx.vb程序中new一個對象出來。不少場合裏,在開發ASP.NET開發中,後端與前端交互,咱們使用控件確實能方便與快捷互通。本篇所涉及的內容以h...2014-07-27T09:50:00Z2014-07-27T09:50:00ZInsus.NEThttp://www.cnblogs.com/insus/

微軟的ASP.NET的開發,就是面向對象的編程,固然前端也能體驗至面向對象的話,使用Web控件也必須的。

任一控件,咱們都可以在後端.aspx.cs或.aspx.vb程序中new一個對象出來。

不少場合裏,在開發ASP.NET開發中,後端與前端交互,咱們使用控件確實能方便與快捷互通。

本篇所涉及的內容以html markup標籤與javascript(或jQuery)無關,由於演示的是Web控件應用。Insus.NET常常會針對開發的應用程序,寫一些經常使用或是特定的對象或是控件。在一塊兒開發的團隊的能句方便用使用,能獲得客戶需求的功能與效果。

開發這些對象或是控件,也並不是一開始就能寫得出來,均是通過一系列編程以後,再次review或是優化的結果。

舉個例子來講明,先在SQL Server數據庫中,建立一個數據表,如[dbo].[UserInfo]:


對這個表,添加幾筆記錄:


寫一個存儲過程,是獲取剛纔添加的全部記錄:

OK,數據庫層已經設計好了,咱們去ASP.NET網站寫程序,須要把這些數據呈現於網頁上。
邏輯層就使用《ASP.NET開發,從二層至三層,至面向對象 (3)http://www.cnblogs.com/insus/p/3826706.html 未來的的博文演示中也會使用它。

在App_Code目錄下,建立一個以數據表名相同的一個類(對象):

 
新建一個網頁.aspx,用它來呈現數據表的數據,直接拉數據控件GridView:



在.aspx.cs代碼中,實現給GridView控件綁定數據:

 

瀏覽一下:


以上的實現,相信不少學習與開發asp.net的人都會,太簡單了,根本不值得一說一提一寫。

 
問題來了,最後一列[Sex],性別具體1代碼是男仍是女,反之亦如此。可否以更友好清晰的表達來表現?下面列幾種網友用常的方法:
第一種方法,寫一個小函數去替換:

 
寫好函數以後,在.aspx的Gridview控件,須要修改,不能使用自動產生列了:


預覽結果:


第二種方法,較爲複雜一些,不過也較常使用的,在.aspx分三步來修改GridView:

 

下面是實現OnRowDataBound="GridView1_RowDataBound":



此種方法預覽結果跟第一種方法是同樣的。

第三種方法,是Insus.NET使用的方法。出現這樣的問題,多數是多表關聯,一張表某些字段是另外一個表的外鍵值。呈現時,均是鍵值或是代號。但實際是須要顯示實際意義的字段。

解決它,能夠建立一個表,是key與value對應的表:



而後修改一下[dbo].[usp_UserInfo_GetAll]存儲過程:

 

在asp.net程序中,在後端無需修心任代碼。


在.aspx頁中的GridView中,僅引用另外一個字段名:


三種方法,均演示完成了。哪種方法,你以爲好,就使參考哪種。

下面有新的要求,客戶要求,將顯示的0或1的信息,使用一張圖片來替代。
這要求不難,用文字「男」或「女」仍是用圖片去替代0或1的方法,均是同樣的。用Image去實現就是了。下面Insus.NET來演示一番:
實現以前,得先準備好兩張圖片,放於站點某一目錄之下。

 

上面有三個步驟標記1至標記3。

 編寫一個私有函數:


而後就能夠寫 OnRowDataBound="GridView1_RowDataBound"事件了:

 

改好了,瀏覽看看效果:

 
上面圖片替換方法,是通用你們所使用的方法。不過Insus.NET的方法,卻不是這樣來作。Insus.NET須要封裝 GetSexImagePath(string num)或是GetSex(string num)函數

另外,由這地方的呈如今一個網站中,也許不止一次(網頁)呈現,在管理員後臺,會員後臺,前端面向全部用戶呈現的網頁均要此樣式呈現。


所以,能夠寫成一個控件便可,先在App_Code建立一個類別SexImg:


有三個public的property以及override方法RenderContents()。重要的一點,是繼承了WebControl類。

接着,咱們打開web.config文件,註冊一下上面咱們建立好的控件:

 

如今的問題是怎樣使用這個控件呢?跟Web控件同樣,沒有什麼分別:

 


在GridView控件內,使用剛纔寫好的控件,直接指寫三個property。

在.aspx.cs內,無需寫什麼代碼:

 

瀏覽的效果,跟上面的同樣:

 

最後一個演示,學會了封裝與建立本身定義控件。Insus.NET雖然只是依性別來舉列,實現開發時,可會趕上不少類別,目錄等相關的。

方法掌握了,類似的功能能夠輕易實現。

 

本文連接:ASP.NET開發,簡化與封裝,轉載請註明。

http://www.cnblogs.com/barros/p/3871652.htmlPDF解決方案(3)--PDF轉SWF - 鐵皮鴨子 相關專題連接PDF解決方案(1)--文件上傳PDF解決方案(2)--文件轉PDFPDF解決方案(3)--PDF轉SWF前言:上一篇中介紹了上傳的文件轉PDF,主要是一些經常使用的文檔格式轉換爲PDF;這一篇主要介紹如何把PDF轉換爲SWF,爲下一步文件在線瀏覽作準備;PDF在線瀏覽的主要如下幾種方式:1...2014-07-27T09:36:00Z2014-07-27T09:36:00Z鐵皮鴨子http://www.cnblogs.com/barros/

相關專題連接

PDF解決方案(1)--文件上傳

PDF解決方案(2)--文件轉PDF

PDF解決方案(3)--PDF轉SWF

前言:上一篇中介紹了上傳的文件轉PDF,主要是一些經常使用的文檔格式轉換爲PDF;這一篇主要介紹如何把PDF轉換爲SWF,爲下一步文件在線瀏覽作準備;

PDF在線瀏覽的主要如下幾種方式:

一、PDF瀏覽器插件

這種方式依賴PDF閱讀器廠商提供的瀏覽器插件,主流的PDF閱讀器如Adobe、福昕在安裝本地客戶端的時候都會附帶安裝這種控件,直接把本地的PDF文件拖到瀏覽器便可看到效果,以下:

 image image

image 

如上圖所示,不一樣閱讀器的插件功能差別較大,不一樣的瀏覽器效果也有不一樣,沒法保證有一個統一的展示效果,並且這種方式必須依賴客戶機安裝上述軟件,有很大的侷限性;

二、使用Jquery插件

這種方式大部分都依賴html5技術,鑑於目前國內的瀏覽器市場佔比,這種方式顯示極其小衆,這裏就再也不介紹了,有興趣的能夠參考:8個實如今線瀏覽PDF文件的實用jQuery插件

三、經過轉換爲SWF來實現

雖然html5技術正在興起,但在目前flash依然受支持比較普遍的技術,經過Flash控件也保證了不一樣瀏覽器相同的展現效果,一些開源的前端控件也提供很好的SWF在線瀏覽體驗,因此這裏咱們就重點介紹這種實現方式;

PDF轉SWF

這裏採用開源軟件swftools,它支持把PDF、圖片、聲音等文件轉換爲SWF文件,而且提供windows和linux版本,能夠在linux環境部署;

swftools下載地址:http://www.swftools.org/download.html

下載安裝後就能夠經過命令行的方式進行調用,pdf2swf提供不少的參數來進行配置,經常使用的如-p設置打開pdf的密碼,-z使用Flash 6的zlib壓縮機制,-s設置更信息的參數(能夠經過pdf2swf -s help來獲取更詳細的參數信息),-o輸出swf文件位置等:

 

image

下面就經過Java代碼啓動系統進程的方式來調用pdf2swf命令進行轉換,Java在啓動進程成功後就會返回,而實際上咱們但願等待文件轉換成功後程序再返回,此時就須要用到Process類了,在Java文檔提到「ProcessBuilder.start() 和 Runtime.exec 方法建立一個本機進程,並返回 Process 子類的一個實例,該實例可用來控制進程並得到相關信息」,利用這一點咱們能夠獲取文件轉換的信息並可讓程序再系統進程結束後再返回,代碼中的dealWith方法就是對Process,詳細轉換代碼以下:

/**
* 把pdf轉換爲swf
*
@param pdfPath pdf文件路徑
*
@throws Exception
*/
public static boolean convert2SWF(String pdfPath) throws Exception
{
String swfFile
= pdfPath.substring(0, pdfPath.lastIndexOf("." ))
+ ".swf" ;
File outFile
= new File(swfFile);
if (outFile.exists())
{
return true ;
}

File pdfFile
= new File(pdfPath);
if (! pdfFile.exists())
{
return false ;
}

// 建立調用swftools命令list
List<String> command = new ArrayList<String> ();
command.add(
"c:\\SWFTools\\pdf2swf"); // pdf2swf命令路徑
command.add("-z" );
command.add(
"-s" );
command.add(
"flashversion=9" );
command.add(
"-s" );
command.add(
"languagedir=C:\\xpdf\\xpdf-chinese-simplified"); // 添加xpdf解決轉換時出現的字符集問題
command.add(pdfPath);
command.add(
"-o" );
command.add(swfFile);

/**
* java啓動系統進程時,啓動成功後就直接返回了,並不會等待系統進程執行結束,這裏咱們須要等待系統進程調用結束後java方法再返回
*/
try
{
// 建立系統進程
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command(command);
// 設置系統進程要執行的系統程序和參數
Process process = processBuilder.start(); // 使用此進程生成器的屬性啓動一個新進程
dealWith(process);
try
{
process.waitFor();
// 等待子進程的結束,子進程就是系統調用文件轉換這個新進程
} catch (InterruptedException e)
{
throw new Exception(e.getMessage());
}
}
catch (IOException e)
{
throw new Exception(e.getMessage());
}
return true ;
}

/**
* 處理進程的IO防止出現阻塞、死鎖等狀況
*
@param pro
*
@throws
*/
private static void dealWith( final Process pro)
{
// 下面是處理堵塞的狀況
try
{
// 啓動單獨線程來清空pro.getInputStream()的緩衝區
new Thread() {
public void run()
{
BufferedReader br1
= new BufferedReader(
new InputStreamReader(pro.getInputStream()));
try
{
String text;
while ((text = br1.readLine()) != null )
{
System.out.println(text);
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}.start();
}
catch (Exception e)
{
e.printStackTrace();
}

try
{
// 不要忘記處理出理時產生的錯誤信息,否則會堵塞不前的
new Thread() {
public void run()
{
BufferedReader br2
= new BufferedReader(
new InputStreamReader(pro.getErrorStream()));
String text;
try
{
while ((text = br2.readLine()) != null )
{
System.err.println(text);
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}.start();
}
catch (Exception e)
{
e.printStackTrace();
}
}

 

上面的代碼中在建立swftools命令行時使用了參數 -s languagedir=C:\\xpdf\\xpdf-chinese-simplified,這裏的地址對應的是另一個工具xpdf,swftools自己會支持一些字體,可是當pdf中存在它不支持的字體時就會報錯,以下圖,此時咱們就須要用到xpdf,Xpdf 是一個開源的PDF文件瀏覽器,經過語言包能夠很好的支持中文,而且提供了windows和linux版本,能夠跨平臺部署

image

xpdf:ftp://ftp.foolabs.com/pub/xpdf/xpdfbin-win-3.04.zip

語言包:ftp://ftp.foolabs.com/pub/xpdf/xpdf-chinese-simplified.tar.gz

xpdf解壓放到C盤根目錄便可,語言包解壓放到xpdf的根目錄中,修改xpdf-chinese-simplified的文件add-to-xpdfrc,添加須要的字體目錄和要展現的具體字體,而後在swftools命令中經過參數指定語言包目錄便可

image

相關文件下載:

PDF解決方案demo: http://pan.baidu.com/s/1i3mmwux

swftools、xpdf:http://pan.baidu.com/s/1dDu1Yoh(注:解壓放在C盤根目錄便可)

本文連接:PDF解決方案(3)--PDF轉SWF,轉載請註明。

http://www.cnblogs.com/Enumz/p/3871651.html算法總結之拓撲排序 - Enumz 拓撲排序1.通常應用 拓撲排序經常使用來肯定一個依賴關係集中,事物發生的順序。例如,在平常工做中,可能會將項目拆分紅A、B、C、D四個子部分來完成,但A依賴於B和D,C依賴於D。爲了計算這個項目進行的順序,可對這個關係集進行拓撲排序,得出一個線性的序列,則排在前面的任務就是須要先完成的任務。2.實現.....2014-07-27T09:35:00Z2014-07-27T09:35:00ZEnumzhttp://www.cnblogs.com/Enumz/

拓撲排序

1.通常應用

      拓撲排序經常使用來肯定一個依賴關係集中,事物發生的順序。例如,在平常工做中,可能會將項目拆分紅A、B、C、D四個子部分來完成,但A依賴於B和D,C依賴於D。爲了計算這個項目進行的順序,可對這個關係集進行拓撲排序,得出一個線性的序列,則排在前面的任務就是須要先完成的任務。

2.實現的基本方法

  (1)從有向圖中選擇一個沒有前驅(即入度爲0)的頂點而且輸出它.

  (2)從網中刪去該頂點,而且刪去從該頂點發出的所有有向邊.

  (3)重複上述兩步,直到剩餘的網中再也不存在沒有前趨的頂點爲止.

3.C++版本實現

1 /* 以鄰接矩陣Edge[A][B]=N存放圖信息:A指向B,權值爲N */
2 /* 假設不相連的邊的Edge==INT_MAX */
3 void Topo()
4 {
5 sort(Edge+ 1,Edge+N+ 1 );
6 for ( int i= 1; i<=N; i++ )
7 {
8 int j;
9 for (j= 1; j<=N; i++) // vis爲標記數組,標記是否已經存在在Topo數組中
10 if (!vis[j]&&! in[j]) // in數組表示的下標頂點的入度
11 {
12 Topo[i]= j;
13 vis[j]= 1 ;
14 break ;
15 }
16 for ( int k= 1;k<=N;k++) // 將與j點相連的頂點的入度刷新
17 if (Edge[j][k]!= INT_MAX)
18 in[k]-- ;
19 }
20 }

4.反向建圖

  拓撲排序並不必定惟一,有時會要求頂點數值大的儘可能在前,這個時候應該反向建圖,再進行拓撲排序,來保證更多小數值頂點在後面。(貪心思想?)

  Eg:HDU 4857 POJ 3687(反向建圖+拓撲排序)

5.優化

  拓撲排序每次選擇一個頂點進入序列後,要更新全部與這個頂點相連的頂點的入度。而上面的代碼全是把全部的頂點都遍歷了一邊。

  這裏能夠使用鄰接表或者鏈式前向星這一類數據結構,來記錄圖的信息,能夠作到只遍歷與該頂點相連的頂點

6.優先隊列實現

1 /* 優先隊列+鄰接表實現拓撲排序 */
2 void Topo()
3 {
4 priority_queue< int> que;
5 for ( int i= 1; i<=N; i++) // 將入度爲零的頂點壓入隊列
6 if (dis[i]== 0 )
7 que.push(i);
8 int p=N+ 1 ;
9 while (! que.empty())
10 {
11 int tmp= que.top();
12 que.pop();
13 topo[--p]=tmp; // 存入topo數組
14 int z= first[tmp];
15 while (z!=- 1) // 鄰接表遍歷與tmp相連的頂點
16 {
17 dis[end[z]]--; // 入度減一
18 if(! dis[end[z]]) que.push(end[z]);
19 z= next[z];
20 }
21 }
22 }

本文連接:算法總結之拓撲排序,轉載請註明。

http://www.cnblogs.com/f1194361820/p/3871633.html Spring源碼閱讀:IOC容器的設計與實現(二)——ApplicationContext - 螺 絲 釘 上一主題中,瞭解了IOC容器的基本概念,以及BeanFactory的設計與實現方式,這裏就來了解一下ApplicationContext方式的實現。ApplicationContext 在Spring的參考文檔中,爲啥要推薦使用ApplicationContext?它能給咱們的應用帶來什麼好處呢?做...2014-07-27T09:25:00Z2014-07-27T09:25:00Z螺 絲 釘http://www.cnblogs.com/f1194361820/

 

 上一主題中,瞭解了IOC容器的基本概念,以及BeanFactory的設計與實現方式,這裏就來了解一下ApplicationContext方式的實現。

 

ApplicationContext

 

    在Spring的參考文檔中,爲啥要推薦使用ApplicationContext?它能給咱們的應用帶來什麼好處呢?做爲BeanFactory的實現之一,它又是如何設計的?在SpringMVC中使用的WebApplictionContext\XmlApplicationContext與之有何關聯?

    ApplicationContext與BeanFactory:

 

 

從類圖中,能夠明顯的看出ApplicationContext是做爲BeanFactory的子接口呈現的。可是它又在BeanFactory的基礎上添加了新的特性:MessageSource(消息支持,例如國際化),ApplicationEventPublisher(事件支持),ResourcePatternResolver(解析資源)。

 

 

AbstractApplicationContext

在ApplicationContext的實現類AbstractApplicationContext已經基本上實現了ApplicationContext的功能。

 

/**

* Abstract implementation of the {
@link org.springframework.context.ApplicationContext}

* interface. Doesn't mandate the type of storage used for configuration; simply

* implements common context functionality. Uses the Template Method design pattern,

* requiring concrete subclasses to implement abstract methods.

*

* <p>In contrast to a plain BeanFactory, an ApplicationContext is supposed

* to detect special beans defined in its internal bean factory:

* Therefore, this class automatically registers

* {
@link org.springframework.beans.factory.config.BeanFactoryPostProcessor BeanFactoryPostProcessors},

* {
@link org.springframework.beans.factory.config.BeanPostProcessor BeanPostProcessors}

* and {
@link org.springframework.context.ApplicationListener ApplicationListeners}

* which are defined as beans in the context.

*

* <p>A {
@link org.springframework.context.MessageSource} may also be supplied

* as a bean in the context, with the name "messageSource"; otherwise, message

* resolution is delegated to the parent context. Furthermore, a multicaster

* for application events can be supplied as "applicationEventMulticaster" bean

* of type {
@link org.springframework.context.event.ApplicationEventMulticaster}

* in the context; otherwise, a default multicaster of type

* {
@link org.springframework.context.event.SimpleApplicationEventMulticaster} will be used.

*

* <p>Implements resource loading through extending

* {
@link org.springframework.core.io.DefaultResourceLoader}.

* Consequently treats non-URL resource paths as class path resources

* (supporting full class path resource names that include the package path,

* e.g. "mypackage/myresource.dat"), unless the {
@link #getResourceByPath}

* method is overwritten in a subclass.

*/

 

上面的描述的大體意思是: 

一、這個類是對ApplicationContext的抽象的實現,並不會指定使用哪一種bean definition 配置策略。它完成了各類ApplicationContext的通用的實現。在設計這個類時,使用了模板方法設計模式,有的方法須要在具體的子類中實現。

二、與BeanFactory相比,ApplicationContxt中能夠把BeanFactoryPostProcessor、BeanPostProcessor、ApplicationListener做爲一個普通的Bean定義。

三、在ApplicationContext中也能夠使用MessageSource,使用它時用的name是"messageSource"。同時也能夠使用ApplicationEventMulticaster(name是"applicationEventMulticaster"),若是不指定,默認使用的是:SimpleApplicationEventMulticaster。

四、經過繼承DefaultResourceLoader方式實現了資源文件的加載。

 

接下來看看這個類的繼承關係:

 

 

從類圖中能夠看出AbstractApplicationContext主要分爲兩支:   ·AbstractRefreshWebApplicationContext(主要用於Web環境下)

    ·AbstractXmlApplicationContext(主要用於非Web環境下)

 

對於AbstractRefreshWebApplicationContext,從配置類別上分爲兩類:使用Annotation配置或者使用XML文件配置。

 

對於AbstractXmlApplicationContext,採用的是XML做爲Bean定義的配置文件,它的兩個子類的區別是從哪裏去加載bean定義件。

 下一節,就能夠看看ApplicationContext是如何初始化IOC容器的。

 

本文連接:Spring源碼閱讀:IOC容器的設計與實現(二)——ApplicationContext,轉載請註明。

http://www.cnblogs.com/senlie/p/3871617.html大數據技術 —— MapReduce 簡介 - senlie zheng 本文爲senlie原創,轉載請保留此地址:http://www.cnblogs.com/senlie/1.概要不少計算在概念上很直觀,但因爲輸入數據很大,爲了能在合理的時間內完成,這些計算必須分佈在數以百計數以千計的機器上。例如處理爬取獲得的文檔、網頁請求日誌來計算各類衍生數據,如倒排索引,網頁文檔...2014-07-27T09:16:00Z2014-07-27T09:16:00Zsenlie zhenghttp://www.cnblogs.com/senlie/

本文爲senlie原創,轉載請保留此地址:http://www.cnblogs.com/senlie/

1.概要
不少計算在概念上很直觀,但因爲輸入數據很大,爲了能在合理的時間內完成,這些計算
必須分佈在數以百計數以千計的機器上。例如處理爬取獲得的文檔、網頁請求日誌來計算
各類衍生數據,如倒排索引,網頁文檔的各類圖結構表示,從每一個主機上爬取的文檔數,
在某一天最頻繁的查詢的集合。

MapReduce 是爲處理和生成大數據集的編程模式和相應的實現。
用戶指定一個 map 函數來處理一個鍵值對來生成一個鍵值對的集合,
和一個 reduce 函數來合併具備相同中間鍵的實值。

例如,有大一堆文檔,要統計裏面每個文檔的出現的次數。能夠這樣寫map 函數和 reduce 函數

map(String key, String value):
//key: document name
//value: document contents
for each word w in value:
EmitIntermediate(w, '1');
reduce(String key, Iterator values):
//key: a word
//values: a list of counts
int result = 0;
for each v in values:
result += ParseInt(v);
Emit(AsString(result));

  

??疑問:map 返回的是一個 key/value ,爲何到了 resuce 這的輸入卻變成了 key/list of values ,這中間
發生了什麼?
解答:
map 函數接受一個鍵值對(如上面例子中的文檔名/文檔內容)併產生一組鍵值對(單詞/1)。在將這組
鍵值對傳給 reduce 函數以前, MapReduce 庫會組合全部具備相同鍵值的實值產生新的一組鍵/值(單詞/次數)。
reduce 函數接受來自多個 map 函數產生的鍵值對,它們在被 reduce 函數處理前,會先被 MapReduce 庫組合成
鍵/值列表(單詞/次數列表)。下圖解釋了這一過程。
(聲明:圖來自實驗室 adonis 同窗的 seminar 展現ppt)

2.MapReduce 的執行的大概流程
經過將輸入數據劃分爲 M 個分片, map 函數的調用分佈在多臺機器上,這些分片可同
不一樣的機器並行地處理。
經過將中間結果的鍵空間劃分爲 R 個分片, reduce 函數的調用分佈在多臺機器上。
下圖展現了 MapReduce 操做的整個流程。

1). 客戶程序中的 MapReduce 庫首先將輸入文件分紅 M 個大小一般爲 16MB 或者64MB 的分片。
而後開始在集羣上的機器複製客戶程序
2).其中有一個程序的備份是特殊的,它就是主節點。其它的是由主節點分配任務的從節點。
主節點有 M 個 map 任務和 R 個 reduce 任務要分配給那些空閒的從節點。
3).一個被分配了 map 任務的從節點從輸入分片中讀取內容,而後從輸入中解析出鍵值對被傳遞給
用戶定義的 map 函數,由它來產生中間結果的鍵值對並緩存在內存中
4).在內存中的鍵值對被週期性地寫入到本地磁盤,經過分片函數被分紅 R 個分片。
這些分片的位置被回傳給主節點,由主節點告訴 reduce 從節點它們的位置
5).當 reduce 從節點被主節點告知分片的位置時,它從使用 RPC(remote procedure call) 去讀取
那些緩存數據,當讀完後,它會按鍵值進行排序,而後將有相同鍵值的鍵值對組合在一塊兒,造成鍵/值列表
6).reduce 從節點遍歷已經排序合併好了的中間數據,將每個鍵/值列表對傳遞給客戶定義的 reduce 函數。
reduce 函數返回的結果被添加到這個 reduce 從節點的結果文件中。
7).當全部 map 從節點和 reduce 從節點完成後,主節點喚醒客戶程序。
若是 MapReduce 程序成功完成,結果文件被存儲在 R 個輸出文件中。

3.示例
這個示例統計了一組輸入文件裏每一個單詞的出現次數

#include "mapreduce/mapreduce.h"
//user's map function
class WordCounter : public Mapper{
public:
virtual void Map(const MapInput &input){
const string &text = input.value();
const int n = text.size();
for(int i = 0; i < n; ){
//忽略單詞前空格
while(i < n && isspace(text[i])) i++;
//找到單詞的結尾
int start = i;
while(i < n && !isspace(text[i])) i++;
if(start < i) Emit(text.substr(start, i - start), "1");

}
}
};
REGISTER_MAPPER(WordCounter); // 這個是幹嗎用的??

//User's reduce function
class Adder : public Reducer {
// 這裏不用加個 public 的關鍵字?
virtual void Reduce(ReduceInput *input){
//把有相同鍵值的數值加起來
int64 value = 0;
while(!input->done()){
value != StringToInt(input->value());
input->NextValue();
}
Emit(IntToString(value));
}
}
REGISTER_REDUCER(Adder);

int main(int argc, char **argv){
ParseCommandLineFlags(argc, argv);
MapReduceSpecification spec;

//把輸入文件列表存入 "spec"
for(int i = 1; i < argc; i++){
MapReduceInput *input = spec.add_input();
input->set_format("text");
input->set_filepattern(argv[i]);
input->set_mapper_class("WordCounter");
}
//指定輸出文件
MapReduceOutput *out = spec.output();
out->set_filebase("gfs/test/freq");
out->set_num_tasks(100);
out->set_format("text");
out->set_reducer_class("Adder");

//可選:在 map 節點中作部分和運算以節省帶寬
out->set_combiner_class("Adder");

//調節參數:使用最多2000臺機器,每一個任務最多100MB內存
spec.set_machines(2000);
spec.set_map_megabytes(100);
spec.set_reduce_megabytes(100);

//開跑
MapReduceResult result;
if(!MapReduce(spec, &result)) abort();

//失敗的時候 abort, 能運行在這裏就是成功了。
return 0;
}

  


參考:
MapReduce: Simplified Data Processing on Large Clusters

本文連接:大數據技術 —— MapReduce 簡介,轉載請註明。

http://www.cnblogs.com/aexin/p/3871613.html04-1. 水仙花數(20) - aexin 水仙花數是指一個N位正整數(N>=3),它的每一個位上的數字的N次冪之和等於它自己。例 如:153 = 13+ 53+ 33。 本題要求編寫程序,計算全部N位水仙花數。輸入格式:輸入在一行中給出一個正整數N(3 2 3 int main() 4 { 5 int n; 6 scanf(...2014-07-27T09:12:00Z2014-07-27T09:12:00Zaexinhttp://www.cnblogs.com/aexin/

水仙花數是指一個N位正整數(N>=3),它的每一個位上的數字的N次冪之和等於它自己。例 如:153 = 13 + 53+ 33。 本題要求編寫程序,計算全部N位水仙花數。

輸入格式:

輸入在一行中給出一個正整數N(3<=N<=7)。

輸出格式:

按遞增順序輸出全部N位水仙花數,每一個數字佔一行。

輸入樣例:

3

輸出樣例:

153
370
371
407



1 #include <stdio.h>
2
3 int main()
4 {
5 int n;
6 scanf( " %d ", & n);
7
8 int i, low = 1, high; // low表示n位數的最小數,high表示n位數的最大數
9 for(i = 1; i < n; i++ ) {
10 low *= 10 ;
11 }
12 high = low * 10 ;
13 for(i = low; i < high; i++ ) { // 從最小數到最大數逐一遍歷
14 int t = i;
15 int sum = 0 ;
16 do {
17 int r = t % 10; // r爲數的末尾數字
18 t /= 10 ;
19 int j, b = r;
20 for(j = 1; j < n; j++) { // 讓r自乘最後獲得r的n次方
21 r *= b;
22 }
23 sum += r;
24 } while(t > 0 );
25 if(sum == i) { // 讓r的n次方和i比較
26 printf( " %d\n " , i);
27 }
28 }
29
30 return 0 ;
31 }

 




本文連接:04-1. 水仙花數(20),轉載請註明。

http://www.cnblogs.com/hook-haifeng/p/3871606.htmlthinkphp多表查詢 - Mapleth 在學習thinkphp 的過程當中,須要對多表進行操做,可是在實際過程當中,老是遇到各類問題,因此寫下這篇博文,做爲本身的學習歷程在操做過程當中,兩表查詢都沒有問題,可是三表查詢就開始出現問題有如下三張表,分表爲pl表(uid,content),user表(id,username),lyb表(uid,ti...2014-07-27T09:11:00Z2014-07-27T09:11:00ZMaplethhttp://www.cnblogs.com/hook-haifeng/

在學習thinkphp 的過程當中,須要對多表進行操做,可是在實際過程當中,老是遇到各類問題,因此寫下這篇博文,做爲本身的學習歷程

在操做過程當中,兩表查詢都沒有問題,可是三表查詢就開始出現問題

有如下三張表,分表爲pl表(uid,content),user表(id,username),lyb表(uid,title)

多表查詢操做有如下幾種方法:

㈠視圖模型(推薦)

定義視圖模型,只須要繼承Think\Model\ViewModel,而後設置viewFields屬性便可

public $viewFields = array (
'pl' => array('uid','rid','content'),
'user' => array('id','username','_on'=>'pl.uid=user.id'),
'lyb' => array('uid'=>'lid','content'=>'lyb_content','title','_on'=>'pl.uid=lyb.uid'), //若是表中有字段重名,能夠經過=>設置別名,'uid'=>'lid'
);

視圖查詢:

視圖查詢和不一樣模型的查詢同樣,沒有什麼區別。

$Model = D("pl") ->field('uid,title,username,lyb_content')->select(); //pl爲數據庫名

若是發現查詢的結果存在重複數據,還能夠使用group方法來處理。

㈡join

JOIN方法也是連貫操做方法之一,用於根據兩個或多個表中的列之間的關係,從這些表中查詢數據。

join一般有下面幾種類型,不一樣類型的join操做會影響返回的數據結果。

  • INNER JOIN: 若是表中有至少一個匹配,則返回行,等同於 JOIN
  • LEFT JOIN: 即便右表中沒有匹配,也從左表返回全部的行
  • RIGHT JOIN: 即便左表中沒有匹配,也從右表返回全部的行
  • FULL JOIN: 只要其中一個表中存在匹配,就返回行

join方法能夠支持以上四種類型:

一樣是對以上三張表進行操做

$Model = D("pl")
         
 -> join('lyb on pl.uid = lyb.uid' )
          
-> join('user on pl.uid = user.id' )
          ->field('user.username,lyb.title,pl.content' )
          
->select();

 

㈢table

table方法也屬於模型類的連貫操做方法之一,主要用於指定操做的數據表。

用法

通常狀況下,操做模型的時候系統可以自動識別當前對應的數據表,因此,使用table方法的狀況一般是爲了:

  1. 切換操做的數據表;
  2. 對多表進行操做;                                                                                                                                                                                          
    $Model = D("pl" )
      
    ->field('pl.content,user.username,lyb.title' )
      
    ->table('pl,lyb,user' )
      
    ->limit(10 )
      
    ->select();

    注:table方法默認查詢的是全部字段的值

本文連接:thinkphp多表查詢,轉載請註明。

http://www.cnblogs.com/jack-1900/p/3871607.html詳解Android定位 - JackCho 移動互聯時代,社交APP火熱,應運而生大量基於LBS的興趣點。本文將從三個方面講解如何獲取用戶的實時位置。2014-07-27T09:11:00Z2014-07-27T09:11:00ZJackChohttp://www.cnblogs.com/jack-1900/

相信不少的朋友都有在APP中實現定位的需求,今天我就再次超炒冷飯,爲你們獻上國內開發者經常使用到的三種定位方式。它們分別爲GPS,百度和高德,慣例先簡單介紹下定位的背景知識。

什麼是GPS定位、基站定位和Wi-Fi定位?

一、GPS定位:根據設備GPS芯片和GPS衛星實現定位,GPS定位在室內是不能夠使用的。GPS定位精度和芯片自己以及實際使用環境有關,通常狀況下,GPS定位精度在10m左右。

二、基站定位:根據設備獲取的基站信息實現定位,基站定位精度通常不受使用環境影響,主要和基站的覆蓋半徑有關。基站定位服務精度目前在200m左右。

三、Wi-Fi定位:根據設備獲取的Wi-Fi的信息進行定位,Wi-Fi定位精度通常不受使用環境影響,主要和Wi-Fi半徑,密度有關。Wi-Fi定位精度目前在20m左右。

目前智能手機都內置了GPS芯片,相對應的各個手機系統廠商也開放了對外的GPS接口。可是因爲GPS受外界因素影響比較大,通常的APP也都是室內使用,因此嚴重影響到了GPS搜星的數量。不過之前在外包公司接手過這麼一個項目,主要面向室外的騎行愛好者使用,知足他們騎行路線的繪製。面對這樣一個需求,GPS定位是最靠譜的選擇了,可是傷不起的耗電量呀。

因此通常比較靠譜的方式,就是使用百度高德這些企業爲開發者提供的成熟方案,能夠選擇混合定位的方式以應對APP複雜的實際使用狀況。混合定位就是使用以上三種定位技術,選擇最優的方式去獲取當前的地理位置。下面來介紹下今天爲你們帶來的簡單實踐。

1、GPS定位

沒有特別的業務需求,請慎用GPS定位,選用NETWORK_PROVIDER是個不錯的選擇。另外,你們有沒有發注意到,經過GPS能夠獲取當前時間,在獲取不到準確時間的時候是個不錯的選擇。

 

二、百度定位

 

百度定位的location裏包含了不少的信息,足以應付咱們工做的須要了。百度定位Jar包大小180Kb,相對來講仍是能夠接受的。百度的三種定位策略也正好是對應上述咱們背景介紹的三種定位技術。

3、高德定位

 

高德定位回調的位置信息也是比較豐富的,並且依賴包大小140kb,通常我工做中定位都是用高德。

備註:經過Android系統的LocationManager去定位也是滿靠譜的,室外需求使用GPS provider,室內使用Network provider;定位的經度和效率也是能夠接受的,並且還不用依賴第三方包,不會增長程序的體積。可是不少業務情形下,咱們不止想獲得簡單的經緯度信息,咱們還須要城市、郵編、具體的位置等信息。

代碼地址:https://github.com/JackCho/LocationDemo

若是以爲對你有所幫助,歡迎你們訂閱個人微信公衆帳號——Android乾貨分享(ID:android_share)。下面是微信的二維碼,爲你提供及時高質的Android乾貨。

本文連接:詳解Android定位,轉載請註明。

http://www.cnblogs.com/justconnor/p/3871548.html數據字典生成工具 - justconnor 以前找的數據庫字典生成工具基本上都依賴於 Office Com 組件,在不安裝 Office的狀況下沒法使用。怒,因而本身用C# 寫了一個。 特徵以下: 1、支持的數據庫 MS SQL Server 2005+、My Sql、Oracle 2、支持的文檔類型 HTML、CHM、 WOR...2014-07-27T08:39:00Z2014-07-27T08:39:00Zjustconnorhttp://www.cnblogs.com/justconnor/

 

  以前找的數據庫字典生成工具基本上都依賴於 Office Com 組件,在不安裝 Office的狀況下沒法使用。怒,因而本身用C# 寫了一個。

    特徵以下:
        1、支持的數據庫 MS SQL Server 2005+、My Sql、Oracle
        2、支持的文檔類型 HTML、CHM、 WORD
        3、無需安裝辦公軟件便可生成 WORD 格式的文件
        4、基於 .net framework 3.5 框架,電腦上須要安裝 .net framework 3.5。
        
    PS:歡迎反饋BUG ,反饋方式 戳 About 窗口的 E-Mail 發郵件 給我。
        
 

 

本文連接:數據字典生成工具,轉載請註明。

http://www.cnblogs.com/eastsea/p/3865852.html DBA_Oracle日誌文件 - altert / trace /audit / redo / archive log(概念) - 東方瀚海 2014-07-26 BaoXinjian1、摘要1. 日誌簡稱日誌通常指的是聯機重作日誌文件(Redlog)。主要功能是恢復異常關閉的數據庫和保證數據的完整性、一致性。還有可恢復近期丟失的數據(這要看重作日誌文件的容量)。重作文件的原理是:把DML(Insert、Update、Delete)語句所... 2014-07-27T08:27:00Z 2014-07-27T08:27:00Z 東方瀚海 http://www.cnblogs.com/eastsea/ 【摘要】2014-07-26 BaoXinjian1、摘要1. 日誌簡稱日誌通常指的是聯機重作日誌文件(Redlog)。主要功能是恢復異常關閉的數據庫和保證數據的完整性、一致性。還有可恢復近期丟失的數據(這要看重作日誌文件的容量)。重作文件的原理是:把DML(Insert、Update、Delete)語句所... 閱讀全文http://www.cnblogs.com/2050/p/3871517.html性能更好的js動畫實現方式——requestAnimationFrame - 無雙 用js來實現動畫,咱們通常是藉助setTimeout或setInterval這兩個函數,css3動畫出來後,咱們又能夠使用css3來實現動畫了,並且性能和流暢度也獲得了很大的提高。可是css3動畫仍是有很多侷限性,好比不是全部屬性都能參與動畫、動畫緩動效果太少、沒法徹底控制動畫過程等等。因此有的時候...2014-07-27T08:16:00Z2014-07-27T08:16:00Z無雙http://www.cnblogs.com/2050/

用js來實現動畫,咱們通常是藉助setTimeout或setInterval這兩個函數,css3動畫出來後,咱們又能夠使用css3來實現動畫了,並且性能和流暢度也獲得了很大的提高。可是css3動畫仍是有很多侷限性,好比不是全部屬性都能參與動畫、動畫緩動效果太少、沒法徹底控制動畫過程等等。因此有的時候咱們仍是不得不使用setTimeout或setInterval的方式來實現動畫,但是setTimeout和setInterval有着嚴重的性能問題,雖然某些現代瀏覽器對這兩函個數進行了一些優化,但仍是沒法跟css3的動畫性能相提並論。這個時候,就該requestAnimationFrame出馬了。

requestAnimationFrame 是專門爲實現高性能的幀動畫而設計的一個API,目前已在多個瀏覽器獲得了支持,包括IE10+,Firefox,Chrome,Safari,Opera等,在移動設備上,ios6以上版本以及IE mobile 10以上也支持requestAnimationFrame,惟一比較遺憾的是目前安卓上的原生瀏覽器並不支持requestAnimationFrame,不過對requestAnimationFrame的支持應該是大勢所趨了,安卓版本的chrome 16+也是支持requestAnimationFrame的。

requestAnimationFrame 比起 setTimeout、setInterval的優點主要有兩點:

一、requestAnimationFrame 會把每一幀中的全部DOM操做集中起來,在一次重繪或迴流中就完成,而且重繪或迴流的時間間隔牢牢跟隨瀏覽器的刷新頻率,通常來講,這個頻率爲每秒60幀。

二、在隱藏或不可見的元素中,requestAnimationFrame將不會進行重繪或迴流,這固然就意味着更少的的cpu,gpu和內存使用量。

像setTimeout、setInterval同樣,requestAnimationFrame是一個全局函數。調用requestAnimationFrame後,它會要求瀏覽器根據本身的頻率進行一次重繪,它接收一個回調函數做爲參數,在即將開始的瀏覽器重繪時,會調用這個函數,並會給這個函數傳入調用回調函數時的時間做爲參數。因爲requestAnimationFrame的功效只是一次性的,因此若想達到動畫效果,則必須接二連三的調用requestAnimationFrame,就像咱們使用setTimeout來實現動畫所作的那樣。requestAnimationFrame函數會返回一個資源標識符,能夠把它做爲參數傳入cancelAnimationFrame函數來取消requestAnimationFrame的回調。怎麼樣,是否是也跟setTimeout的clearTimeout很類似啊。

因此,能夠這麼說,requestAnimationFrame就是一個性能優化版、專爲動畫量身打造的setTimeout,不一樣的是requestAnimationFrame不是本身指定回調函數運行的時間,而是跟着瀏覽器內建的刷新頻率來執行回調,這固然就能達到瀏覽器所能實現動畫的最佳效果了。

目前,各個支持requestAnimationFrame的瀏覽器有些仍是本身的私有實現,因此必須加前綴,對於不支持requestAnimationFrame的瀏覽器,咱們只能使用setTimeout,由於二者的使用方式幾近相同,因此這二者的兼容並不難。對於支持requestAnimationFrame的瀏覽器,咱們使用requestAnimationFrame,而不支持的咱們優雅降級使用傳統的setTimeout。把它們封裝一下,就能獲得一個統一兼容各大瀏覽器的API了。

代碼能夠到這裏來查看:https://gist.github.com/chaping/88813f56e75b0fd43f8c

var lastTime = 0 ;
var prefixes = 'webkit moz ms o'.split(' '); // 各瀏覽器前綴

var requestAnimationFrame = window.requestAnimationFrame;
var cancelAnimationFrame = window.cancelAnimationFrame;

var prefix;
// 經過遍歷各瀏覽器前綴,來獲得requestAnimationFrame和cancelAnimationFrame在當前瀏覽器的實現形式
for( var i = 0; i < prefixes.length; i++ ) {
if ( requestAnimationFrame && cancelAnimationFrame ) {
break ;
}
prefix
= prefixes[i];
requestAnimationFrame
= requestAnimationFrame || window[ prefix + 'RequestAnimationFrame' ];
cancelAnimationFrame
= cancelAnimationFrame || window[ prefix + 'CancelAnimationFrame' ] || window[ prefix + 'CancelRequestAnimationFrame' ];
}

// 若是當前瀏覽器不支持requestAnimationFrame和cancelAnimationFrame,則會退到setTimeout
if ( !requestAnimationFrame || ! cancelAnimationFrame ) {
requestAnimationFrame
= function ( callback, element ) {
var currTime = new Date().getTime();
// 爲了使setTimteout的儘量的接近每秒60幀的效果
var timeToCall = Math.max( 0, 16 - ( currTime - lastTime ) );
var id = window.setTimeout( function () {
callback( currTime
+ timeToCall );
}, timeToCall );
lastTime
= currTime + timeToCall;
return id;
};

cancelAnimationFrame
= function ( id ) {
window.clearTimeout( id );
};
}

// 獲得兼容各瀏覽器的API
window.requestAnimationFrame = requestAnimationFrame;
window.cancelAnimationFrame
= cancelAnimationFrame;

這樣子咱們就能在全部瀏覽器上使用requestAnimationFrame和cancelAnimationFrame了。

下面舉個簡單的例子來講明怎麼運用requestAnimationFrame進行動畫,下面的代碼會將id爲demo的div以動畫的形式向右移動到300px

< div id ="demo" style ="position:absolute; width:100px; height:100px; background:#ccc; left:0; top:0;" ></ div >

< script >
var demo = document.getElementById( ' demo ' );
function rander(){
demo.style.left
= parseInt(demo.style.left) + 1 + ' px ' ; // 每一幀向右移動1px
}
requestAnimationFrame(
function (){
rander();
// 當超過300px後才中止
if (parseInt(demo.style.left) <= 300 ) requestAnimationFrame(arguments.callee);
});
</ script >

 

參考資料:

http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/

http://msdn.microsoft.com/zh-cn/library/ie/hh920765(v=vs.85).aspx

https://developer.mozilla.org/zh-CN/docs/Web/API/window.requestAnimationFrame

本文連接:性能更好的js動畫實現方式——requestAnimationFrame,轉載請註明。

http://www.cnblogs.com/workest/p/3871515.html我給女友講編程-題外話系列(1)--懼怕過七夕,不知道買什麼禮物 - 拼命工做 我女友在外地出差,日常可以作的就是打打電話,聊聊天。下週六就是中國的情人節了。說實話,也許大家以爲七夕很浪漫,可是我是有一點小恐懼,由於不知道送什麼禮物給女友好。之前給女友送過一些禮物,儘管精心準備,有時不免留有遺憾。無論怎麼說,又是一次情人節,我仍是須要精心準備一下,因而花時間來搜索禮物,另...2014-07-27T08:15:00Z2014-07-27T08:15:00Z拼命工做http://www.cnblogs.com/workest/

 
我女友在外地出差,日常可以作的就是打打電話,聊聊天。

下週六就是中國的情人節了。

說實話,也許大家以爲七夕很浪漫,可是我是有一點小恐懼,由於不知道送什麼禮物給女友好。之前給女友送過一些禮物,儘管精心準備,有時不免留有遺憾。

無論怎麼說,又是一次情人節,我仍是須要精心準備一下,因而花時間來搜索禮物,另外也請朋友們給我出一點建議。

下面是我搜到的一些禮物,想看大圖片的朋友能夠單擊小標題。請你們給點建議。

1, 戒指

 

曾經在網上買了兩對情侶戒指,還刻上了雙方名字首字母,滿心歡喜送出去,女友收到後發現,太大了,不合適,容易掉。

當時我是認真看了說明和評論的,有人說偏小,讓買大一點的,我還對照了身高、體重和戒指尺寸的對照比,精心挑選了兩對,沒想到仍是大了。

不過,上次買的那對戒指比較簡單,沒有任何修飾,此次搜到了一個帶珠子的,不知道怎麼樣。

 

2, 連衣裙

 

女友在外地出差,剛過去的時候沒有裙子換,就給她買了兩條。

後來,女友收到貨,有一件太大了,撐不起來;還有一件像睡衣,和網上看到的出入很大,後來,這兩個裙子都扔了。

此次搜到一個如圖所示的,不知道她會不會喜歡。

 

3, 項鍊

 

項鍊卻是沒有給女友買過,不過女友說她也不怎麼喜歡這些金銀首飾,不過,我是否是要嘗試一下呢?

買過項鍊的朋友,請給我點建議。

 

4, 小熊

 

 

女友比較喜歡比較可愛的娃娃,這是一個小笨熊,也挺可愛的,不知道女友會不會喜歡。

學校裏,見不少人追女友,通常都是送棉娃娃,不過,不知道會不會很俗啊。

 

5,巧克力

 

我查的時候,看到好多人買巧克力,不過,我女友不喜歡吃甜的,因此,我感受,買這個也不是太好。

 

6,

 

另外,我搜索到了這麼一盒花,也是有不少人買,感受這個比巧克力更適合女友一些。不過,仍然不知道女友會不會喜歡。

上個月,女友畢業,我買了一束雲南乾花去看她,不事後來由於東西太多了,就丟到了宿舍。

我也沒啥興趣愛好,也不怎麼懂幽默,不過也是但願進步,因此,想請朋友給點建議。

各位朋友,你有沒有送過什麼禮物,結果特別讓女友滿意的啊,請給我說說。

本文連接:我給女友講編程-題外話系列(1)--懼怕過七夕,不知道買什麼禮物,轉載請註明。

http://www.cnblogs.com/dongyu9521/p/3871507.html.NET基礎筆記(C#) - 七步、 閒着沒事就把之前學習時的筆記拿出來整理了一下,我的感受有點用,就想拿出來跟園友共享一下。有些基礎性的內容好比基本概念、語法什麼的就不發了。內容:一、構造方法(函數) 二、繼承 三、訪問修飾符 四、靜態和非靜態 五、隱藏基類方法 六、重寫基類方法 七、抽象方法 八、接口 九、多態和接口 十、值...2014-07-27T08:08:00Z2014-07-27T08:08:00Z七步、http://www.cnblogs.com/dongyu9521/

     閒着沒事就把之前學習時的筆記拿出來整理了一下,我的感受有點用,就想拿出來跟園友共享一下。有些基礎性的內容好比基本概念、語法什麼的就不發了。

內容:一、構造方法(函數) 二、繼承   三、訪問修飾符  四、靜態和非靜態  五、隱藏基類方法  六、重寫基類方法  七、抽象方法  八、接口  九、多態和接口  十、值類型與引用類型  十一、ref和out  十二、類型轉換  1三、異常處理  1四、string字符串處理  1五、string經常使用方法  1六、StringBulider  1七、File類讀取文件  1八、文本高亮 1九、泛型集合List<T>和Dictionary<TKey,TValue>  20、裝箱和拆箱  2一、讀寫數據(Ststem.IO)  2二、文件流(FileStream)  2三、StreamReader和StringWriter  2四、File和Directory  2五、序列化  2六、Directory類的靜態方法  2七、正則表達式  2八、Regex類  2九、字符串提取  30、貪婪模式  3一、字符串替換  3二、byte數組和字符串的轉換  3三、委託  3四、多播委託  3五、事件  3六、委託和事件的區別  3七、var類型  3八、擴展方法  3九、XML

一、構造方法(函數):在對象建立的時候初始化字段

    public 類名([參數])

    {

        //執行內容,如this.name=name;(有參數)

    }

  構造方法沒有返回值,void也不寫

  建立對象時若是沒寫構造方法系統默認有一個無參的構造方法,一旦用戶添加了構造方法,原來默認的無參的構造方法就沒有了

  默認初始值爲:int:0;  bool:false;  string:null;   char:‘\0’; 

  構造方法的做用:初始化字段(實例化類的時候傳入初始值)

  調用構造方法:

    1)除了new對象的時候,不能直接使用構造方法名調用構造方法

    2)this調用構造方法(難點)(一個構造方法調用另外一個構造方法)

   爲了解決代碼的重用才使用this調用構造方法

   當一個類中出現多個構造方法重載的時候,同時構造方法都須要爲字段賦初值

   使用this表明當前類的構造方法來使用,根據this後面的參數決定使用哪個重載

    public 構造方法名():this([參數])

    {

        //代碼

    }

如:  

 public Person(string name, int age, string sex)

        {

            this.name = name;

            this.age = age;

            this.sex = sex;

        }

        public Person(string name)

            : this(name, 0, null)

        {

        }

二、繼承:

  多個類都有共同的字段、屬性或方法時,能夠使用繼承

  須要寫一個學生類、一個老師類、一個校長類

  事先寫一個Person類,在寫其餘類的時候繼承這個類,Person叫父類,繼承他的叫子類

  特徵:子類既有父類的非私有字段、屬性和方法,又有子類獨有的字段、屬性和方法

  一個子類只能有一個父類,一個父類能夠有若干個子類

    [訪問修飾符] class 子類名:父類名

子類調用父類構造方法的問題(難點)

  ->構造方法的執行順序:先父類再子類

  ->關於構造方法的重載:若是不聲明調用哪一個構造方法默認執行無參的構造方法

  避免錯誤的方法:

->爲父類提供無參構造方法

->在子類中指定調用父類有參的構造方法

注意:父類除構造函數(方法)以外的非私有成員均可以被子類所繼承,構造方法不能夠被繼承,但能夠被調用,調用方法: [訪問修飾符] 構造方法名([參數]):base(父類構造方法的參數)

public Teacher():base("狗蛋」,20,"女")

        {        }    //直接賦值,實例化對象時不需再賦值

 

 public Teacher(string name, int age, string sex)

            : base(name, age, sex)

        {

            this.className = "C#";//老師類獨有的字段

        }   //繼承傳遞參數,實例化對象時須要賦值

  base關鍵字用於顯示聲明要調用父類的哪一個構造方法,是調用,不是聲明不是繼承

  注意:爲避免繼承父類時由於構造方法出錯,應該爲每一個聲明的類都手動添加一個無參的構造方法

三、訪問修飾符

  public 最公開的,全部地方均可以訪問

  private 最隱蔽的,只有本類能夠訪問

  protected 能夠在當前類和子類中被訪問

  internal 只能在本項目中被訪問

  C#中規定類的訪問修飾符只能是public 和internal 

  類中成員的訪問修飾符除以上四種之外還有個(protected internal)便可以在當前類、子類和本項目中被訪問  

四、靜態和非靜態

  靜態使用static標記

靜態成員

  ->如何定義靜態成員

       在成員前加static關鍵字

  ->如何使用靜態成員 

靜態成員不能由實例對象調用,只能用類名調用

使用靜態成員,不須要實例化對象

靜態成員會在整個應用程序退出時才釋放資源,因此這個變量能夠在整個程序中共享數據,可用於窗體間傳遞參數

注意:靜態變量過多會佔用系統內存,所以聲明靜態變量時要多加考慮

Main方法是靜態的,因此它只能調用靜態的方法或參數,若想調用非靜態方法,必須new一個類的實例,用實例名調用。

靜態類

  1)什麼狀況下要將一個類標記爲靜態類?

      通常狀況是,當這個類是一個工具類,裏面都是方法,爲了讓用戶調用的時候方便,不須要實例化對象,這時能夠將該類標記爲static類,此時該類中只能包含靜態成員,不能包含實例成員,好比Convert、Console、Read、ReadInt等

  2)什麼狀況下須要在一個普通類中編寫一個靜態成員,而這個類不能標記爲static?

      當這個類須要被實例化的時候,若是這個類中有一個成員是全部對象要共享的數據,這時能夠將該類中的這個成員標記爲靜態的,可是這個類仍是一個非靜態類

  3)靜態類不能被實例化,不能被繼承

  4)因爲靜態成員會在整個程序退出時才釋放資源,因此儘可能避免寫靜態字段或靜態屬性,最好只寫靜態方法

  5)靜態類中能夠有靜態成員和實例成員,由於其不能被實例化,因此靜態類中的實例成員沒法被調用,也就沒有任何意義了

  6)靜態類不能被繼承,也不能繼承自其它類,只能繼承自Object類

靜態構造函數

  1)靜態構造方法(或字段)在第一次訪問這個類的時候執行,而且只執行一次

  ->靜態構造方法與靜態類的生命週期(瞭解)

靜態成員屬於該類的全部對象。實例成員只屬於當前實例

靜態類的生命週期:第一次訪問類的時候建立,程序結束時才釋放

 

五、隱藏基(父)類方法(瞭解,用的很少)

  當子類和父類有相同名字的方法時,實例化子類調用該方法爲子類內的方法,把子類轉換成父類後再調用該方法就是父類內的方法了

  爲了代碼規範化,如要有意隱藏父類的方法,要在子類的同名方法前加new關鍵字,用於   提醒這裏是要隱藏父類方法

//隱藏基類方法

    class MyBase

    {

        public void Func()

        {Console.WriteLine("我是父類的方法);}

    }

    class MySub : MyBase

    {

        public new void Func() //在方法前用new關鍵字提醒這裏是有意隱藏父類方法

        {Console.WriteLine("我是子類的方法);}

    }

    class Program

    {

        static void Main(string[] args)

        {

            MySub ms = new MySub();

            ms.Func();

           // ((MyBase)ms).Func();

            MyBase my = ms;

            my.Func();

            Console.ReadKey();

        }

    }

六、重寫基(父)類方法(多態的體現)

  在父類方法前加virtual(虛方法),表示這個方法能夠被重寫

  在子類方法前加override,表示重寫基類方法,子類若是不寫override就是隱藏

 當子類和父類有相同名字的方法時,實例化父類調用的是父類的方法,將子類賦值給父類後,父類調用的就是子類的方法了

  一旦父類的方法在子類中被重寫,除了實例化父類調用之外,子類或者子類的子類調用時都是調用的最新的那個子類重寫方法

  此時base和this就有區別了:

  若是子類和父類中有名字相同的方法,那麼base.Func()就表明父類的方法,this.Func()表明當前類的方法

  若是不但願子類再重寫,須要在子類方法前加sealed

//重寫基類方法

    class USB

    {

        public virtual void Usb() //virtual關鍵字表示父類方法能夠被重寫′

 

        {Console.WriteLine("我是父類的方法);}

    }

    class Phone:USB

    {

        public override void Usb()//override關鍵字表示這個方法重寫父類的方法

 

        {Console.WriteLine("手機");}

    }

    class Mp3:USB

    {

        public override void Usb()

        {Console.WriteLine("MP3");}

    }

    class Program:USB

    {

        static void Main(string[] args)

        {

            Console.WriteLine("輸入數字");

            USB usb = new USB();

            switch (Console.ReadLine() )

            {

                case "1":

                    usb = new Phone();

                    break;

                case "2":

                    usb = new Mp3();

                    break;

                default:

                    break;

            }

            usb.Usb();

            Console.ReadKey();

        }

}

隱藏看類型,重寫只管新

七、抽象方法

  方法前加abstract,圓括號後加分號

  [public]  abstract  void 方法名(參數);

  抽象方法所在的類也必須是抽象的,不能被實例化,類前加abstract  

  abstract  class  類名

  抽象成員必須出如今抽象類中,但抽象類中能夠有抽象成員和實例成員

  抽象類的抽象方法默承認以且必須被重寫,因此須要重寫時不須要再寫virtual,直接在子類方法中寫override關鍵字便可重用

  抽象類的成員:方法、屬性、索引、事件

  注意:抽象類中的全部抽象方法在子類中必需要被重寫,若是子類中不重寫,那這個子類也必須聲明成抽象類,但此時子類也就不能被實例化了

八、接口

  [訪問修飾符] interface 接口名(接口通常以I開頭,I+行爲+able)

  {

    //接口成員,必定是抽象成員

  }

  成員的定義:與抽象成員的寫法同樣(沒有關鍵字),沒有執行體(方法體);沒有訪問修符;

  實現:子類「繼承」自接口,接口能夠看作是子類的「乾爹」,補全抽象的方法

  調用:和類的使用方法同樣,要使用接口中的方法,則將對象賦值給接口變量

  多態:和抽象類的實現同樣,接口的多繼承使得多態的實現變得靈活

  子類繼承父類,子類實現(繼承)接口:class 子類名:父類名,接口名 或class 類名:接口名

  我的理解:接口就是把類中的一種特定的功能性方法封裝成接口(如開車、飛等),聲明類的時候能夠繼承這個接口,就擁有了這個接口所特有的功能,就能夠在類中實現這個功能,那實現後的這個功能就成爲了這個類的一個功能性方法。用接口能夠實現多繼承,一個類能夠繼承多個接口,也就擁有了多個功能性方法,聲明類的時候能夠選擇性的繼承,好比定義老師的時候能夠繼承說話、吃飯、教課等接口,定義司機的時候又能夠繼承說話、吃飯、開車等接口

//定義一個接口,表示Driving功能

interface IDrivable

    {

        void Driving();

    }

class Teacher:Person,IDrivable//繼承父類和接口

    {

        public Teacher(string name, int age, string sex):base(name,age,sex)

        {//繼承父類的構造方法

        }

        public void Driving()//實現接口的Driving功能

        {

            Console.WriteLine("我會開車");

        }

        public override void ShowMe()//重寫父類方法

        {

            Console.WriteLine("我是老師");

        }

    }

static void Main(string[] args)

        {

            Teacher tea = new Teacher("張三", 18, "男");

            tea.ShowMe();//調用重寫後的方法

            tea.Driving();//調用實現後的接口方法

            Console.ReadKey();

        }

九、多態和接口

  接口是能夠多繼承的,多繼承同時會引發方法的重名

  爲避免重名,顯示實現接口:

返回值 接口名.方法名(參數)

   {

        //方法體

   }

顯示實現接口的這個方法只能由接口變量進行調用

現階段記住接口使用的語法,而後將接口直接當作抽象類使用(初學階段)

十、值類型和引用類型

  變量能夠看作是一個數據

  值類型,是一個存儲數據的容器,這個數據就是這個類型表示的數據

  引用類型,也是一個容器,可是這個容器存儲對象的一個引用(地址),真正的數據在另外一塊內存中,就至關因而一個指向數據的快捷方式

  值類型存儲在棧裏面,引用類型存儲在棧和堆裏面(堆裏存儲的是真實數據,棧裏面存儲的是真實數據在堆裏面的內存地址)

  值類型和引用類型會涉及到傳參和賦值時的不一樣,要注意區分

 

  委託(delegate)也是引用類型

  值類型賦值賦的是真實的值,引用類型賦值賦的是地址

  引用類型是一個變量,兩個快捷方式,修改一個快捷方式會影響另外一個快捷方式;值類型是一個變量和一個複製後的變量,修改一個變量不會影響另外一個變量

  全部的值類型都繼承自System.ValueType類

十一、引用傳遞:ref和out

  使用ref或out就能夠實現將引用傳遞過來

  定義方法時,在參數類型前加ref或out

  調用方法時,在參數前加ref或out

  注:定義變量時不須要加ref或out

  當一個變量傳遞給一個方法時,老是複製一份本身的數據,賦值給方法,那麼方法中執行的變量就與方法外的那麼變量沒有關係了,方法內修改變量值,也不會影響方法外的那個變量。有時會要求多個返回操做(方法中的變量有多個在方法外須要使用),此時能夠使用ref標記參數,此時在方法中使用的這個變量與方法外的變量就是同一個變量了,至關於能夠使用參數實現返回值

    out與ref的做用與使用方法相同

  out 必須在方法中賦值

  ref必須在方法外賦值

十二、類型轉換

  隱式類型轉換:兼容類型,小轉大

  顯式類型轉換:即強制類型轉換  (轉換後的類型)要轉換的變量

  Convert類型轉換:系統封裝的方法,Convert.ToInt32()、Convert.ToDouble()等

  其餘轉換方法:int.Parse()、int.TryParse()(第一個參數表示待轉換的字符串,第二個out(result)參數表示數字轉換成功後的變量,若是轉換失敗,返回false,爲out result賦值爲0)

  用int.TryParse()代替try-catch,釋放內存,提升性能

  不止int類型有TryParse,全部基本類型都有TryParse,用法都同樣

1三、異常處理(try-catch、try-catch-finally、try-finally)

  Exception是一個專門用來封裝異常的一個類型

  兩個屬性:message(異常說明文本)和stackTrace(異常拋出的順序)

  拋出異常:throw Exception的一個對象(new一個對象)

  從出現異常的try向上依次拋出(方法之間依次調用),直至處理,找到最近的catch捕獲異常(用於try-finally語句,catch塊在方法之外,執行順序是try-finally再向上尋找catch執行異常捕獲)

Finally用於釋放資源,finally{},程序執行完try-catch後會再執行finally語句塊

Finally總會執行,即便try-catch中有return

           try

            {  }

            catch (Exception ex)

            { throw; }

            finally

            {  }

Try-finally用處很少,用於釋放資源

使用異常會下降系統性能,儘可能少用

1四、string字符串處理

構造函數:string(char[] chs)、string(char ch,int count)

  string str = new string(’a‘,’b’,’c’);//abc

  string str = new string(‘a’,3);//aaa

  3.144.ToString(「0.0」);用於控制格式,會四捨五入

字符串能夠當作數組進行處理(使用下標讀取,擁有數組的各類屬性)

  string str = 「不可見的你」;  此時str[1]就是「可」了

  經過索引獲得的數據是char類型,字符串不可改變,使用索引沒法修改字符串的數據

  要想修改可將字符串變成字符型數組,str.ToCharArray()

string是引用類型

string str = string.Empty;聲明一個空字符串

  判斷字符串是否爲空:

str.Length == 0(推薦)

str ==「」

str == string.Empty

String.IsNullOrEmpty(要判斷的字符串)(推薦)

1五、string經常使用方法

  1)字符串比較:bool isTrue = string.Equals(string a,string b)

  String.Equals(str1,str2);

  Str1.Equals(str2,StringComparison.OrdinalIgnoreCase); //第二個參數意思是不區分大小寫

  string.Compare(str1,str2);

  Equals方法:

String重載的方法判斷兩個,一個是==,一個是EqualsHelper

==判斷兩字符串是否相同

EqualsHelper判斷兩個字符串中每個字符是否相同

  Object的重載是來自於object類,是繼承下來的

在object中使用的是==和Equals方法

Equals方法是一個虛方法,由string重寫了,調用的是object.ReferenceEquals方法和EqualsHelper方法

注意:==默認表示判斷兩個對象的地址是否相同,與object.ReferenceEquals方法同樣

String提供的str1.Equals(str2)判斷地址是否相同,字符串是否object提供的virtual Eaulse(object)

Equals和==的區別:

  Equals會判斷兩個值的內存地址;==只判斷值是否相等。

Compare方法:

  int result = String.Compare(str1,str2);

  str1>str2 -> 1    str1 == str2 -> 0   str1<str2 -> -1

  string.Compare方法比較兩個字符串,這兩個字符串字母順序表示大小,按照字典排序規則進行比較(對於char類型:A>a,B>a,b>A同一個字母,大寫>小寫,不一樣字母按照字母順序後面的大於前面的;對於string類型不是按照埃克森碼比較,A>a,b>A,B>a)

  2)大小寫轉換:ToLower()和ToUpper()

  3)str1 = str1.Trim([params char[] chs]);去除字符串兩邊的空格,或chs中出現的字符(重載)

     str1 = str1.TrimEnd(params char[] chs);去除字符串的末尾chs中出現的字符

     str1 = str1.TrimStart(params char[] chs);去除字符串的開頭chs中出現的字符

  4)合併與分割

合併字符串:string s = string.Join(str1,str2,str3,...)

分割字符串:string[] strArray = str1.Split(‘a’);

                string[] strArray= str1.Split(new char[]{‘a’,’b’},StringSplitOptions.RemoveEmptyEntries);去掉a、b和全部空格

  5)字符串查找

Contain包含,返回bool類型的值,str1.Contain(「愛」);

IndexOf檢索位置,返回字符串中某個字符的位置(int)找不到則返回-1

str.IndexOf(要找的字符或字符串)

str.IndexOf(要找的字符或字符串,開始尋找的位置)

str.LastIndexOf()是從後往前尋找,用法同str.IndexOf() 

注意:IndexOf和LastIndexOf中第二個參數(開始尋找的位置)只是爲了說明要查找的是字符串中的哪個字符(若是字符有重複),即按查找順序在開始位置後的第一個字符,返回的索引依然是該字符在整個字符串中的索引,而不是從查找位置開始的索引。

  6)截取子字符串

string s =str1.Substring(開始的位置,子字符串的長度)

String s = str1.Substring(開始的位置)

  7)判斷字符串的開頭和結尾

bool a = str1.StratWith(字符串);

bool a = str1.EndWith(字符串);

  8)字符串的插入、移除和替換

插入:string str2 = str1.Insert(位置(int),要插入的人字符串(string));

移除:string str2 = str1.Remove(位置(int),長度(int));

      string str2 = str1.Remove(位置(int));移除該位置後的全部字符

替換:string str2 = str1.Replace(舊字符串,新字符串);

  9)格式化字符串

String.Format(格式化的字符串,填坑的參數)

string str1 = String.Format(「{0},{1}」,str2,str3);

  10)判斷字符串是否爲空

    String.IsNullOrEmpty(str);

  10)字符串的方法(總結)

增:添加(+=)、插入(Insert)

刪:Remove

改:Replace、 ToUpper、ToLower、Trim、TrimStart、TrimEnd、Split、Join、new String、SubString、Format

查:Contains、IndexOf、LastIndexOf、StartsWith、EndsWith、ToCharArray、Length、Empty

比:Equals、Compare

1六、StringBuilder

大量字符串拼接的時候性能很是差,很難完成大型數據的拼接

(Stopwatch對象能夠記錄程序運行的時間,Start開始計時,Stop結束)

使用StringBuilder:StringBuilder sb = new StringBuilder();

  sb.Append(要添加的字符串);//向sb中添加數據

  sb.AppendLine(要添加的字符串);//向sb中添加數據後換行,等價於sb.Append(要添加的字符串+」\r\n」);

  sb.AppendFormat(要添加的字符串);格式化處理,等價於 sb.Append(string.Format(要添加的字符串));

  string str = sb.ToString;輸出或賦值時要轉換成string

在處理大型數據的時候,StringBuilder要比普通的string處理快不少,由於處理大型數據要用StringBuilder

1七、讀取文件

  string[] lines = File.ReadAllLines(@"H:\傳智播客實訓資料代碼\第9天\a.csv", Encoding.Default);//按行讀取

  string[] lines = File.ReadAllText(@"H:\傳智播客實訓資料代碼\第9天\a.csv", Encoding.Default);//讀取全部文本

  string[] lines = File.ReadLines(@"H:\傳智播客實訓資料代碼\第9天\a.csv", Encoding.Default);//讀取一行文本

  string[] lines = File.ReadAllBytes(@"H:\傳智播客實訓資料代碼\第9天\a.csv", Encoding.Default);//讀取字節

1八、文本高亮

->讓文本框得到焦點--txtContent.Focus();

->找到要高亮的位置--pos

->選中(高亮)的字符串長度--length

->調用TextBox的選中方法txtContent.Select(pos,length)

1九、泛型集合   List<T>和Dictionary<TKey,TValue>

List集合:動態的自定義數組

  List<類型> 集合名 = new List<類型>();

List用法與ArrayList同樣,不一樣點在於定義時和使用時的類型固定,所以能夠徹底替代ArrayList

  類型[] = list.ToArray()//將List轉換成該類型的數組

Dictionary集合:動態的自定義鍵值對

  Dictionary<類型,類型> 集合名 = new Dictionary<類型,類型>();

Dictionary用法與Hashtable同樣,不一樣點在於定義時和使用時的類型固定,所以能夠徹底替代Hashtable

20、裝箱與拆箱

  直接將值類型賦值給引用類型就是裝箱

  將存儲值類型的引用類型強制轉化爲對應的值類型就稱爲拆箱

Object o = 1;//裝箱      int n = (int)o;//拆箱

  裝箱對值類型保持無關性,裝箱對引用類型保持相關性

  裝箱和拆箱會對性能有必定的影響

2一、讀寫數據(I/O操做、System.IO類)

  System.IO.Path類,專門處理字符串路徑,是一個靜態類

    string path = @「D:\window\system\file.txt」; 

    獲取文件名:string fileName = Path.GetFileName(path);

    獲取後綴名:string fileName = Path.GetExtension(path);

    修改後綴名:path = Path.ChangeExtension(待修改的路徑,「mp3」);

    獲取文件夾名:string fileName = Path.GetDirectoryName(path);

    合併路徑:path= Path.Combine(路徑1,路徑2,路徑3...);

    臨時文件夾:path = Path.GetTempPath();

  絕對路徑:從盤符開始的最精確的路徑

  相對路徑:相對於當前文件同一個目錄做爲參照的路徑

  相對路徑和絕對路徑:區分就看有沒有根目錄盤符的標記

2二、文件流(FileStream)

  1)引入命名空間

  2)建立FileStream對象FIleStream fs = new FileStream(文件名,FileModel,FileAccess)

FileStream fs = new FileStream(@"D:\a.txt", FileMode.Create, FileAccess.Write);

FileModel:對文件的處理方式(打開、建立、追加)

FileAccess:對文件的操做:讀、寫

  3)使用方法操做

寫一個字節:fs.WriteByte()

寫一個字節片斷(將字節數組中的數據寫入到fs指定的文件):

  fs.Write(存放字節的數組,開始寫字節的數組下標,要寫的字節數)

讀一個字節:fs.ReadByte()

讀一個字節片斷(將fs指定的文件中的數據讀取到字節數組):

  fs.Read(存放字節的數組,開始存放字節的數組下標,要讀的字節數)

  4)釋放資源

fs.Close()和fs.Dispose()方法(兩個都要調)

2三、StreamReader和StreamWriter

  StreamReader:專門用來讀取文本文件的流

1)引入命名空間:IO

2)new一個FileStream指向文件

3)new一個StreamReader,構造函數參數是FileStream的對象

4)調用方法

    StreamReader有一個屬性EndOfStream:判斷當前的流位置是否在文件流的末端,通常用來判斷文件是否讀完

  StreamWriter:專門用來寫入文本文件的流

1)引入命名空間:IO

2)new一個FileStream指向文件

3)new一個StreamWriter,構造函數參數是FileStream的對象

4)調用方法

2四、File和Directory對文件和目錄操做作了一個封裝

增(Create):建立文件或文件夾  

刪(Delete):刪除文件或文件夾  

改:更名字 File.Move(「1.txt」,「2.txt」)

查:...

判斷是否存在(Exists)

移動文件:File.Move(「1.txt」,「2\1.txt」)

複製文件:Copy

  Directory用於處理文件夾(目錄)

刪除目錄的時候若是目錄不是空的則會報錯,此時須要在Delete內添加一個true

Directory.Delete(「1」,true);

2五、序列化:

  序列化:把一個對象的內容存儲到磁盤上(文件流)、網絡上(網絡流)、內存裏(內存流),下次須要用到對象數據的時候能夠直接拿來用

  反序列化:把已經序列化存儲到磁盤、網絡、內存裏的對象數據,提取到項目中的對象中

序列化步驟:

1)建立一個文件流

2)爲須要序列化的對象添加標記([Serializable]表示此對象能夠被序列化)

3)建立BinaryFormatter(導入命名空間)

4)調用Seralize方法(bf.Seralize(文件流對象,須要被序列化的對象))

反序列化步驟:

1)建立一個文件流

2)爲須要序列化的對象添加標記([Serializable]表示此對象能夠被序列化)

3)建立BinaryFormatter(導入命名空間)

4)調用DeSeralize方法(object ob = bf.DeSeralize(文件流對象))

反序列化定義接收類型的時候必須根據原序列化的程序集肯定類型

  建議:在使用序列化的時候儘可能避免使用自動屬性,由於自動屬性在每次編譯的時候自動生成的字段名可能不同,因此在反序列化的時候可能會形成問題

  注意:若是序列化和反序列化不在同一項目下,那反序列化的時候須要引用原序列化的程序集

2六、關於文件夾下的文件與子文件夾

  Directory類的靜態方法

獲取子文件名:string[] s = Directory.GetFiles(@「D:\dir「);

獲取特定後綴名的子文件名:string[] s = Directory.GetFiles(@「D:\dir「,」*.txt「);

獲取全部文件夾名:string[] s = Directory.GetDirectories(@「D:\dir「);

2七、正則表達式

  元字符:

1).(點)表示除\n之外任意的單個字符

2)[ ]表示括號內的任意一個字符(如a[xyz]b表示axb或ayb或azb)

3)^在[ ]括號內表示取反(如^[a-z]表示除小寫字母之外的全部字符)

4)^匹配一串字符的開始(^abc表示以abc爲開頭的任意字符串)

5)$匹配一串字符的結尾(abc$表示以abc爲結尾的任意字符串)

5)|表示「或」,優先級最低(如a|bc表示a或bc,(a|b)c表示ac或bc)

6)()能夠改變優先級、提取組

7)*表示限定前面的字符出現任意次數(abc*表示ab、abc、abcccc......(abc)*表示abc、abcabc)

8)+ 至少出現一次,也可出現屢次(xa+y表示xay、xaay...)

9)?表示出現0次或1次

10){n}限定前面的表達式出現n次

11){n,m}至少出現n次,最多出現m次

12){n,}至少出現n次

13)\d表示0-9,\D表示\d的反面

14)\s表示空白符,\S表示\s的反面

15)\w表示數字、字母、下劃線、漢字,\W表示\w的反面

注:正則表達式的轉義符也是\,若是要表示*(星),能夠寫成\*,要表示一個\,能夠寫成\\

2八、Regex類

  Regex.IsMatch(待判斷的字符串,正則表達式)判斷一個字符串是否匹配某個正則表達式

  !若是正則表達式沒有^和$,那默認不設定開頭和結束,此時只要待判斷的字符串中含有該正則表達式就返回true

  ^z|food$:表示以z開頭的任意字符串或者以food結尾的任意字符串,都返回true

             由於|的優先級最低,因此上邊的表達式實際上是(^z)|(food$)

  Regex.Match()從某個字符串中提取匹配某個正則表達式的某個子字符串,但只能提取一個

  Regex.Matches()同上,能夠提取全部的匹配字符串

  Regex.Replace()字符串替換,把全部匹配正則表達式的字符串替換爲對應的字符

2九、字符串提取

  字符串提取的時候通常不加^和$  

  Match m = Regex.Match(原字符串,要提取的正則表達式)

  m.Value屬性表示提取到的字符串

  m.Group[n]:提取組,按正則表達式中()括號對的個數,m.Group[0]表示整個字符串,m.Group[1]表示第一個括號內的內容,因此提取組的時候要從下標1的地方開始

  MatchCollection mc = Regex.Matches(原字符串,要提取的正則表達式)

  MatchCollection是一個集合,須要foreach遍歷輸出(遍歷時的類型是Match)

30、貪婪模式

  定義:當正則表達式提取的時候,若是一個字符或多個字符都能匹配,這時會按照使用最多字符的方式來匹配。

  正則表達式默認採用貪婪模式,盡多的匹配

  在限定符後面使用問號用來終止貪婪模式,即只會提取匹配的第一個

  string s = 「aaaa bbbbbbbb」;string s1 = 「[a-zA-Z]+」;  匹配結果:aaaa

  string s = 「aaaa bbbbbbbb」;string s1 = 「[a-zA-Z]+?」;  匹配結果:a

3一、字符串替換

  String s =Regex.Replace(原字符串,待替換的正則表達式,替換後的字符串);

  如:string s = Regex.Replace(s, "-+", "-");//把字符串s中的全部-替換成一個-

  提取組替換:

            string s = "aaa13812345678bbb";

            s = Regex.Replace(s, @"(\d{3})(\d{4})(\d{4})", "$1****$3");//把手機號中間4位替換成4個*

3二、byte數組和字符串的轉換

  byte[] bt= System.Text.Encoding.UTF8.GetBytes(str);

  string str = System.Text.Encoding.UTF8.GetString(bt);

3三、委託(delegate)

  委託是一種數據類型(和類同樣),能夠將方法賦值給委託對象,能夠理解爲方法類型

  定義(在命名空間下,或添加一個cs文件,和類的定義同樣):

1)使用delegate關鍵字

2)這個委託未來要存儲的方法若是沒有返回值,那麼委託也要定義成void,參數也要與方法保持一致

3)委託是一個數據類型,用的時候須要傳遞一個變量

4)建立委託對象的時候能夠不用new,系統編譯時會自動給咱們new

定義委託類型:public delegate void ChangeTxtDelegate(string str);

建立委託對象:public ChangeTxtDelegate changeTxt;  //Form1中

    給委託賦值:f1.changeTxt = ChangeText;  //Form2中

調用委託:changeTxt(txt);  //Form1中,此種調用方法爲簡寫,其實是changeTxt.invoke(txt);

建立委託對象時也可直接對其賦值:ChangeTxtDelegate changeTxt = new ChangeTxtDelegate(ChangeText) ;

  用法(窗口間傳值):委託要聲明在須要被傳值的對象內,好比Form1要提取Form2中的數據(即Form2往Form1傳值),就應該把委託聲明在Form1中,在Form2中寫一個方法獲取要傳的數據,而且賦值給Form1的委託,最後在Form1中調用委託就ok了。(委託聲明位置不絕對,還須要考慮當前活動窗口的問題,要聲明再活動窗口中,有時也可聲明在被提取值的窗口內)

  做用:能夠在某個代碼內部,嵌入一段外部代碼(外部寫一個方法賦值給委託或在定義方法時把委託類型做爲參數,調用時把方法名做爲參數傳遞給委託對象,那麼委託就執行該方法,不一樣的外部項目能夠寫不一樣的方法賦值給委託,能夠實現一個委託選擇性執行多種方法的靈活性),至關因而注入

  什麼狀況下使用委託?

    當一個類型中須要嵌入一段代碼,可是這段代碼具備不肯定性,是根據使用這個類型的用戶來肯定代碼的,這時就能夠在該類型中使用一個委託,保證在某種狀況下會調用該委託,用戶將對應的方法傳遞給該委託,就會調用這個方法

  能夠把靜態方法或者私有方法賦值給委託了變量,賦值後只要能使用到該委託變量的地方就能使用該方法,打破了訪問修飾符的限制

  通常在調用委託前或者觸發事件前,都要判斷委託變量或事件是否爲null,若是爲null則不調用

3四、多播委託

  MyDelegate md = new MyDelegate(M1);  md+=M2;(增長某個方法)md-=M4;(去掉某個方法)

  使用委託時,若是不是+=而是直接用=賦值,則會將前面增長的全部方法都覆蓋掉

  多播委託能夠存儲多個方法,委託中方法調用的順序與增長方法時的順序是一致的,可是,不要依賴於這個順序(微軟沒有承諾這樣的順序,萬一之後改了就GG了)

  多播委託中,若是要是有返回值,只會獲得最後一個方法返回的結果。能夠經過調用GetInvocationList()方法返回當前委託中的全部方法,返回值類型時一個Delegate數組(委託數組),再用foreach遍歷調用全部方法

  全部定義的委託都繼承自抽象類MulticastDelegate,而MulticastDelegate又繼承自Delegate抽象類

  多播委託內部是將綁定在當前委託對象上的每一個方法,都轉換成一個委託對象,而且存儲在了一個叫_invocationList的object數組中。當調用委託的時候,其實就是循環遍歷_invocationList數組,而且調用其中的每一個委託

  多播委託中,若是其中的某個方法執行時發生了異常,則後面的方法再也不執行。

  多播委託中只能存儲同一類型的委託,即返回值、參數都相同

3五、事件

  事件是在特定條件下執行的動做,這個動做是由用戶肯定的。如Button的Click事件,其動做是由程序員寫的,所以能夠用委託來實現這個功能,寫不一樣的方法賦值給委託變量。

  但用委託模擬方法有兩個缺點:

  1)定義的委託能夠在類外部的任何地方被觸發,即非特定條件下也能夠調用。由於委託變量是public修飾,改成private就不能在外部賦值了。

  2)因爲委託能夠用=(等號)賦值,因此就有可能把前面已經註冊的事件處理程序都覆蓋掉。

  而用事件就能夠解決以上問題:

  1)用事件必須先定義一個委託,不然沒法使用事件

  2)實例化委託變量的時候,在委託類型名前面、訪問修飾付的後面加event關鍵字,就定義了一個事件

  3)使用方法與委託同樣,只是避免了以上兩個問題

  4)因爲事件只能有+=或-=賦值,因此就避免了用=(等號)賦值時覆蓋前面事件處理程序的問題

  5)因爲事件不能在定義事件的類之外被觸發,因此也就避免了冒充事件觸發的問題。

3六、委託和事件的區別(面試常考)

  委託和事件沒有可比性,委託是數據類型,事件是委託類型的變量

  委託能夠用+=、-=、=賦值,能夠在類的外部被調用

  事件只能用+=、-=賦值,不能在類的外部被調用

  事件的內部是用委託實現的

  事件的做用和委託變量(不是委託,是委託變量)同樣,只是在功能上受到必定的限制

3七、var類型

  var只能用做局部變量,能夠賦任何類型的值。

  var a = 1;和int a = 1;二者徹底同樣

  var不能做爲類的成員的類型,不能用做參數,不能用做返回值,只能用做局部變量

3八、擴展方法(不修改微軟系統方法源代碼,實現系統方法的增長)

  1)添加一個靜態類

  2)在靜態類中增長一個靜態方法,方法參數是:(this+要擴展的類名+變量名,該方法的參數)

  如要在string類中添加一個驗證是不是Email格式的擴展方法:

        public static bool IsEmail(this string str)

        {

            return Regex.IsMatch(str, @"^\w+@\w+\.\w+$");

        }

            string a = "1321321@qq.com";

            Console.WriteLine(a.IsEmail());

  擴展方法只是看起來像類中的方法,其實不是,因此在擴展方法中也訪問不到類中原來的私有成員

  由於會擾亂系統方法,因此不建議使用,儘可能不用

3九、XML

  XML是用一種格式化的方式來存儲數據,能夠用記事本打開

  1)XML有且只有一個根元素

  2)有開始標籤就必須得有結束標籤,且區分大小寫

  3)元素的屬性值要用引號

  讀取XML文件,經過XDocument(須要添加命名空間)

  讀取整個XML文件: XDocument xd = XDocument.Load(XML文件路徑)

  循環遍歷每一個節點:

1)獲取根節點  XElement xeRoot = xd.Root;(xeRoot.ToString()表示XML文檔的內容)

2)遞歸遍歷XML中的每一個節點

  遍歷xeRoot下面的全部子節點:

     public static void GetEle(XElement xe)

            {

                foreach (XElement ele in xe.Elements())

                {

                    Console.WriteLine(ele.Name);

                    GetEle(ele);

                }

            }

           GetEle(xeRoot);

例:讀取XML數據

<CFX>

  <MSG>

     <交易碼val="1000" />

     <流水號val="100000000000000001" />

     <金額val="1234567890.12" />

     <付款機構val="1234" />

     <付款單位帳號val="12345678901234567890" />

     <收款機構val="1234" />

     <收款單位帳號val="12345678901234567890" />

  </MSG>

  <MSG>

     <交易碼val="1000" />

     <流水號val="100000000000000002" />

     <金額val="1234567890.12" />

     <付款機構val="1234" />

     <付款單位帳號val="12345678901234567890" />

     <收款機構val="1234" />

     <收款單位帳號val="12345678901234567890" />

  </MSG>

</CFX>

    VS中讀取XML的數據:

            XDocument xd = XDocument.Load("ytbank.xml");  //加載XML文件

            XElement xeRoot = xd.Root;  //獲取根節點

            foreach (XElement item in xeRoot.Elements())  //遍歷根節點,獲取第一級子節點(MSG)

                {

                  foreach (XElement itema in item.Elements())  //遍歷第一級子節點,獲取第二級子節點

                    {

                    Console.WriteLine("{0}:{1}", item.Element(itema.Name).Name, item.Element(itema.Name).Attribute("val").Value);  //獲取節點名和屬性值

                    }

                Console.WriteLine("==================================");

              }

XML寫入:

            XDocument xdoc = new XDocument();  //建立一個XML對象

            XElement xeleRoot = new XElement("Websites");  //建立一個根節點

            xdoc.Add(xeleRoot);  //將根節點添加到XML文件中

            xeleRoot.SetElementValue("baidu", "http://www.baidu.com");  //添加一個節點以及內容       

            XElement xeleGoogle = new XElement("website");  //建立一個節點

            xeleGoogle.SetAttributeValue("url", "http://www.google.com");  //添加屬性和屬性值

            xeleGoogle.SetElementValue("name", "谷歌"); //爲節點添加子節點

            xeleGoogle.SetElementValue("age", "14");

            xeleGoogle.SetElementValue("boss", "謝蓋爾");

            xeleRoot.Add(xeleGoogle); //將節點添加進根節點

            xdoc.Save("website.xml");  //保存一個XML文檔路徑

 

 

           

 

 

本文連接:.NET基礎筆記(C#),轉載請註明。

相關文章
相關標籤/搜索