2015年9月30日 星期三

Raspberry Pi 網路卡驅動問題 (USB WiFi: TOTOLINK N150UA)

網路卡驅動問題

在 Raspberry Pi 2 上使用TOTOLINK N150UA此型號之USB網卡,發生網卡無法驅動,以下為解決之步驟。

使用 lsusb 有裝置訊息,但無法使用
pi@rjcpi ~ $ lsusb
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 005: ID 148f:7601 Ralink Technology, Corp.
Bus 001 Device 006: ID 1a40:0101 Terminus Technology Inc. 4-Port HUB
Bus 001 Device 007: ID 0461:4de2 Primax Electronics, Ltd
Bus 001 Device 008: ID 0461:0010 Primax Electronics, Ltd HP Keyboard

從上述結果得知網卡ID為以下所示
Bus 001 Device 005: ID 148f:7601 Ralink Technology, Corp.

使用dmesg發現驅動錯誤
pi@rjcpi ~ $ dmesg | grep mt7601
[    4.805772] mt7601u 1-1.5:1.0: ASIC revision: 76010001 MAC revision: 76010500
[    4.821366] mt7601u 1-1.5:1.0: Direct firmware load for mt7601u.bin failed with error -2
[    4.836151] mt7601u: probe of 1-1.5:1.0 failed with error -2
[    4.848095] usbcore: registered new interface driver mt7601u

上述中發現缺少 mt7601u.bin 此檔案
因此,下載 mt7601u.bin 至 /lib/firmware/ 此目錄下
下載指令為
sudo wget https://github.com/porjo/mt7601/raw/master/src/mcu/bin/MT7601.bin -O /lib/firmware/mt7601u.bin


重新啟動後,即可使用

參考資料:
https://www.raspberrypi.org/forums/viewtopic.php?t=119095&p=808311

2015年9月21日 星期一

在 Google Blogger 中建立樹狀標籤分類


  1. 後台→版面設定→清除所有標籤 Label
  2. 重新命名文章標籤名稱為「第一層-第二層-第三層」,可以保留原標籤,例如… 文章: 筆電音量快捷鍵設定,標籤:Debian, Laptop, Linux-Debian-基礎操作及運用
  3. 至版面設定新增一個小工具「標籤」
  4. 後台 → 範本 → 修改 HTML→跳至小工具→Label1,找到:
    <b:widget id='Label1' locked='false' title='分類' type='Label'> 

    展開區塊,再找到:
     <h2><data:title/></h2> 

    將 <h2>.......</h2> 修改為:
     <h2><div id="treeLabel_toggle"><a href="http://wayne-fu.blogspot.com/2013/01/multi-tree-label-update.html" target="_blank"><img class="post-img" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXu5214D1Tmf4cGR2DdioycBy4zCZtZMBdQnRs-aiyFminbHan_oTcq3oQ8zzN-WE9cVzy7XxxY6jXOwz5PBLE8ggwdIowJhLjW_SsEaXOQreuzUw2NjKdfdL0R6bI-0LlJBu9CCQE2ES9/s1600/info.png"/></a></div><data:title/></h2> 
  5. 安裝程式碼,改完 <h2>.......</h2> 後,再往下三行找到:
     <b:if cond='data:display == &quot;list&quot;'>
          <ul>
          <b:loop values='data:labels' var='label'>
            <li>
              <b:if cond='data:blog.url == data:label.url'>
                <span expr:dir='data:blog.languageDirection'><data:label.name/></span>
              <b:else/>
                <a expr:dir='data:blog.languageDirection' expr:href='data:label.url'><data:label.name/></a>
              </b:if>
              <b:if cond='data:showFreqNumbers'>
                <span dir='ltr'>(<data:label.count/>)</span>
              </b:if>
            </li>
          </b:loop>
          </ul>
        <b:else/>
          <b:loop values='data:labels' var='label'>
            <span expr:class='&quot;label-size label-size-&quot; + data:label.cssSize'>
              <b:if cond='data:blog.url == data:label.url'>
                <span expr:dir='data:blog.languageDirection'><data:label.name/></span>
              <b:else/>
                <a expr:dir='data:blog.languageDirection' expr:href='data:label.url'><data:label.name/></a>
              </b:if>
              <b:if cond='data:showFreqNumbers'>
                <span class='label-count' dir='ltr'>(<data:label.count/>)</span>
              </b:if>
            </span>
          </b:loop>
        </b:if> 
    修改為下段,並再做細部修改:
     <div id='treeLabel_main' style='font-family: Arial;'><span class='item-control blog-admin' id='treeLabel_host'/></div>
    <style>
    #treeLabel_toggle {
      float: right;
      font-family: Arial;
    }
    #treeLabel_toggle a, #treeLabel_main a {
      font-size: 10pt;
      text-decoration: none;
    }
     
    /*查看色碼表 http://rhinejo.myweb.hinet.net/home/color/color-cord.html */
    .treeLabel_catText a:link {
    /*  color: #0b5394; /* 請填入大分類的顏色, 如果要使用系統預設的超連結顏色, 可刪除此行 */
      font-weight: bold;
    }
    .treeLabel_catText a:hover {
    /*  color: #b8b832;  /* 請填入滑鼠移過大分類要顯示的顏色, 如果要使用系統預設的超連結顏色, a:link 與 a:hover 的顏色都不要設定 */
      color: #FEFF91;
    }
     
    .treeLabel_category {  /* 這裡可設定大分類名稱區塊的 CSS */
      font-size: 12pt;
      margin-top: 4px;
    }
    .treeLabel_label {  /* 這裡可設定標籤名稱區塊的 CSS */
      font-size: 10pt;
      margin-top: 2px;  
    }
    </style>
     
    <script>
    //<![CDATA[
    var treeLabel = {
      category: ["Blog Usage", "Blender", "Embedded Boards", "Linux", "Programs", "Windows", "3D Printer"], // 雙引號內填入大分類名稱, 每個大分類用小寫逗號隔開, 最後一個大分類之後不可有逗號; 填入順序就是顯示的順序
      showLevel: 1,  // 預設打開的標籤層數, 填入 1 為全部收起的狀態
      showCategoryCount: "Y",  // 大分類若不顯示文章數, 請填入 "N"
      openLogo: "▼",  // 如使用圖檔,雙引號內請填入 http 開頭的網址
      closeLogo: "►",  // 如使用圖檔,雙引號內請填入 http 開頭的網址
      listLogo: "⇢",  // 如使用圖檔,雙引號內請填入 http 開頭的網址
      margin: 10,  // 縮排的像素值
      openText: "Open",  // 可改為自訂文字, 不顯示文字請改為 ""
      closeText: "Close",  // 可改為自訂文字, 不顯示文字請改為 "&nbsp;"
      interval: "Y"  // 預設每個大分類之間空一行, 如不要空行請填 "N"
    };
    //]]>
     
    treeLabel.data = [];
    treeLabel.labelName = [];
     
    <b:loop values='data:labels' var='label'>
     
    (function ()  {
      var a = &quot;<data:label.name/>&quot;,
          b = a.split(&quot;-&quot;),
          l = b.length,
          data = [],
          i;
    //<![CDATA[
    for(i=0;i<l;i++){if(i!=0&&i!=l-1&&b[i].search(" ")!=0){b[i]=" "+b[i]}data[i]=b[i]};
    //]]>
      treeLabel.data.push([data, &quot;<data:blog.languageDirection/>&quot;, &quot;<data:label.url/>&quot;, &quot;<data:label.count/>&quot;]);
    } )();
     
    </b:loop>
     
    //<![CDATA[
    treeLabel.dg=function(a){return document.getElementById(a)};treeLabel.toggle=function(n){var k=treeLabel.dg,o=treeLabel.labelName,b=o.length,p=treeLabel.openLogo,h=treeLabel.closeLogo,m,q,d,g,a,e,c,f;for(e=0;e<b;e++){m=o[e];f=m.length;for(c=0;c<f;c++){q=m.join("")+c;d="logo"+q;g=k(q);a=k(d);if(m[1]&&n==1){if(a&&!a.firstChild.src){a.innerHTML=p}if(a&&a.firstChild.src){a.firstChild.src=p}if(g){g.style.display="block"}}if(m[1]&&n==0){if(a&&!a.firstChild.src){a.innerHTML=h}if(a&&a.firstChild.src){a.firstChild.src=h}if(g){g.style.display="none"}}}}};treeLabel.swap=function(c,d){var f=treeLabel.dg,a=f(d),e=f(c),b=treeLabel.openLogo,g=treeLabel.closeLogo;if(!e.firstChild.src){e.innerHTML=(e.innerHTML==b)?g:b}else{e.firstChild.src=(e.firstChild.src==b)?g:b}a.style.display=(a.style.display=="block")?"none":"block"};(function(){var l=treeLabel.dg,S=treeLabel.data,F=treeLabel.category,R=[],D=[],u=[],f=[],z=F.length,g=S.length,E=treeLabel.showLevel,v=treeLabel.openLogo,e=treeLabel.closeLogo,N=treeLabel.listLogo,d=treeLabel.margin,I=(treeLabel.interval=="Y")?"<p/>":"",w="",t="",m="",a=0,J,A,o,c=l("treeLabel_host"),Q=(window.getComputedStyle)?(window.getComputedStyle(c).display=="none")?"<a href='http://wayne-fu.blogspot.com/2013/01/multi-tree-label-update.html' target='_blank'><img src='https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXu5214D1Tmf4cGR2DdioycBy4zCZtZMBdQnRs-aiyFminbHan_oTcq3oQ8zzN-WE9cVzy7XxxY6jXOwz5PBLE8ggwdIowJhLjW_SsEaXOQreuzUw2NjKdfdL0R6bI-0LlJBu9CCQE2ES9/s1600/info.png' title='Blogger 多層樹狀標籤\n程式設計:WFU BLOG' style='width: 20px; vertical-align: middle;'/></a>":"":"",P,O,M,C,B,K,L,s,H,q,G,h,b,r;v=(v.search("http")<0)?v:"<img src='"+v+"' style='vertical-align: middle;'/>";e=(e.search("http")<0)?e:"<img src='"+e+"' style='vertical-align: middle;'/>";N=(N.search("http")<0)?N:"<img src='"+N+"' style='vertical-align: middle;'/>";S.sort();for(P=0;P<g;P++){treeLabel.labelName[P]=S[P][0];D[P]=S[P][1];u[P]=S[P][2];f[P]=S[P][3]}R=treeLabel.labelName;for(P=0;P<z;P++){for(O=0;O<g;O++){J=R[O];if(J[1]&&J[0]==F[P]){a++;if(a!=0){a=1}L=function(){if(O-1<0){return 0}K=0,A=R[O-1];function i(){if(J[K]==A[K]){K++;i()}}i();return K};M=L();o=function(){if(J[M+1]){H=0;q="";G=J.join("")+M;h="logo"+G;b=(M<E-1)?v:e;r=(M<E-1)?"block":"none";if(treeLabel.showCategoryCount=="Y"){for(C=0;C<g;C++){A=R[C];for(B=M;B>=0;B--){if(J[B]!=A[B]){break}if(J[B]==A[B]&&B==0){H+=parseInt(f[C]);q="("+H+")"}}}}w+="<div class='treeLabel_category'><span onclick='treeLabel.swap(\""+h+'","'+G+"\");'><a id='"+h+"' href='javascript:' style='margin-left:"+M*d+"px;'>"+b+"</a>";w+="<span class='treeLabel_catText'><a href='javascript:'> "+J[M]+" </a></span></span><span>"+q+"</span></div><div id='"+G+"' style='display:"+r+"'>";M++;o()}else{w+="<div class='treeLabel_label' style='margin-left:"+M*d+"px;'>"+N+" <a dir='"+D[O]+"' href='"+u[O]+"'><span dir='ltr'>"+J[M]+"</span></a> ("+f[O]+")</div>";A=R[O+1]||"";m="";s=function(){if(M-1>0){m+="</div>";if(!A){M--;s()}else{for(K=M;K>=1;K--){if(J[K-1]!=A[K-1]){K=2;break}if(J[K-1]==A[K-1]&&K==1){break}}if(K==1){m=m.replace("</div>","")}else{M--;s()}}}};s();w+=m}};o()}}if(a==1){w+=I+"</div>";a=0}}l("treeLabel_main").innerHTML=w;t="<a href='javascript:treeLabel.toggle(1);'>"+v+"</a><span class='treeLabel_catText'><a href='javascript:treeLabel.toggle(1);'>"+treeLabel.openText+"</a></span> ";t+="<a href='javascript:treeLabel.toggle(0);'>"+e+"</a><span class='treeLabel_catText'><a href='javascript:treeLabel.toggle(0);'>"+treeLabel.closeText+"</a></span> ";if(navigator.userAgent.indexOf("MSIE")<0){t+=Q}l("treeLabel_toggle").innerHTML=t})();
    //]]>
    </script>
  6. Reference http://www.wfublog.com/2013/01/multi-tree-label-update.html#more
    http://lester116.blogspot.tw/2013/08/blogger.html

2015年9月20日 星期日

開機跳過「登入畫面」及「開機畫面」



一、跳過要帳號密碼登入的畫面
netplwiz















Reference:
http://changyang319.pixnet.net/blog/post/31344187-%E5%9C%A8windows-8.1%E4%B8%AD%EF%BC%8C%E5%A6%82%E4%BD%95%E8%B7%B3%E9%81%8E%E3%80%8C%E5%B8%B3%E8%99%9F%E7%99%BB%E5%85%A5%E3%80%8D%E5%8F%8A%E3%80%8C%E9%96%8B

CentOS 7 橋接網路設定

練習 RHCE 時,我們會用到兩台虛擬機 ( desktopX / serverX ),而這兩台虛擬機必須是同個網段,且最好與實體機可以相互連結,所以我們在建立虛擬機之前,要先建立橋接網路。

首先安裝下列套件:
[root@localhost ~]# yum -y install qemu-kvm libvirt virt-install bridge-utils ifconfig bind-utils

開啟虛擬網卡的服務與開機啟動:
[root@localhost ~]# systemctl start libvirt
[root@localhost ~]# systemctl enable libvirt


JAVA SL-275_09/20

/*
join
如果 A 執行緒正在運行,流程中允許 B 執行緒加入,等到 B 執行緒執行完畢再繼續 A 執行緒流程就可以使用 join() 方法完成需求,當執行緒使用 join() 加入至另一執行緒時,另一執行緒會等待被加入的執行緒工作完畢然後再續繼它的動作。
*/

//*****************************************************************************
// joinDemo.java
public class joinDemo{
public static void main(String args[]){
System.out.println("Main thread 開始…");
Thread threadB = new Thread(){
public void run(){
try{
System.out.println("Thread B 開始…");
for(int i=0;i<5;i++){
Thread.sleep(1000);
System.out.println("Thread S 執行…");
}
System.out.println("Thread B 結束");
}catch(InterruptedException e){
e.printStackTrace();
}
}
};
threadB.start();
try{
//Thread B 加入 Main Thread 流程
threadB.join();
}catch(InterruptedException ex){
ex.printStackTrace();
}
System.out.println("Main Thread 將結束…");
}
}
//*****************************************************************************
/*
Thread Group
每個執行緒都屬於某個執行緒群組,可以使用以下程式片段取得目前執行緒所屬的執行緒群組。
Thread.currentThread().getThreadGroup().getName();
可以自行指定執行緒群組,執行緒一旦加入,即無法更改群組。

java.lang.ThreadGroup 可以管理群組中的執行緒。
*/
//*****************************************************************************
package java_0920;

public class ThreadGroupDemo {
public static void main(String args[]){
ThreadGroup tg1 = new ThreadGroup("tg1");

Thread t1 = new Thread(tg1, new Runnable(){
public void run(){
throw new RuntimeException("t1 測試例外");
}
},"tg1");

t1.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {

public void uncaughtException(Thread t, Throwable e) {
System.out.printf("%s ... %s%n", t.getName(), e.getMessage());
}
});

Thread t2 = new Thread(tg1, new Runnable(){
public void run(){
throw new RuntimeException("t2 測試例外");
}
},"tg2");

t1.start();
t2.start();
}
}
//*****************************************************************************
// 兩執行緒同時間點別相同的方法,會出現競速狀態出現 Error
// 下例的 Error: Exception in thread "Thread-0" java.lang.ArrayIndexOutOfBoundsException
// java.lang.OutOfMemoryError 先不管它,此處為了探討競速物件。

import java.util.Arrays;

public class ArrayList {
private Object[] list;
private int next;
public ArrayList(int capacity){
list = new Object[capacity];
}
public ArrayList(){
this(16);
}

public void add(Object o){
//System.out.println("add start...");
if(next == list.length){
list = Arrays.copyOf(list, list.length * 2);
}
list[next++]=o;
}
public Object get(int index){
return list[index];
}
public int size(){
return next;
}
public static void main(String args[]){
ArrayList list = new ArrayList();
Thread t1 = new Thread(){
public void run(){
while(true){
list.add(1);
}
}
};
Thread t2 = new Thread(){
public void run(){
while(true){
list.add(2);
}
}
};
t1.start();
t2.start();
}
}
//-----------------------------------------------------------------------------------------------
// 同上範例,加入 synchronized 除掉競速問題
// 同樣會有  java.lang.OutOfMemoryError 此處不管它

import java.util.Arrays;

public class ArrayList {
private Object[] list;
private int next;
public ArrayList(int capacity){
list = new Object[capacity];
}
public ArrayList(){
this(16);
}
synchronized public void add(Object o){
if(next == list.length){
list = Arrays.copyOf(list, list.length * 2);
}
list[next++]=o;
}
public Object get(int index){
return list[index];
}
public int size(){
return next;
}
public static void main(String args[]){
ArrayList list = new ArrayList();

Thread t1 = new Thread(){
public void run(){
while(true){
synchronized(list){
list.add(1);
System.out.println(list.get(list.size()-1));
}
}
}
};
Thread t2 = new Thread(){
public void run(){
while(true){
synchronized(list){
System.out.println(list.get(list.size()-1));
list.add(2);
}
}
}
};
t1.start();
t2.start();
}
}
//*****************************************************************************

/*
synchronized 與 volatile
在 Java 中對資可見性的要求,可以使用 volatile 達到,在變數上宣告,表示變數是不穩定的是易變的,也就是可能在多執行緒下存取,可保證變數的可見性,也是是若執行緒變動了變數值,另一執行緒一可以看到變更。
不允許執行緒快取,變數的存取是在共享記憶體中進行。
*/









//*****************************************************************************

// 寫一個練習,分為四個檔案:
// Producer.java
package java_0920;

public class Producer implements Runnable {
private Clerk clerk;
public Producer(Clerk clerk){
this.clerk = clerk;
}
public void run(){
System.out.println("生產者開始生產…");
for(int product=1;product<=10;product++){
try{
Thread.sleep((int)(Math.random()*3000));
}catch(InterruptedException ex){
throw new RuntimeException(ex);
}
clerk.setProduct(product);
}
}
}

//Consumer.java
package java_0920;

public class Consumer implements Runnable {
private Clerk clerk;
public Consumer(Clerk clerk){
this.clerk = clerk;
}
public void run(){
System.out.println("消費者開始消費…");
for(int i=1;i<=10;i++){
try{
Thread.sleep((int)(Math.random()*3000));
}catch(InterruptedException ex){
throw new RuntimeException(ex);
}
int product = clerk.getProduct();
}
}
}

//Clerk.java
package java_0920;

public class Clerk {
private int product = -1 ;

public synchronized int getProduct() {
while(this.product != -1){
try{
wait();
}catch(InterruptedException e){
throw new RuntimeException(e);
}
}
int p = this.product;
System.out.printf("消費者取得…(%d)%n",this.product);
this.product=-1;
notify();
return p;
}

public synchronized void setProduct(int product) {
while(this.product != -1){
try{
wait();
}catch(InterruptedException e){
throw new RuntimeException(e);
}
}
this.product = product;
System.out.printf("生產者設定…(%d)%n", this.product);
notify();
}

}

//ProducerConsumerDemo.java
package java_0920;

public class ProducerConsumerDemo {
public static void main(String args[]){
Clerk clerk = new Clerk();
new Thread(new Producer(clerk)).start();
new Thread(new Consumer(clerk)).start();
}
}
//*****************************************************************************

/*
Collection 集合架構介面關係圖


※可動態產生集合元素
可置入不同型別的資料,依照各集合的特性有:排序性、順序性、不允許重複、是否有鍵值的使用。

<String, Integer> 泛型

public interface Set implements Collection
其特性是無順序性,並且元素與元素之間不得重複。
其利用 equal() 方法來判斷加入的物件是否重複,Set 是資料具唯一性但無順序性的集。

※ 不是用 equals (用於比較字串)
*/
//*****************************************************************************
//HashSet
//沒有順序性 (擺放位置是根據 hashCode) 不允許重複

import java.util.*;

public class HashSetDemo {
public static void main(String argsp[]){
HashSet<String> s = new HashSet<String>();
s.add("SCJP");
s.add("SCWCD");
s.add("SCBCD");

Iterator i = s.iterator();
while(i.hasNext()){
String str = (String)i.next();
System.out.println(str + " ");
}
}
}
//*****************************************************************************
//練習:重複輸入的資料只顯示一個

import java.util.*;

public class HashSetDemo2 {
public static void main(String args[]){
Set<String> words = new HashSet<String>();
Scanner scanner = new Scanner(System.in);
System.out.println("Input english word:");
String line = scanner.nextLine();
String tokens[] = line.split(" ");
for(String token:tokens){
words.add(token);
}

System.out.printf("不重複的單字有(%d)個 %s%n", words.size(), words);

}
}
//執行後自己手動輸入單字,以空白隔開,會自動過濾並顯示出不重複單字。
//*****************************************************************************

import java.util.*;

class Student {
private String name;
private String number;
Student(String name, String number){
this.name=name;
this.number=number;
}
public String toString(){
return String.format("(%s %s)", name, number);
}
}

public class StudentDemo{
public static void main(String args[]){
/*
Set<String> set = new HashSet<String>();
set.add(new Student("Justin", "B6789").toString());
set.add(new Student("Monica", "B8765").toString());
set.add(new Student("Joe", "B213678").toString());
*/
Set set = new HashSet();
set.add(new Student("Monica", "B8765"));
set.add(new Student("Justin", "B6789"));
set.add(new Student("Joe", "B213678"));


System.out.println(set);
}
}



2015年9月13日 星期日

vsftpd Server

Setup vsftpd on Debian/Jessie.

##ReadMore##

安裝
sudo apt-get install vsftpd

設定檔:
sudo vi /etc/vsftpd.conf
編輯設定如下…

‧設定 FTP 家目錄 (自訂)
local_root=/home/ftp

‧開放寫入權限(除 Anonymous)
write_enable=YES

‧設定網域權限,使用 /etc/hosts.deny & /etc/hosts.allow
1.vim vsftpd.conf
tcp_wrappers=YES

2.vim /etc/hosts.deny
vsftpd: ALL

3.vim /etc/hosts.allow
vsftpd:120.117.73.0/24,120.117.72.0/24

‧設定只允許某些人登錄ftp,且限制不能離開家目錄
1.vi /etc/vsftpd.conf
chroot_local_user=NO
chroot_list_enable=yes
chroot_list_file=/etc/vsftpd.chroot_list

2.vi /etc/vsftpd.chroot_list
$USER

承上,若登入 FTP 出現錯誤:
00 OOPS: vsftpd: refusing to run with writable root inside chroot()
1.則需要修改所設家目錄權限
chmod 555 /home/ftp

2.根目錄以後目錄可以保有寫入權限
chmod 755 /home/ftp/*



‧開放匿名登入
vi /etc/vsftpd.conf
anonymous_enable=YES
anon_root=/home/ftp

‧上傳檔案權限 rwxr-xr-x
local_umask=022


。重啟服務
systemctl restart vsftpd.service

.Video Player on FTP Stream
1.Windows: Potplayer
2.Linux: SMPlayer


Reference:
http://serverfault.com/questions/577393/vsftpd-limit-connection-to-a-set-of-ip-addresses
http://www.linuxquestions.org/questions/linux-software-2/changing-default-directory-on-vsftp-server-167202/ 
http://www.liverx.org/2013/01/13/%E8%A7%A3%E6%B1%BAvsftpd%E4%B8%8D%E8%83%BD%E9%9B%A2%E9%96%8B%E5%AE%B6%E7%9B%AE%E9%8C%84%E7%9A%84%E6%96%B9%E5%BC%8F/ 
http://blog.miniasp.com/post/2012/08/14/Secure-vsFTPd-with-chroot-and-multiple-user-access-permission-tips.aspx 









JAVA SL-275_0913

/*
‧使用 finally
無論 try 區塊中有無發生例外,若撰寫有 finally 區塊,則 finally 區塊一定會執行,如果程式撰寫的流程中先 return 了,而且也有寫 finally 區塊,那 finally 區塊會先執行完後,再將值傳回。

try{
do something…
}catch{
do something…
}finally{ // Always 會執行,且優先過 try-cache
….
}

可以允許的程式寫法:
try-cache
try-finally
try-cache-finally

錯誤的寫法:
catch finally
*/
/******************************************************************************/
public class FinallyDemo{
public static int test(boolean flag){
try{
if(flag){
return 1;
}
}finally{
System.out.println("finally...");
}
return 0;
}
public static void main(String args[]){
System.out.println(test(true));
}
}
/******************************************************************************/

/*
java.lang.AutoCloseable 介面
JDK 7 新增了自動關閉資源語法可用的套件,必須實作 java.lang.AutoCloseable 介面,其僅定義了 close() 方法
package java.lang.*;

public interface AutoCloseable{
void close() throws Exception;
}
*/

/*
執行序流程圖

---

執行序的執行狀態:
起始狀態
Thread t = new Thread();

可執行狀態
Thread t = new Thread();
t.start(); t.yield();

執行狀態
實作 Runnable 介面
繼承 Thread 類別
public void run(){
……
}

非可執行狀態
Thread t - new Thread();
sleep().wait().suspend();

結束狀態
stop()
正常結束

*/
/******************************************************************************/
// Thread

public class ThreadDemo{
public static void main(String args[]){
System.out.println("Hello Java 測試");
String str = Thread.currentThread().getName();
System.out.println("Thread name: " + str);
System.out.println(Thread.activeCount());
}
}

/******************************************************************************/
// 練習 Thread 寫龜兔賽跑
// TortoisHareDemo.java

public class TortoisHareDemo{
public static void main(String args [])throws InterruptedException{
boolean flags[]={true,false};
int totalStep=10;
int tortoiseStep=0;
int hareStep=0;
System.out.println("龜兔賽跑開始…");
while(tortoiseStep < totalStep && hareStep <totalStep){
Thread.sleep(1000);
tortoiseStep++;
System.out.printf("烏龜跑了 %d 步…%n", tortoiseStep);
boolean isHareSleep=flags[((int)(Math.random()*10))%2];
if(isHareSleep){
System.out.println("兔子睡著了…zzz");
}else{
hareStep+=2;
System.out.printf("兔子跑了 %d 步…%n", hareStep);
}
}
}
}
/******************************************************************************/
// 練習 Thread 寫龜兔賽跑,拆開來寫成三個檔案:
// Hare.java

public class Hare implements Runnable{
private boolean[] flags = {true,false};
private int totalStep;
private int step;
public Hare(int totalStep){
this.totalStep=totalStep;
}
public void run(){
try{
while(step<totalStep){
Thread.sleep(1000);
boolean isHareSleep = flags[((int)(Math.random()*10))%2];
if(isHareSleep){
System.out.println("兔子睡著了...");
}
else{
step +=2;
System.out.printf("兔子跑了 %d 步…%n", step);
}
}
}catch(InterruptedException ex){
throw new RuntimeException(ex);
}
}
}
//------------------------------------------------------------------------------------
//Tortoise.java

public class Tortoise implements Runnable{
private int totalStep;
private int step;
public Tortoise(int totalStep){
this.totalStep=totalStep;
}
public void run(){
try{
while(step<totalStep){
Thread.sleep(1000);
step++;
System.out.printf("烏龜跑了 %d 步 %n", step);
}
}catch(InterruptedException ex){
throw new RuntimeException(ex);
}
}
}
//------------------------------------------------------------------------------------
//TortoiseHareRace.java

public class TortoiseHareRace{
public static void main(String args[]){
Tortoise t = new Tortoise(10);
Hare h = new Hare(10);
Thread tortoiseThread = new Thread(t);
Thread hareThread = new Thread(h);
tortoiseThread.start();
hareThread.start();
}
}
/******************************************************************************/
// 實作 Thread 類別

class HelloThread extends Thread{
HelloThread(String str){
super(str);
}
public void run(){
for(int i=0;i<1000;i++){
String s = Thread.currentThread().getName();
System.out.println(s +" : " + i);
}
}
}
public class TestThread{
public static void main(String args[]){
HelloThread h =new HelloThread("Monic");
h.start();
}
}

/*
實作 Runnable 介面,好處是有彈性,還有機會繼承其它類別
 繼承 Thread 類別,通常是為了直接利用 Thread 類別中的一些方法才會直接繼承 Thread 類別
*/
/******************************************************************************/
/*
執行序有其優先權,可用 Thread 類別底下的 setPriority() 方法設定優先權,可設定值為 1~10,預設是 5 如果超出 1~10 以外的設定值會拋出 IllegalArgnmentException,數字越大優先權愈高,越優先排入;cpu 若相同,則輪流執行。
*/

// PersonDemo.java
class Person extends Thread{
Person(String str){
super(str);
}
public void run(){
String name=Thread.currentThread().getName();
int priority = Thread.currentThread().getPriority();
Thread.State state = Thread.currentThread().getState();
System.out.println( name + "優先序─ " + priority + ",狀態─ " + state);
for(int i=1;i<=10;i++){
System.out.println(name + "跑完第" + i + "圈");
if(name.equals("Ken") && i%3==0 ){
System.out.println(name + "休息 1 秒…");
}
try{
Thread.sleep(1000);
}catch(InterruptedException ex){
ex.printStackTrace();
}
}
}
}
public class PersonDemo{
public static void main(String args[]){
Person p1 = new Person("Ron");
Person p2 = new Person("Ken");
p1.start();
p2.start();
System.out.println("正在執行的執行序:" + Thread.activeCount());
}
}


/******************************************************************************/
/*
有幾種狀況會讓執行序進入 Blocked 狀態:
呼叫 Thread.sleep() 方法
進入 synchronized 前競爭物件鎖定的阻斷
呼叫 wait() 的阻斷
等待 input/output 完成

一個進入 Blocked 狀態的執行序可由另一個執行序呼叫該執行序的 interrupt() 方法,讓它離開 Blocked 狀態。
*/
/******************************************************************************/
// 比較 synchronized  同步

// 無同步
class Company{
static int sum=0;
static void add(int n){
int tmp=sum;
tmp+=n;
try{
Thread.sleep(1000);
}catch(InterruptedException e){}
sum=tmp;
String name=Thread.currentThread().getName();
System.out.println("執行緒:" + name + ",存款為:" + sum);
}
}
class Ccompany extends Thread{
Ccompany(String str){
super(str);
}
public void run(){
for(int i=1;i<=3;i++)
Company.add(100);
}
}

public class SynchronizedDemo{
public static void main(String args[]){
Ccompany c1 = new Ccompany("Ron");
Ccompany c2 = new Ccompany("Ken");
c1.start();
c2.start();
}
}
/*
輸出結果:
*/
//----------------------------------------------------------------------------
// 加入同步
class Company{
static int sum=0;
synchronized static void add(int n){
int tmp=sum;
tmp+=n;
try{
Thread.sleep(1000);
}catch(InterruptedException e){}
sum=tmp;
String name=Thread.currentThread().getName();
System.out.println("執行緒:" + name + ",存款為:" + sum);
}
}
class Ccompany extends Thread{
Ccompany(String str){
super(str);
}
public void run(){
for(int i=1;i<=3;i++)
Company.add(100);
}
}

public class SynchronizedDemo{
public static void main(String args[]){
Ccompany c1 = new Ccompany("Ron");
Ccompany c2 = new Ccompany("Ken");
c1.start();
c2.start();
}
}

/*
輸出結果:
*/
/******************************************************************************/
//wait

class Company{
static int sale = 0;
synchronized static void add(int n){
String name = Thread.currentThread().getName();
int sum = sale;
sum = sum + n;
System.out.println(name + "銷售量" + n + ",公司銷售量:" + sum);
sale=sum;
}
}
class Ccompany extends Company implements Runnable{
private String id;
public Ccompany(String id){
this.id=id;
}
public void run(){
for(int i=1;i<=10;i++){
Company.add(i);
if(sale > 5){
System.out.println("庫存量超過 5,停止生產…");
try{
wait();
}catch(InterruptedException e){
System.out.println("繼續生產...");
}
}
}
}
}

public class WaitDemo{
public static void main(String args[]){
Thread s1 = new Thread(new Ccompany("S 分店"),"C 分店");
Thread s2 = new Thread(new Ccompany("S2 分店"),"C2 分店");
s1.start();
s2.start();
//s2.interrupt();
}
}


2015年9月7日 星期一

JAVA SL-275_09/06

/*
‧匿名內部類別:簡單的說就是沒有宣告名稱的類別,直接以 {....} 來實作的類別程式碼。
*/

// 利用匿名內部類別來實作 interface
// Anomouse.java

interface Pet{
        String attr="aute";
        void skill();
        void move();
}

public class Anomouse{
        public static void main(String args[]){
                Pet p = new Pet(){              //無 ;
                        public void skill(){
                                System.out.println("拎拖鞋");
                        }
                        public void move(){
                                System.out.println("移動");
                        }
                };
                p.skill();
                p.move();
        }
}

/*
其中,編譯完後,會出現 Anomouse$1.class 匿名內部類別,其內容包含:
 Pet p = new Pet(){              //無 ;
                        public void skill(){
                                System.out.println("拎拖鞋");
                        }
                        public void move(){
                                System.out.println("移動");
                        }
                };
若有 n 個內部類別則會以 $流水號 來依序往後排。
*/
/******************************************************************************/
/*
‧靜態內部類別:是在宣告時加上 static ,使其物件實體配置在記憶體 Global 區塊中。
*/

class MyOuter{
        static class MyStatic{
                public void fooA(){
                        System.out.println("Hello" + "no static");
                }
                public static void fooB(){
                        System.out.println("Hello" + "static method");
                }
        }
}

public class StaticInnerClass{
        public static void main(String args[]){
                MyOuter.MyStatic f = new MyOuter.MyStatic();
                f.fooB();
                f.fooA();
                MyOuter.MyStatic.fooB(); //配置為 static 才可以直接執行!
        }
}
/******************************************************************************/
class MyOuter{
        private int x = 7;
        static private int sx = 9;
        static class MyStatic{
                private int x = 77;
                static private int sx = 99;
                public void fooA(){
                        System.out.println("fooA non-static");
                        System.out.println(sx);
                        System.out.println(MyOuter.sx);
                        System.out.println(x);
                        System.out.println(new MyOuter().x);
                }
                public static void fooB(){
                        System.out.println("fooB static method");
                        System.out.println(sx);
                        System.out.println(MyOuter.sx);
                }
        }
}
public class StaticInnerClass2{
        public static void main(String args[]){
        MyOuter.MyStatic f = new MyOuter.MyStatic();
        f.fooA();
        MyOuter.MyStatic.fooB();
        }
}
/******************************************************************************/
/*
‧try-catch
‧Bug 的分類:
程式語法上的錯誤。
執行時期的錯誤
ex:陣列元素索引值超出最大範圍 or 整數除以 0
邏輯的錯誤。
try{
// do something…
}catch(Exception e){
// do something…(通常在這做堆疊追蹤)
}

Java 中用依處理錯誤的類別:Throwable, Error, Exception

Error → 指的是系統本身發出的錯誤訊息,也有可能是程式所造成。
Exception → 是一個不正常的程式在執行時期所觸發的事件。
Throwable → 為 Error, Exception 的父類別,若其無法處理,則再往上丟給 JVM 處理。
JVM → Throwable → Error
         ↘ Exception

try
撰寫時可將容易發生錯誤的程式碼 package 在 try 中。
catch
產生錯誤事件時,catch 進行攔截,並執行此區塊內程式碼。
*/
/*
※Exception 大多放在 Input/Ouput 位置,若一開始不知道要放什麼類型的 exception,
則可以先讓程式去 run,看它出現什麼錯誤訊息。
以下為例:
public class Test{
        public static void main(String args[]){
                int arr[] = new int[5];
                arr[10] = 7;
                System.out.println("end of main method");
        }
}
故意讓它 run 出錯誤訊息,再加到 try-catch 中:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10
        at Test.main(Test.java:4)
/*
public class Test{
        public static void main(String args[]){
                try{
                int arr[] = new int[5];
                arr[10] = 7;
                }catch(ArrayIndexOutOfBoundsException e){
                        System.out.println("catch to Exception");
                        System.out.println("Exception:" + e);
                        System.out.println("e.Message:" + e.getMessage());
                }
                System.out.println("end of main method");
        }
}
/******************************************************************************/
// Average.java
import java.util.*;

public class Average{
        public static void main(String args[]){
                Scanner scanner = new Scanner(System.in);
                double sum = 0 ;
                int count = 0;
                int number = 0 ;
                System.out.println("Key Integer Num. (exit:0):");
                while(true){
                        try{
                                number = scanner.nextInt();
                                if(number == 0 ){
                                        break;
                                }
                                sum += number ;
                                count++;
                        }catch(InputMismatchException e){
                                System.out.println("Error:Input is Integer.");
                                System.out.println("Exception Message:" + e);
                                break;
                        }
                }
                System.out.printf("平均:%.2f%n", sum/count);
        }
}
/******************************************************************************/
//例外繼承架構:
try{
do something…
}catch(IOException e ){ //直系子類別
e.printStackTrace();
}catch(InterruptedException e){
e.printStackTrace();
}catch(ClassCastException e){ //直系父類別
e.printStackTrace();
}
/******************************************************************************/
// Java 7.0 之後 → 多重捕捉 multi-catch
try{
do something…
}catch(IOException | InterruptedException | ClassCastExeption e){
e.printStackTrace(); //堆疊追蹤
}
※左邊的例外不得是右邊的父類別!
/******************************************************************************/
/*
‧利用 throw 丟出例外
throw 用來呼叫或傳遞一個例外,所以可以利用它在程式中觸發一個例外
*/
throw 例外物件變數
→丟出一個例外物件變數
throw new Exception(錯誤訊息字串)
→丟出一個匿名的例外物件
/******************************************************************************/
// FileUtil.java
import java.io.*;
import java.util.*;

public class FileUtil{
        public static String readFile(String name)
        throws FileNotFoundException{
                StringBuilder builder = new StringBuilder();
                try{
                        Scanner scanner = new Scanner(new FileInputStream(name));
                        String text = null;
                        while(scanner.hasNext()){
                                builder.append(scanner.nextLine());
                                builder.append('\n');
                        }
                }catch(FileNotFoundException ex){
                        ex.printStackTrace();
                        throw ex;
                }
                return builder.toString();
        }
}
//---------------------------------------------------------------------
// Demo.java
import java.io.*;

public class Demo{
        public static void main(String args[])
        throws Exception{               // 宣告方法中拋出例外
                System.out.println(FileUtil.readFile("C:\\java\\0906\\Main.java"));
        }
        public static void doSome(String arg)
        throws FileNotFoundException, EOFException{
                try{
                        if("one".equals(arg)){
                                throw new FileNotFoundException();
                        }else{
                                throw new EOFException();
                        }
                }catch(IOException ex){
                        ex.printStackTrace();
                        throw ex;       // 執行時拋出例外
                }
        }
}
//---------------------------------------------------------------------
// 自訂路徑(要同 Demo.java 截取檔案路徑),
隨便編寫內容。 例: C:\java\0906\Main.java
Lccnet
/******************************************************************************/
/*
編譯出 .jar 執行檔
*/
以 eclipse 軟體
File > New > Java Project > TEST
“TEST/src” 右鍵 > New > Class > Main3 (勾選 public static void….)
import javax.swing.*;

public class Main3 {

public static void main(String[] args) {
String s = JOptionPane.showInputDialog("Input number");
JOptionPane.showMessageDialog(null, s);
}

}
對 “TEST” 右鍵 > Export > Java > Runnable JAR file

以指令 jar
編寫檔案 Main3.java ,內容同上。
編譯出 Class檔:javac Main3.java
jar cfe myJRE.jre Main3 Main3.class
/******************************************************************************/
// 堆疊處理
// Main.java

public class Main {

public static String a(){
String text =null;
return text.toUpperCase();
}
public static void b(){
a();
}
public static void c(){
try{
b();
}catch(NullPointerException e){
e.printStackTrace();
Throwable t = e.fillInStackTrace();
throw(NullPointerException) t;
}
}
public static void main(String[] args) {
try{
c();
}catch(NullPointerException ex){
ex.printStackTrace();
}
}
}
/******************************************************************************/
/*
‧ Assert 斷言

assert boolean_expression;
assert boolean_expression:detail_expression;

boolean_expression 若為 true 則什麼事都不會發生;
若為 false 則會發生 java.lang.AssertionError;
*/
//----------------------------------------------------------------------------
// AssertDemo.java

public class AssertDemo{
        final int ACTION_STOP=0;
        final int ACTION_RIGHT=1;
        final int ACTION_LEFT=2;
        final int ACTION_UP=3;

        public static void main(String args[]){
                new AssertDemo().play(0);
                new AssertDemo().play(1);
                new AssertDemo().play(2);
                new AssertDemo().play(3);
//              new AssertDemo().play(5);
                new AssertDemo().testScore(0);
                new AssertDemo().testScore(100);
                new AssertDemo().testScore(-1);
        }

        public void testScore(int score){
                assert(score >= 0 && score <= 100):"成績錯誤";
                System.out.println("score = " + score);
        }

        public void play(int action){
                switch(action){
                case ACTION_STOP:
                        System.out.println("停止撥放");
                        break;
                case ACTION_RIGHT:
                        System.out.println("向右撥放");
                        break;
                case ACTION_LEFT:
                        System.out.println("向左撥放");
                        break;
                case ACTION_UP:
                        System.out.println("向上撥放");
                        break;
                default:
                        assert false : "非定義的常數";
                }
        }
}

/*
※注意,編譯完執行要加 -ea 參數啟用 Assertion
javac AssertDemo.java
java -ea AssertDemo
*/



/******************************************************************************/