1. 顯示系統中所有Android平臺: android list targets 2. 顯示系統中所有AVD(模擬器): android list avd 3. 建立AVD(模擬器): android create avd --name 名稱 --target 平臺編號 4. 啓動模擬器: emulator -avd 名稱 -sdcard ~/名稱.img (-skin 1280x800) 5. 刪除AVD(模擬器): android delete avd --name 名稱 6. 建立SDCard: mksdcard 1024M ~/名稱.img 7. AVD(模擬器)所在位置: Linux(~/.android/avd) Windows(C:\Documents and Settings\Administrator\.android\avd) 8. 啓動DDMS: ddms 9. 顯示當前運行的所有模擬器: adb devices 10. 對某一模擬器執行命令: abd -s 模擬器編號 命令 11. 安裝應用程序: adb install -r 應用程序.apk 12. 獲取模擬器中的文件: adb pull <remote> <local> 13. 向模擬器中寫文件: adb push <local> <remote> 14. 進入模擬器的shell模式: adb shell 15. 啓動SDK,文檔,實例下載管理器: android 16. 缷載apk包: adb shell cd data/app rm apk包 exit adb uninstall apk包的主包名 adb install -r apk包 17. 查看adb命令幫助信息: adb help 18. 在命令行中查看LOG信息: adb logcat -s 標籤名 19. adb shell後面跟的命令主要來自: 源碼\system\core\toolbox目錄和源碼\frameworks\base\cmds目錄。 20. 刪除系統應用: adb remount (從新掛載系統分區,使系統分區從新可寫)。 adb shell cd system/app rm *.apk 21. 獲取管理員權限: adb root 22. 啓動Activity: adb shell am start -n 包名/包名+類名(-n 類名,-a action,-d date,-m MIME-TYPE,-c category,-e 擴展數據,等)。 23、發佈端口: 你能夠設置任意的端口號,作爲主機向模擬器或設備的請求端口。如: adb forward tcp:5555 tcp:8000 24、複製文件: 你可向一個設備或從一個設備中複製文件, 複製一個文件或目錄到設備或模擬器上: adb push <source> <destination></destination></source> 如:adb push test.txt /tmp/test.txt 從設備或模擬器上覆制一個文件或目錄: adb pull <source> <destination></destination></source> 如:adb pull /addroid/lib/libwebcore.so . 25、搜索模擬器/設備的實例: 取得當前運行的模擬器/設備的實例的列表及每一個實例的狀態: adb devices 26、查看bug報告: adb bugreport 27、記錄無線通信日誌: 通常來講,無線通信的日誌很是多,在運行時不必去記錄,但咱們仍是能夠經過命令,設置記錄: adb shell logcat -b radio 28、獲取設備的ID和序列號: adb get-product adb get-serialno 29、訪問數據庫SQLite3 adb shell sqlite3 busybox BusyBox 是標準 Linux 工具的一個單個可執行實現。BusyBox 包含了一些簡單的工具,例如 cat 和 echo,還包含了一些更大、更復雜的工具,例如 grep、find、mount 以及 telnet。有些人將 BusyBox 稱爲 Linux 工具裏的瑞士軍刀.簡單的說BusyBox就好像是個大工具箱,它集成壓縮了 Linux 的許多工具和命令。 1、 BusyBox 的誕生 BusyBox 最初是由 Bruce Perens 在 1996 年爲 Debian GNU/Linux 安裝盤編寫的。其目標是在一張軟盤上建立一個可引導的 GNU/Linux 系統,這能夠用做安裝盤和急救盤。 2、busybox的用法 能夠這樣用busybox #busybox ls 他的功能就至關運行ls命令 最經常使用的用法是創建指向busybox的連接,不一樣的連接名完成不一樣的功能. #ln -s busybox ls #ln -s busybox rm #ln -s busybox mkdir 而後分別運行這三個連接: #./ls #./rm #./mkdir 就能夠分別完成了ls rm 和mkdir命令的功能.雖然他們都指向同一個可執行程序busybox,可是隻要連接名不一樣,完成的功能就不一樣,不少linux網站都提供busybox的源代碼下載。 3、配置busybox busybox的配置程序和linux內核菜單配置方式簡直如出一轍.熟悉用make menuconfig方式配置linux內核的朋友很容易上手. #cp busybox-1.00.tar.gz /babylinux #cd /babylinux #tar xvfz busybox-1.00.tar.gz #cd busybox-1.00 #make menuconfig 下面是須要編譯進busybox的功能選項。 General Configuration應該選的選項 Show verbose applet usage messages Runtime SUID/SGID configuration via /etc/busybox.conf Build Options Build BusyBox as a static binary (no shared libs) 這個選項是必定要選擇的,這樣才能把busybox編譯成靜態連接的可執行文件,運行時才獨立於其餘函數庫.不然必須要其餘庫文件才能運行,在單一個linux內核不能使它正常工做. Installation Options Don't use /usr 這個選項也必定要選,不然make install 後busybox將安裝在原系統的/usr下,這將覆蓋掉系統原有的命令.選擇這個選項後,make install後會在busybox目錄下生成一個叫_install的目錄,裏面有busybox和指向它的連接. 其它選項都是一些linux基本命令選項,本身須要哪些命令就編譯進去,通常用默認的就能夠了,配置好後退出並保存。 4、編譯並安裝busybox #make #make install 編譯好後在busybox目錄下生成子目錄_install,裏面的內容: drwxr-xr-x 2 root root 4096 11月 24 15:28 bin rwxrwxrwx 1 root root 11 11月 24 15:28 linuxrc -> bin/busybox drwxr-xr-x 2 root root 4096 11月 24 15:28 sbin 其中可執行文件busybox在bin目錄下,其餘的都是指向他的符號連接. Android系統在超級終端下必會的命令大全(二) 1、安裝和登陸命令 reboot 1.做用 reboot命令的做用是從新啓動計算機,它的使用權限是系統管理者。 2.格式 reboot [-n] [-w] [-d] [-f] [-i] 3.主要參數 -n: 在重開機前不作將記憶體資料寫回硬盤的動做。 -w: 並不會真的重開機,只是把記錄寫到/var/log/wtmp文件裏。 -d: 不把記錄寫到/var/log/wtmp文件裏(-n這個參數包含了-d)。 -i: 在重開機以前先把全部與網絡相關的裝置中止。 mount 1.做用 mount命令的做用是加載文件系統,它的用權限是超級用戶或/etc/fstab中容許的使用者。 2.格式 mount -a [-fv] [-t vfstype] [-n] [-rw] [-F] device dir 3.主要參數 -h:顯示輔助信息。 -v:顯示信息,一般和-f用來除錯。 -a:將/etc/fstab中定義的全部文件系統掛上。 -F:這個命令一般和-a一塊兒使用,它會爲每個mount的動做產生一個行程負責執行。在系統須要掛上大量NFS文件系統時能夠加快加載的速度。 -f:一般用於除錯。它會使mount不執行實際掛上的動做,而是模擬整個掛上的過程,一般會和-v一塊兒使用。 -t vfstype:顯示被加載文件系統的類型。 -n:通常而言,mount掛上後會在/etc/mtab中寫入一筆資料,在系統中沒有可寫入文件系統的狀況下,能夠用這個選項取消這個動做。 4.應用技巧 在 Linux和Unix系統上,全部文件都是做爲一個大型樹(以/爲根)的一部分訪問的。要訪問CD-ROM上的文件,須要將CD-ROM設備掛裝在文件樹中的某個掛裝點。若是發行版安裝了自動掛裝包,那麼這個步驟可自動進行。在Linux中,若是要使用硬盤、光驅等儲存設備,就得先將它加載,當儲存設備掛上了以後,就能夠把它當成一個目錄來訪問。掛上一個設備使用mount命令。在使用mount這個指令時,至少要先知道下列三種信息:要加載對象的文件系統類型、要加載對象的設備名稱及要將設備加載到哪一個目錄下。 (1)Linux能夠識別的文件系統 ◆ Windows 95/98經常使用的FAT 32文件系統:vfat ; ◆ Win NT/2000 的文件系統:ntfs ; ◆ OS/2用的文件系統:hpfs; ◆ Linux用的文件系統:ext二、ext3; ◆ CD-ROM光盤用的文件系統:iso9660。 雖然vfat是指FAT 32系統,但事實上它也兼容FAT 16的文件系統類型。 (2)肯定設備的名稱 在Linux中,設備名稱一般都存在/dev裏。這些設備名稱的命名都是有規則的,能夠用「推理」的方式把設備名稱找出來。例如,/dev/hda1這個 IDE設備,hd是Hard Disk(硬盤)的,sd是SCSI Device,fd是Floppy Device(或是Floppy Disk?)。a表明第一個設備,一般IDE接口能夠接上4個IDE設備(好比4塊硬盤)。因此要識別IDE硬盤的方法分別就是hda、hdb、hdc、 hdd。hda1中的「1」表明hda的第一個硬盤分區 (partition),hda2表明hda的第二主分區,第一個邏輯分區從hda5開始,依此類推。此外,能夠直接檢查/var/log/messages文件,在該文件中能夠找到計算機開機後系統已辨認出來的設備代號。 (3)查找掛接點 在決定將設備掛接以前,先要查看一下計算機是否是有個/mnt的空目錄,該目錄就是專門用來看成掛載點(MountPoint)的目錄。建議在/mnt裏建幾個/mnt/cdrom、/mnt/floppy、/mnt/mo等目錄,看成目錄的專用掛載點。舉例而言,如要掛載下列5個設備,其執行指令可能以下 (假設都是Linux的ext2系統,若是是Windows XX請將ext2改爲vfat): 軟盤 ===>mount -t ext2 /dev/fd0 /mnt/floppy cdrom ===>mount -t iso9660 /dev/hdc /mnt/cdrom SCSI cdrom ===>mount -t iso9660 /dev/sdb /mnt/scdrom SCSI cdr ===>mount -t iso9660 /dev/sdc /mnt/scdr 不過目前大多數較新的Linux發行版本(包括紅旗 Linux、中軟Linux、Mandrake Linux等)均可以自動掛裝文件系統,但Red Hat Linux除外。 umount 1.做用 umount命令的做用是卸載一個文件系統,它的使用權限是超級用戶或/etc/fstab中容許的使用者。 2.格式 unmount -a [-fFnrsvw] [-t vfstype] [-n] [-rw] [-F] device dir 3.使用說明 umount 命令是mount命令的逆操做,它的參數和使用方法和mount命令是同樣的。Linux掛裝CD-ROM後,會鎖定CD—ROM,這樣就不能用CD- ROM面板上的Eject按鈕彈出它。可是,當再也不須要光盤時,若是已將/cdrom做爲符號連接,請使用umount/cdrom來卸裝它。僅當無用戶 正在使用光盤時,該命令纔會成功。該命令包括了將帶有當前工做目錄看成該光盤中的目錄的終端窗口。 exit 1.做用 exit命令的做用是退出系統,它的使用權限是全部用戶。 2.格式 exit 3.參數 exit命令沒有參數,運行後退出系統進入登陸界面。 -------------------------------------------------------------------------------- 做者: ☆-☆ 時間: 2010-6-8 11:52 Android系統在超級終端下必會的命令大全(三) 2、文件處理命令 mkdir 1.做用 mkdir命令的做用是創建名稱爲dirname的子目錄,與MS DOS下的md命令相似,它的使用權限是全部用戶。 2.格式 mkdir [options] 目錄名 3.[options]主要參數 -m, --mode=模式:設定權限,與chmod相似。 -p, --parents:須要時建立上層目錄;若是目錄早已存在,則不看成錯誤。 -v, --verbose:每次建立新目錄都顯示信息。 --version:顯示版本信息後離開。 4.應用實例 在進行目錄建立時能夠設置目錄的權限,此時使用的參數是「-m」。假設要建立的目錄名是「tsk」,讓全部用戶都有rwx(即讀、寫、執行的權限),那麼能夠使用如下命令: $ mkdir -m 777 tsk grep 1.做用 grep命令能夠指定文件中搜索特定的內容,並將含有這些內容的行標準輸出。grep全稱是Global Regular Expression Print,表示全局正則表達式版本,它的使用權限是全部用戶。 2.格式 grep [options] 3.主要參數 [options]主要參數: -c:只輸出匹配行的計數。 -I:不區分大小寫(只適用於單字符)。 -h:查詢多文件時不顯示文件名。 -l:查詢多文件時只輸出包含匹配字符的文件名。 -n:顯示匹配行及行號。 -s:不顯示不存在或無匹配文本的錯誤信息。 -v:顯示不包含匹配文本的全部行。 pattern正則表達式主要參數: \:忽略正則表達式中特殊字符的原有含義。 ^:匹配正則表達式的開始行。 $: 匹配正則表達式的結束行。 \:到匹配正則表達式的行結束。 [ ]:單個字符,如[A]即A符合要求 。 [ - ]:範圍,如[A-Z],即A、B、C一直到Z都符合要求 。 。:全部的單個字符。 * :有字符,長度能夠爲0。 正則表達式是Linux/Unix系統中很是重要的概念。正則表達式(也稱爲「regex」或「regexp」)是一個能夠描述一類字符串的模式(Pattern)。若是一個字符串能夠用某個正則表達式來描述,咱們就說這個字符和該正則表達式匹配(Match)。這和DOS中用戶能夠使用通配符 「*」表明任意字符相似。在Linux系統上,正則表達式一般被用來查找文本的模式,以及對文本執行「搜索-替換」操做和其它功能。 4.應用實例 查詢DNS服務是平常工做之一,這意味着要維護覆蓋不一樣網絡的大量IP地址。有時IP地址會超過2000個。若是要查看nnn.nnn網絡地址,可是卻忘了第二部分中的其他部分,只知到有兩個句點,例如nnn nn..。要抽取其中全部nnn.nnn IP地址,使用[0-9 ]\{3 \}\.[0-0\{3\}\。含義是任意數字出現3次,後跟句點,接着是任意數字出現3次,後跟句點。 $grep ’[0-9 ]\{3 \}\.[0-0\{3\}\’ ipfile 補充說明,grep家族還包括fgrep和egrep。fgrep是fix grep,容許查找字符串而不是一個模式;egrep是擴展grep,支持基本及擴展的正則表達式,但不支持\q模式範圍的應用及與之相對應的一些更加規範的模式。 dd 1.做用 dd命令用來複制文件,並根據參數將數據轉換和格式化。 2.格式 dd [options] 3.[opitions]主要參數 bs=字節:強迫 ibs=及obs=。 cbs=字節:每次轉換指定的。 conv=關鍵字:根據以逗號分隔的關鍵字表示的方式來轉換文件。 count=塊數目:只複製指定的輸入數據。 ibs=字節:每次讀取指定的。 if=文件:讀取內容,而非標準輸入的數據。 obs=字節:每次寫入指定的。 of=文件:將數據寫入,而不在標準輸出顯示。 seek=塊數目:先略過以obs爲單位的指定的輸出數據。 skip=塊數目:先略過以ibs爲單位的指定的輸入數據。 4.應用實例 dd命令經常用來製做Linux啓動盤。先找一個可引導內核,令它的根設備指向正確的根分區,而後使用dd命令將其寫入軟盤: $ rdev vmlinuz /dev/hda $dd if=vmlinuz of=/dev/fd0 上面代碼說明,使用rdev命令將可引導內核vmlinuz中的根設備指向/dev/hda,請把「hda」換成本身的根分區,接下來用dd命令將該內核寫入軟盤。 find 1.做用 find命令的做用是在目錄中搜索文件,它的使用權限是全部用戶。 2.格式 find [path][options][expression] path指定目錄路徑,系統從這裏開始沿着目錄樹向下查找文件。它是一個路徑列表,相互用空格分離,若是不寫path,那麼默認爲當前目錄。 3.主要參數 [options]參數: -depth:使用深度級別的查找過程方式,在某層指定目錄中優先查找文件內容。 -maxdepth levels:表示至多查找到開始目錄的第level層子目錄。level是一個非負數,若是level是0的話表示僅在當前目錄中查找。 -mindepth levels:表示至少查找到開始目錄的第level層子目錄。 -mount:不在其它文件系統(如Msdos、Vfat等)的目錄和文件中查找。 -version:打印版本。 [expression]是匹配表達式,是find命令接受的表達式,find命令的全部操做都是針對表達式的。它的參數很是多,這裏只介紹一些經常使用的參數。 —name:支持統配符*和?。 -atime n:搜索在過去n天讀取過的文件。 -ctime n:搜索在過去n天修改過的文件。 -group grpoupname:搜索全部組爲grpoupname的文件。 -user 用戶名:搜索全部文件屬主爲用戶名(ID或名稱)的文件。 -size n:搜索文件大小是n個block的文件。 -print:輸出搜索結果,而且打印。 4.應用技巧 find命令查找文件的幾種方法: (1)根據文件名查找 例如,咱們想要查找一個文件名是lilo.conf的文件,能夠使用以下命令: find / -name lilo.conf find命令後的「/」表示搜索整個硬盤。 (2)快速查找文件 根據文件名查找文件會遇到一個實際問題,就是要花費至關長的一段時間,特別是大型Linux文件系統和大容量硬盤文件放在很深的子目錄中時。若是咱們知道了這個文件存放在某個目錄中,那麼只要在這個目錄中往下尋找就能節省不少時間。好比smb.conf文件,從它的文件後綴「.conf」能夠判斷這是一個配置文件,那麼它應該在/etc目錄內,此時能夠使用下面命令: find /etc -name smb.conf 這樣,使用「快速查找文件」方式能夠縮短期。 (3)根據部分文件名查找方法 有時咱們知道只某個文件包含有abvd這4個字,那麼要查找系統中全部包含有這4個字符的文件能夠輸入下面命令: find / -name ’*abvd*’ 輸入這個命令之後,Linux系統會將在/目錄中查找全部的包含有abvd這4個字符的文件(其中*是通配符),好比abvdrmyz等符合條件的文件都能顯示出來。 (4) 使用混合查找方式查找文件 find命令能夠使用混合查找的方法,例如,咱們想在/etc目錄中查找大於500000字節,而且在24小時內修改的某個文件,則能夠使用-and (與)把兩個查找參數連接起來組合成一個混合的查找方式。 find /etc -size +500000c -and -mtime +1 mv 1.做用 mv命令用來爲文件或目錄更名,或者將文件由一個目錄移入另外一個目錄中,它的使用權限是全部用戶。該命令如同DOS命令中的ren和move的組合。 2.格式 mv[options] 源文件或目錄 目標文件或目錄 3.[options]主要參數 -i:交互方式操做。若是mv操做將致使對已存在的目標文件的覆蓋,此時系統詢問是否重寫,要求用戶回答「y」或「n」,這樣能夠避免誤覆蓋文件。 -f:禁止交互操做。mv操做要覆蓋某個已有的目標文件時不給任何指示,指定此參數後i參數將再也不起做用。 4.應用實例 (1)將/usr/cbu中的全部文件移到當前目錄(用「.」表示)中: $ mv /usr/cbu/ * . (2)將文件cjh.txt重命名爲wjz.txt: $ mv cjh.txt wjz.txt ls 1.做用 ls命令用於顯示目錄內容,相似DOS下的dir命令,它的使用權限是全部用戶。 2.格式 ls [options][filename] 3.options主要參數 -a, --all:不隱藏任何以「.」 字符開始的項目。 -A, --almost-all:列出除了「 . 」及 「.. 」之外的任何項目。 --author:印出每一個文件著做者。 -b, --escape:以八進制溢出序列表示不可打印的字符。 --block-size=大小:塊以指定的字節爲單位。 -B, --ignore-backups:不列出任何以 ~ 字符結束的項目。 -f:不進行排序,-aU參數生效,-lst參數失效。 -F, --classify:加上文件類型的指示符號 (*/=@| 其中一個)。 -g:like -l, but do not list owner。 -G, --no-group:inhibit display of group information。 -i, --inode:列出每一個文件的inode號。 -I, --ignore=樣式:不印出任何符合Shell萬用字符的項目。 -k:即--block-size=1K。 -l:使用較長格式列出信息。 -L, --dereference:當顯示符號連接的文件信息時,顯示符號連接所指示的對象,而並不是符號連接自己的信息。 -m:全部項目以逗號分隔,並填滿整行行寬。 -n, --numeric-uid-gid:相似-l,但列出UID及GID號。 -N, --literal:列出未經處理的項目名稱,例如不特別處理控制字符。 -p, --file-type:加上文件類型的指示符號 (/=@| 其中一個)。 -Q, --quote-name:將項目名稱括上雙引號。 -r, --reverse:依相反次序排列。 -R, --recursive:同時列出全部子目錄層。 -s, --size:以塊大小爲序。 4.應用舉例 ls 命令是Linux系統使用頻率最多的命令,它的參數也是Linux命令中最多的。使用ls命令時會有幾種不一樣的顏色,其中藍色表示是目錄,綠色表示是可執 行文件,紅色表示是壓縮文件,淺藍色表示是連接文件,加粗的黑色表示符號連接,灰色表示是其它格式文件。ls最常使用的是ls- l。 文 件類型開頭是由10個字符構成的字符串。其中第一個字符表示文件類型,它能夠是下述類型之一:-(普通文件)、d(目錄)、l(符號連接)、b(塊設備文件)、c(字符設備文件)。後面的9個字符表示文件的訪問權限,分爲3組,每組3位。第一組表示文件屬主的權限,第二組表示同組用戶的權限,第三組表示其餘用戶的權限。每一組的三個字符分別表示對文件的讀(r)、寫(w)和執行權限(x)。對於目錄,表示進入權限。s表示當文件被執行時,把該文件的UID 或GID賦予執行進程的UID(用戶ID)或GID(組ID)。t表示設置標誌位(留在內存,不被換出)。若是該文件是目錄,那麼在該目錄中的文件只能被超級用戶、目錄擁有者或文件屬主刪除。若是它是可執行文件,那麼在該文件執行後,指向其正文段的指針仍留在內存。這樣再次執行它時,系統就能更快地裝入該文件。接着顯示的是文件大小、生成時間、文件或命令名稱。 Android系統在超級終端下必會的命令大全(四) diff 1.做用 diff命令用於兩個文件之間的比較,並指出二者的不一樣,它的使用權限是全部用戶。 2.格式 diff [options] 源文件 目標文件 3.[options]主要參數 -a:將全部文件看成文本文件來處理。 -b:忽略空格形成的不一樣。 -B:忽略空行形成的不一樣。 -c:使用綱要輸出格式。 -H:利用試探法加速對大文件的搜索。 -I:忽略大小寫的變化。 -n --rcs:輸出RCS格式。 cmp 1.做用 cmp(「compare」的縮寫)命令用來簡要指出兩個文件是否存在差別,它的使用權限是全部用戶。 2.格式 cmp[options] 文件名 3.[options]主要參數 -l: 將字節以十進制的方式輸出,並方便將兩個文件中不一樣的以八進制的方式輸出。 cat 1.做用 cat(「concatenate」的縮寫)命令用於鏈接並顯示指定的一個和多個文件的有關信息,它的使用權限是全部用戶。 2.格式 cat [options] 文件1 文件2…… 3.[options]主要參數 -n:由第一行開始對全部輸出的行數編號。 -b:和-n類似,只不過對於空白行不編號。 -s:當遇到有連續兩行以上的空白行時,就代換爲一行的空白行。 4.應用舉例 (1)cat命令一個最簡單的用處是顯示文本文件的內容。例如,咱們想在命令行看一下README文件的內容,能夠使用命令: $ cat README (2)有時須要將幾個文件處理成一個文件,並將這種處理的結果保存到一個單獨的輸出文件。cat命令在其輸入上接受一個或多個文件,並將它們做爲一個單獨的文件打印到它的輸出。例如,把README和INSTALL的文件內容加上行號(空白行不加)以後,將內容附加到一個新文本文件File1 中: $ cat README INSTALL File1 (3)cat 還有一個重要的功能就是能夠對行進行編號。這種功能對於程序文檔的編制,以及法律和科學文檔的編制很方便,打印在左邊的行號使得參考文檔的某一部分變得容易,這些在編程、科學研究、業務報告甚至是立法工做中都是很是重要的。對行進行編號功能有-b(只能對非空白行進行編號)和-n(能夠對全部行進行編號)兩個參數: $ cat -b /etc/named.conf ln 1.做用 ln命令用來在文件之間建立連接,它的使用權限是全部用戶。 2.格式 ln [options] 源文件 [連接名] 3.參數 -f:鏈結時先將源文件刪除。 -d:容許系統管理者硬鏈結本身的目錄。 -s:進行軟鏈結(Symbolic Link)。 -b:將在鏈結時會被覆蓋或刪除的文件進行備份。 連接有兩種,一種被稱爲硬連接(Hard Link),另外一種被稱爲符號連接(Symbolic Link)。默認狀況下,ln命令產生硬連接。硬鏈接指經過索引節點來進行的鏈接。在Linux的文件系統中,保存在磁盤分區中的文件無論是什麼類型都給它分配一個編號,稱爲索引節點號(InodeIndex)。在Linux中,多個文件名指向同一索引節點是存在的。通常這種鏈接就是硬鏈接。硬鏈接的做用是容許一個文件擁有多個有效路徑名,這樣用戶就能夠創建硬鏈接到重要文件,以防止「誤刪」的功能。其緣由如上所述,由於對應該目錄的索引節點有一個以上的鏈接。只刪除一個鏈接並不影響索引節點自己和其它的鏈接,只有當最後一個鏈接被刪除後,文件的數據塊及目錄的鏈接纔會被釋放。也就是說,文件纔會被真正刪除。與硬鏈接相對應,Lnux系統中還存在另外一種鏈接,稱爲符號鏈接(Symbilc Link),也叫軟鏈接。軟連接文件有點相似於Windows的快捷方式。它其實是特殊文件的一種。在符號鏈接中,文件其實是一個文本文件,其中包含的有另外一文件的位置信息。 -------------------------------------------------------------------------------- 做者: ☆-☆ 時間: 2010-6-8 11:55 本帖最後由 ☆-☆ 於 2010-6-8 11:59 編輯 Android系統在超級終端下必會的命令大全(五) 系統管理命令 df 1.做用 df命令用來檢查文件系統的磁盤空間佔用狀況,使用權限是全部用戶。 2.格式 df [options] 3.主要參數 -s:對每一個Names參數只給出佔用的數據塊總數。 -a:遞歸地顯示指定目錄中各文件及子目錄中各文件佔用的數據塊數。若既不指定-s,也不指定-a,則只顯示Names中的每個目錄及其中的各子目錄所佔的磁盤塊數。 -k:以1024字節爲單位列出磁盤空間使用狀況。 -x:跳過在不一樣文件系統上的目錄不予統計。 -l:計算全部的文件大小,對硬連接文件則計算屢次。 -i:顯示inode信息而非塊使用量。 -h:以容易理解的格式印出文件系統大小,例如136KB、254MB、21GB。 -P:使用POSIX輸出格式。 -T:顯示文件系統類型。 4.說明 df 命令被普遍地用來生成文件系統的使用統計數據,它能顯示系統中全部的文件系統的信息,包括總容量、可用的空閒空間、目前的安裝點等。超級權限用戶使用df 命令時會發現這樣的狀況:某個分區的容量超過了100%。這是由於Linux系統爲超級用戶保留了10%的空間,由其單獨支配。也就是說,對於超級用戶而言,他所見到的硬盤容量將是110%。這樣的安排對於系統管理而言是有好處的,當硬盤被使用的容量接近100%時系統管理員還能夠正常工做。 5.應用實例 Linux支持的文件系統很是多,包括JFS、ReiserFS、ext、ext二、ext三、ISO9660、XFS、Minx、vfat、MSDOS等。使用df -T命令查看磁盤空間時還能夠獲得文件系統的信息: #df -T 文件系統 類型 容量 已用 可用 已用% 掛載點 /dev/hda7 reiserfs 5.2G 1.6G 3.7G 30% / /dev/hda1 vfat 2.4G 1.6G 827M 66% /windows/C /dev/hda5 vfat 3.0G 1.7G 1.3G 57% /windows/D /dev/hda9 vfat 3.0G 2.4G 566M 82% /windows/E /dev/hda10 NTFS 3.2G 573M 2.6G 18% /windows/F /dev/hda11 vfat 1.6G 1.5G 23M 99% /windows/G 從上面除了能夠看到磁盤空間的容量、使用狀況外,分區的文件系統類型、掛載點等信息也一覽無遺。 top 1.做用 top命令用來顯示執行中的程序進程,使用權限是全部用戶。 2.格式 top [-] [d delay] [q] [c] [S] [n] 3.主要參數 d:指定更新的間隔,以秒計算。 q:沒有任何延遲的更新。若是使用者有超級用戶,則top命令將會以最高的優先序執行。 c:顯示進程完整的路徑與名稱。 S:累積模式,會將己完成或消失的子行程的CPU時間累積起來。 s:安全模式。 i:不顯示任何閒置(Idle)或無用(Zombie)的行程。 n:顯示更新的次數,完成後將會退出top。 4.說明 top命令是Linux系統管理的一個主要命令,經過它能夠得到許多信息。 下面列出了詳細解釋。 PID(Process ID):進程標示號。 USER:進程全部者的用戶名。 PR:進程的優先級別。 NI:進程的優先級別數值。 VIRT:進程佔用的虛擬內存值。 RES:進程佔用的物理內存值。 SHR:進程使用的共享內存值。 S:進程的狀態,其中S表示休眠,R表示正在運行,Z表示僵死狀態,N表示該進程優先值是負數。 %CPU:該進程佔用的CPU使用率。 %MEM:該進程佔用的物理內存和總內存的百分比。 TIME+:該進程啓動後佔用的總的CPU時間。 Command:進程啓動的啓動命令名稱,若是這一行顯示不下,進程會有一個完整的命令行。 top命令使用過程當中,還能夠使用一些交互的命令來完成其它參數的功能。這些命令是經過快捷鍵啓動的。 :馬上刷新。 P:根據CPU使用大小進行排序。 T:根據時間、累計時間排序。 q:退出top命令。 m:切換顯示內存信息。 t:切換顯示進程和CPU狀態信息。 c:切換顯示命令名稱和完整命令行。 M:根據使用內存大小進行排序。 W:將當前設置寫入~/.toprc文件中。這是寫top配置文件的推薦方法。 能夠看到,top命令是一個功能十分強大的監控系統的工具,對於系統管理員而言尤爲重要。可是,它的缺點是會消耗不少系統資源。 free 1.做用 free命令用來顯示內存的使用狀況,使用權限是全部用戶。 2.格式 free [-b|-k|-m] [-o] [-s delay] [-t] [-V] 3.主要參數 -b -k -m:分別以字節(KB、MB)爲單位顯示內存使用狀況。 -s delay:顯示每隔多少秒數來顯示一次內存使用狀況。 -t:顯示內存總和列。 -o:不顯示緩衝區調節列。 4.應用實例 free命令是用來查看內存使用狀況的主要命令。和top命令相比,它的優勢是使用簡單,而且只佔用不多的系統資源。經過-S參數能夠使用free命令不間斷地監視有多少內存在使用,這樣能夠把它看成一個方便實時監控器。 #free -b -s5 使用這個命令後終端會接二連三地報告內存使用狀況(以字節爲單位),每5秒更新一次。 chown 1.做用 更改一個或多個文件或目錄的屬主和屬組。使用權限是超級用戶。 2.格式 chown [選項] 用戶或組 文件 3.主要參數 --dereference:受影響的是符號連接所指示的對象,而非符號連接自己。 -h, --no-dereference:會影響符號連接自己,而非符號連接所指示的目的地(當系統支持更改符號連接的全部者,此選項纔有效)。 --from=目前全部者:目前組只當每一個文件的全部者和組符合選項所指定的,纔會更改全部者和組。其中一個能夠省略,這已省略的屬性就不須要符合原有的屬性。 -f, --silent, --quiet:去除大部分的錯誤信息。 -R, --recursive:遞歸處理全部的文件及子目錄。 -v, --verbose:處理任何文件都會顯示信息。 4.說明 chown 將指定文件的擁有者改成指定的用戶或組,用戶能夠是用戶名或用戶ID;組能夠是組名或組ID;文件是以空格分開的要改變權限的文件列表,支持通配符。系統管理員常用chown命令,在將文件拷貝到另外一個用戶的目錄下之後,讓用戶擁有使用該文件的權限。 5.應用實例 1.把文件shiyan.c的全部者改成wan $ chown wan shiyan.c 2.把目錄/hi及其下的全部文件和子目錄的屬主改爲wan,屬組改爲users。 $ chown - R wan.users /hi chattr 1.做用 修改ext2和ext3文件系統屬性(attribute),使用權限超級用戶。 2.格式 chattr [-RV] [-+=AacDdijsSu] [-v version] 文件或目錄 3.主要參數 -R:遞歸處理全部的文件及子目錄。 -V:詳細顯示修改內容,並打印輸出。 -:失效屬性。 +:激活屬性。 = :指定屬性。 A:Atime,告訴系統不要修改對這個文件的最後訪問時間。 S:Sync,一旦應用程序對這個文件執行了寫操做,使系統馬上把修改的結果寫到磁盤。 a:Append Only,系統只容許在這個文件以後追加數據,不容許任何進程覆蓋或截斷這個文件。若是目錄具備這個屬性,系統將只容許在這個目錄下創建和修改文件,而不容許刪除任何文件。 i:Immutable,系統不容許對這個文件進行任何的修改。若是目錄具備這個屬性,那麼任何的進程只能修改目錄之下的文件,不容許創建和刪除文件。 D:檢查壓縮文件中的錯誤。 d:No dump,在進行文件系統備份時,dump程序將忽略這個文件。 C:Compress,系統以透明的方式壓縮這個文件。從這個文件讀取時,返回的是解壓以後的數據;而向這個文件中寫入數據時,數據首先被壓縮以後才寫入磁盤。 s:Secure Delete,讓系統在刪除這個文件時,使用0填充文件所在的區域。 u:Undelete,當一個應用程序請求刪除這個文件,系統會保留其數據塊以便之後可以恢復刪除這個文件。 4.說明 chattr 命令的做用很大,其中一些功能是由Linux內核版原本支持的,若是Linux內核版本低於2.2,那麼許多功能不能實現。一樣-D檢查壓縮文件中的錯誤 的功能,須要2.5.19以上內核才能支持。另外,經過chattr命令修改屬性可以提升系統的安全性,可是它並不適合全部的目錄。chattr命令不能 保護/、/dev、/tmp、/var目錄。 5.應用實例 1.恢復/root目錄,即子目錄的全部文件 # chattr -R +u/root 2.用chattr命令防止系統中某個關鍵文件被修改 在Linux下,有些配置文件(passwd ,fatab)是不容許任何人修改的,爲了防止被誤刪除或修改,能夠設定該文件的「不可修改位(immutable)」,命令以下: # chattr +i /etc/fstab ps 1.做用 ps顯示瞬間進程 (process) 的動態,使用權限是全部使用者。 2.格式 ps [options] [--help] 3.主要參數 ps的參數很是多, 此出僅列出幾個經常使用的參數。 -A:列出全部的進程。 -l:顯示長列表。 -m:顯示內存信息。 -w:顯示加寬能夠顯示較多的信息。 -e:顯示全部進程。 a:顯示終端上的全部進程,包括其它用戶的進程。 -au:顯示較詳細的信息。 -aux:顯示全部包含其它使用者的進程。 4.說明 要 對進程進行監測和控制,首先要了解當前進程的狀況,也就是須要查看當前進程。ps命令就是最基本、也是很是強大的進程查看命令。使用該命令能夠肯定有哪些 進程正在運行、運行的狀態、進程是否結束、進程有沒有殭屍、哪些進程佔用了過多的資源等。圖2給出了ps-aux命令詳解。大部分信息均可以經過執行該命 令獲得。最經常使用的三個參數是u、a、x。下面就結合這三個參數詳細說明ps命令的做用:ps aux 圖2 ps-aux命令詳解 圖2第2行代碼中,USER表示進程擁有者;PID表示進程標示符;%CPU表示佔用的CPU使用率;%MEM佔用的物理內存使用率;VSZ表示佔用的虛擬內存大小;RSS爲進程佔用的物理內存值;TTY爲終端的次要裝置號碼。 STAT 表示進程的狀態,其中D爲不可中斷的靜止(I/O動做);R正在執行中;S靜止狀態;T暫停執行;Z不存在,但暫時沒法消除;W沒有足夠的內存分頁可分 配;高優先序的進程;N低優先序的進程;L有內存分頁分配並鎖在內存體內 (實時系統或 I/O)。START爲進程開始時間。TIME爲執行的時間。COMMAND是所執行的指令。 4.應用實例 在進行系統維護時,常常會出現內存使用量驚人,而又不知道是哪個進程佔用了大量進程的狀況。除了能夠使用top命令查看內存使用狀況以外,還能夠使用下面的命令: ps aux | sort +5n -------------------------------------------------------------------------------- 做者: ☆-☆ 時間: 2010-6-8 11:58 Android系統在超級終端下必會的命令大全(十) 6、其餘命令 tar 1.做用 tar命令是Unix/Linux系統中備份文件的可靠方法,幾乎能夠工做於任何環境中,它的使用權限是全部用戶。 2.格式 tar [主選項+輔選項] 文件或目錄 3.主要參數 使用該命令時,主選項是必需要有的,它告訴tar要作什麼事情,輔選項是輔助使用的,能夠選用。 主選項: -c 建立新的檔案文件。若是用戶想備份一個目錄或是一些文件,就要選擇這個選項。 -r 把要存檔的文件追加到檔案文件的未尾。例如用戶已經作好備份文件,又發現還有一個目錄或是一些文件忘記備份了,這時能夠使用該選項,將忘記的目錄或文件追加到備份文件中。 -t 列出檔案文件的內容,查看已經備份了哪些文件。 -u 更新文件。就是說,用新增的文件取代原備份文件,若是在備份文件中找不到要更新的文件,則把它追加到備份文件的最後。 -x 從檔案文件中釋放文件。 輔助選項: -b 該選項是爲磁帶機設定的,其後跟一數字,用來講明區塊的大小,系統預設值爲20(20×512 bytes)。 -f 使用檔案文件或設備,這個選項一般是必選的。 -k 保存已經存在的文件。例如把某個文件還原,在還原的過程當中遇到相同的文件,不會進行覆蓋。 -m 在還原文件時,把全部文件的修改時間設定爲如今。 -M 建立多卷的檔案文件,以便在幾個磁盤中存放。 -v 詳細報告tar處理的文件信息。如無此選項,tar不報告文件信息。 -w 每一步都要求確認。 -z 用gzip來壓縮/解壓縮文件,加上該選項後能夠將檔案文件進行壓縮,但還原時也必定要使用該選項進行解壓縮。 4.應用說明 tar 是Tape Archive(磁帶歸檔)的縮寫,最初設計用於將文件打包到磁帶上。若是下載過Linux的源代碼,或許已經碰到過tar文件 請注意,不要忘了Linux是區分大小寫的。例如,tar命令應該老是以小寫的形式執行。命令行開關能夠是大寫、小寫或大小寫的混合。例如,-t和-T執行不一樣的功能。文件或目錄名稱能夠混合使用大小寫,並且就像命令和命令行開關同樣是區分大小寫的。 5.應用實例 tar是一個命令行的工具,沒有圖形界面。使用Konsole打開一個終端窗口,接下來是一個簡單的備份命令(在/temp目錄中建立一個back.tar的文件,/usr目錄中全部內容都包含在其中。): $tar cvf - /usr > /temp/back.tar 另 外,tar命令支持前面第三講中講過的crontab命令,能夠用crontab工具設置成基於時間的有規律地運行。例如,每晚6點把/usr目錄備份到 hda—第一個IDE接口的主驅動器 (老是位於第一個硬盤)中,只要將下面語句添加到root的crontab中便可: $00 06 * * * tar cvf /dev/hda1/usrfiles.tar - /usr 通常狀況下,如下這些目錄是須要備份的: ◆/etc 包含全部核心配置文件,其中包括網絡配置、系統名稱、防火牆規則、用戶、組,以及其它全局系統項。 ◆ /var 包含系統守護進程(服務)所使用的信息,包括DNS配置、DHCP租期、郵件緩衝文件、HTTP服務器文件、dB2實例配置等。 ◆/home 包含全部默認用戶的主目錄,包括我的設置、已下載的文件和用戶不但願失去的其它信息。 ◆/root 根(root)用戶的主目錄。 ◆/opt 是安裝許多非系統文件的地方。IBM軟件就安裝在這裏。OpenOffice、JDK和其它軟件在默認狀況下也安裝在這裏。 有些目錄是能夠不備份的: ◆ /proc 應該永遠不要備份這個目錄。它不是一個真實的文件系統,而是運行內核和環境的虛擬化視圖,包括諸如/proc/kcore這樣的文件,這個文件是整個運行內存的虛擬視圖。備份這些文件只是在浪費資源。 ◆/dev 包含硬件設備的文件表示。若是計劃還原到一個空白的系統,就能夠備份/dev。然而,若是計劃還原到一個已安裝的Linux 系統,那麼備份/dev是沒有必要的。 unzip 1.做用 unzip 命令位於/usr/bin目錄中,它們和MS DOS下的pkzip、pkunzip及MS Windows中的Winzip軟件功能同樣,將文件壓縮成.zip文件,以節省硬盤空間,當須要的時候再將壓縮文件用unzip命令解開。該命令使用權 限是全部用戶。 2.格式 unzip [-cflptuvz][-agCjLMnoqsVX][-P ][.zip文件][文件][-d ][-x ] 3.主要參數 -c:將解壓縮的結果顯示到屏幕上,並對字符作適當的轉換。 -f:更新現有的文件。 -l:顯示壓縮文件內所包含的文件。 -p:與-c參數相似,會將解壓縮的結果顯示到屏幕上,但不會執行任何的轉換。 -t:檢查壓縮文件是否正確。 -u:與-f參數相似,可是除了更新現有的文件外,也會將壓縮文件中的其它文件解壓縮到目錄中。 -v:執行是時顯示詳細的信息。 -z:僅顯示壓縮文件的備註文字。 -a:對文本文件進行必要的字符轉換。 -b:不要對文本文件進行字符轉換。 -C:壓縮文件中的文件名稱區分大小寫。 -j:不處理壓縮文件中原有的目錄路徑。 -L:將壓縮文件中的所有文件名改成小寫。 -M:將輸出結果送到more程序處理。 -n:解壓縮時不要覆蓋原有的文件。 -o:沒必要先詢問用戶,unzip執行後覆蓋原有文件。 -P:使用zip的密碼選項。 -q:執行時不顯示任何信息。 -s:將文件名中的空白字符轉換爲底線字符。 -V:保留VMS的文件版本信息。 -X:解壓縮時同時回存文件原來的UID/GID。 [.zip文件]:指定.zip壓縮文件。 [文件]:指定要處理.zip壓縮文件中的哪些文件。 -d:指定文件解壓縮後所要存儲的目錄。 -x:指定不要處理.zip壓縮文件中的哪些文件。 -Z unzip:-Z等於執行zipinfo指令。在Linux中,還提供了一個叫zipinfo的工具,可以察看zip壓縮文件的詳細信息。 gunzip 1.做用 gunzip命令做用是解壓文件,使用權限是全部用戶。 2.格式 gunzip [-acfhlLnNqrtvV][-s ][文件...] 或者 gunzip [-acfhlLnNqrtvV][-s ][目錄] 3.主要參數 -a或--ascii:使用ASCII文字模式。 -c或--stdout或--to-stdout:把解壓後的文件輸出到標準輸出設備。 -f或-force:強行解開壓縮文件,不理會文件名稱或硬鏈接是否存在,以及該文件是否爲符號鏈接。 -h或--help:在線幫助。 -l或--list:列出壓縮文件的相關信息。 -L或--license:顯示版本與版權信息。 -n或--no-name:解壓縮時,若壓縮文件內含有原來的文件名稱及時間戳記,則將其忽略不予處理。 -N或--name:解壓縮時,若壓縮文件內含有原來的文件名稱及時間戳記,則將其回存到解開的文件上。 -q或--quiet:不顯示警告信息。 -r或--recursive:遞歸處理,將指定目錄下的全部文件及子目錄一併處理。 -S或--suffix:更改壓縮字尾字符串。 -t或--test:測試壓縮文件是否正確無誤。 -v或--verbose:顯示指令執行過程。 -V或--version:顯示版本信息。 4.說明 gunzip是個使用普遍的解壓縮程序,它用於解開被gzip壓縮過的文件,這些壓縮文件預設最後的擴展名爲「.gz」。事實上,gunzip就是gzip的硬鏈接,所以不管是壓縮或解壓縮,均可經過gzip指令單獨完成。gunzip最新版本是1.3.3 。 12:39 評論 / 瀏覽 (0 / 23) 分類:移動開發 2011-12-01 縮略顯示 java runtime.exec()相關 java 那就首先說點Runtime類吧,他是一個與JVM運行時環境有關的類,這個類是Singleton的。我說幾個本身以爲重要的地方。 1、Runtime.getRuntime()能夠取得當前JVM的運行時環境,這也是在Java中惟一一個獲得運行時環境的方法。 2、Runtime上其餘大部分的方法都是實例方法,也就是說每次進行運行時調用時都要用到getRuntime方法。 3、 Runtime中的exit方法是退出當前JVM的方法,估計也是惟一的一個吧,由於我看到System類中的exit實際上也是經過調用 Runtime.exit()來退出JVM的,這裏說明一下Java對Runtime返回值的通常規則(後邊也提到了),0表明正常退出,非0表明異常停止,這只是Java的規則,在各個操做系統中總會發生一些小的混淆。 4、Runtime.addShutdownHook()方法能夠註冊一個hook在JVM執行shutdown的過程當中,方法的參數只要是一個初始化過可是沒有執行的Thread實例就能夠。(注意,Java中的Thread都是執行過了就不值錢的哦) 5、說到addShutdownHook這個方法就要說一下JVM運行環境是在什麼狀況下shutdown或者abort的。文檔上是這樣寫的,當最後一個非精靈進程退出或者收到了一個用戶中斷信號、用戶登出、系統shutdown、Runtime的exit方法被調用時JVM會啓動shutdown的過程,在這個過程開始後,他會並行啓動全部登記的shutdown hook(注意是並行啓動,這就須要線程安全和防止死鎖)。當shutdown過程啓動後,只有經過調用halt方法才能停止shutdown的過程並退出JVM。 那何時JVM會abort退出那?首先說明一下,abort退出時JVM就是中止運行但並不必定進行shutdown。這隻有JVM在遇到SIGKILL信號或者windows停止進程的信號、本地方法發生相似於訪問非法地址一類的內部錯誤時會出現。這種狀況下並不能保證shutdown hook是否被執行。 如今開始看這篇文章,呵呵。 首先講的是Runtime.exec()方法的全部重載。這裏要注意的有一點,就是public Process exec(String [] cmdArray, String [] envp);這個方法中cmdArray是一個執行的命令和參數的字符串數組,數組的第一個元素是要執行的命令日後依次都是命令的參數,envp我我的感受應該和C中的execve中的環境變量是同樣的,envp中使用的是name=value的方式。 <!--[if !supportLists]-->1、 <!--[endif]-->一個很糟糕的調用程序,代碼以下,這個程序用exec調用了一個外部命令以後立刻使用exitValue就對其返回值進行檢查,讓咱們看看會出現什麼問題。 import java.util.*; import java.io.*; public class BadExecJavac { public static void main(String args[]) { try { Runtime rt = Runtime.getRuntime(); Process proc = rt.exec("javac"); int exitVal = proc.exitValue(); System.out.println("Process exitValue: " + exitVal); } catch (Throwable t) { t.printStackTrace(); } } } A run of BadExecJavac produces: E:classescomjavaworldjpitfallsarticle2>java BadExecJavac java.lang.IllegalThreadStateException: process has not exited at java.lang.Win32Process.exitValue(Native Method) at BadExecJavac.main(BadExecJavac.java:13) 這裏看原文就能夠了解,這裏主要的問題就是錯誤的調用了exitValue來取得外部命令的返回值(呵呵,這個錯誤我也曾經犯過),由於exitValue 這個方法是不阻塞的,程序在調用這個方法時外部命令並無返回因此形成了異常的出現,這裏是由另外的方法來等待外部命令執行完畢的,就是waitFor方法,這個方法會一直阻塞直到外部命令執行結束,而後返回外部命令執行的結果,做者在這裏一頓批評設計者的思路有問題,呵呵,反正我是無所謂阿,能用就能夠拉。可是做者在這裏有一個說明,就是exitValue也是有好多用途的。由於當你在一個Process上調用waitFor方法時,當前線程是阻塞的,若是外部命令沒法執行結束,那麼你的線程就會一直阻塞下去,這種意外會影響咱們程序的執行。因此在咱們不能判斷外部命令何時執行完畢而咱們的程序還須要繼續執行的狀況下,咱們就應該循環的使用exitValue來取得外部命令的返回狀態,並在外部命令返回時做出相應的處理。 2、對exitValue處改進了的程序 import java.util.*; import java.io.*; public class BadExecJavac2 { public static void main(String args[]) { try { Runtime rt = Runtime.getRuntime(); Process proc = rt.exec("javac"); int exitVal = proc.waitFor(); System.out.println("Process exitValue: " + exitVal); } catch (Throwable t) { t.printStackTrace(); } } } 不幸的是,這個程序也沒法執行完成,它沒有輸出但卻一直懸在那裏,這是爲何那? JDK文檔中對此有如此的解釋:由於本地的系統對標準輸入和輸出所提供的緩衝池有效,因此錯誤的對標準輸出快速的寫入和從標準輸入快速的讀入都有可能形成子進程的鎖,甚至死鎖。 文檔引述完了,做者又開始批評了,他說JDK僅僅說明爲何問題會發生,卻並無說明這個問題怎麼解決,這的確是個問題哈。緊接着做者說出本身的作法,就是在執行完外部命令後咱們要控制好Process的全部輸入和輸出(視狀況而定),在這個例子裏邊由於調用的是Javac,而他在沒有參數的狀況下會將提示信息輸出到標準出錯,因此在下面的程序中咱們要對此進行處理。 import java.util.*; import java.io.*; public class MediocreExecJavac { public static void main(String args[]) { try { Runtime rt = Runtime.getRuntime(); Process proc = rt.exec("javac"); InputStream stderr = proc.getErrorStream(); InputStreamReader isr = new InputStreamReader(stderr); BufferedReader br = new BufferedReader(isr); String line = null; System.out.println("<ERROR>"); while ( (line = br.readLine()) != null) System.out.println(line); System.out.println("</ERROR>"); int exitVal = proc.waitFor(); System.out.println("Process exitValue: " + exitVal); } catch (Throwable t) { t.printStackTrace(); } } } 程序的運行結果爲 E:classescomjavaworldjpitfallsarticle2>java MediocreExecJavac <ERROR> Usage: javac <options> <source files> where <options> includes: -g Generate all debugging info -g:none Generate no debugging info -g:{lines,vars,source} Generate only some debugging info -O Optimize; may hinder debugging or enlarge class files -nowarn Generate no warnings -verbose Output messages about what the compiler is doing -deprecation Output source locations where deprecated APIs are used -classpath <path> Specify where to find user class files -sourcepath <path> Specify where to find input source files -bootclasspath <path> Override location of bootstrap class files -extdirs <dirs> Override location of installed extensions -d <directory> Specify where to place generated class files -encoding <encoding> Specify character encoding used by source files -target <release> Generate class files for specific VM version </ERROR> Process exitValue: 2 哎,無論怎麼說仍是出來告終果,做者做了一下總結,就是說,爲了處理好外部命令大量輸出的狀況,你要確保你的程序處理好外部命令所須要的輸入或者輸出。 下一個題目,當咱們調用一個咱們認爲是可執行程序的時候容易發生的錯誤(今天晚上我剛剛犯這個錯誤,沒事作這個練習時候發生的) import java.util.*; import java.io.*; public class BadExecWinDir { public static void main(String args[]) { try { Runtime rt = Runtime.getRuntime(); Process proc = rt.exec("dir"); InputStream stdin = proc.getInputStream(); InputStreamReader isr = new InputStreamReader(stdin); BufferedReader br = new BufferedReader(isr); String line = null; System.out.println("<OUTPUT>"); while ( (line = br.readLine()) != null) System.out.println(line); System.out.println("</OUTPUT>"); int exitVal = proc.waitFor(); System.out.println("Process exitValue: " + exitVal); } catch (Throwable t) { t.printStackTrace(); } } } A run of BadExecWinDir produces: E:classescomjavaworldjpitfallsarticle2>java BadExecWinDir java.io.IOException: CreateProcess: dir error=2 at java.lang.Win32Process.create(Native Method) at java.lang.Win32Process.<init>(Unknown Source) at java.lang.Runtime.execInternal(Native Method) at java.lang.Runtime.exec(Unknown Source) at java.lang.Runtime.exec(Unknown Source) at java.lang.Runtime.exec(Unknown Source) at java.lang.Runtime.exec(Unknown Source) at BadExecWinDir.main(BadExecWinDir.java:12) 說實在的,這個錯誤還真是讓我摸不着頭腦,我以爲在windows中返回2應該是沒有找到這個文件的緣故,可能windows 2000中只有cmd命令,dir命令不是當前環境變量可以解釋的吧。我也不知道了,慢慢往下看吧。 嘿,果真和做者想的同樣,就是由於dir命令是由windows中的解釋器解釋的,直接執行dir時沒法找到dir.exe這個命令,因此會出現文件未找到這個2的錯誤。若是咱們要執行這樣的命令,就要先根據操做系統的不一樣執行不一樣的解釋程序command.com 或者cmd.exe。 做者對上邊的程序進行了修改 import java.util.*; import java.io.*; class StreamGobbler extends Thread { InputStream is; String type; StreamGobbler(InputStream is, String type) { this.is = is; this.type = type; } public void run() { try { InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String line=null; while ( (line = br.readLine()) != null) System.out.println(type + ">" + line); } catch (IOException ioe) { ioe.printStackTrace(); } } } public class GoodWindowsExec { public static void main(String args[]) { if (args.length < 1) { System.out.println("USAGE: java GoodWindowsExec <cmd>"); System.exit(1); } try { String osName = System.getProperty("os.name" ); String[] cmd = new String[3]; if( osName.equals( "Windows NT" ) ) { cmd[0] = "cmd.exe" ; cmd[1] = "/C" ; cmd[2] = args[0]; } else if( osName.equals( "Windows 95" ) ) { cmd[0] = "command.com" ; cmd[1] = "/C" ; cmd[2] = args[0]; } Runtime rt = Runtime.getRuntime(); System.out.println("Execing " + cmd[0] + " " + cmd[1] + " " + cmd[2]); Process proc = rt.exec(cmd); // any error message? StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), "ERROR"); // any output? StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), "OUTPUT"); // kick them off errorGobbler.start(); outputGobbler.start(); // any error??? int exitVal = proc.waitFor(); System.out.println("ExitValue: " + exitVal); } catch (Throwable t) { t.printStackTrace(); } } } Running GoodWindowsExec with the dir command generates: E:classescomjavaworldjpitfallsarticle2>java GoodWindowsExec "dir *.java" Execing cmd.exe /C dir *.java OUTPUT> Volume in drive E has no label. OUTPUT> Volume Serial Number is 5C5F-0CC9 OUTPUT> OUTPUT> Directory of E:classescomjavaworldjpitfallsarticle2 OUTPUT> OUTPUT>10/23/00 09:01p 805 BadExecBrowser.java OUTPUT>10/22/00 09:35a 770 BadExecBrowser1.java OUTPUT>10/24/00 08:45p 488 BadExecJavac.java OUTPUT>10/24/00 08:46p 519 BadExecJavac2.java OUTPUT>10/24/00 09:13p 930 BadExecWinDir.java OUTPUT>10/22/00 09:21a 2,282 BadURLPost.java OUTPUT>10/22/00 09:20a 2,273 BadURLPost1.java ... (some output omitted for brevity) OUTPUT>10/12/00 09:29p 151 SuperFrame.java OUTPUT>10/24/00 09:23p 1,814 TestExec.java OUTPUT>10/09/00 05:47p 23,543 TestStringReplace.java OUTPUT>10/12/00 08:55p 228 TopLevel.java OUTPUT> 22 File(s) 46,661 bytes OUTPUT> 19,678,420,992 bytes free ExitValue: 0 這裏做者教了一個windows中頗有用的方法,呵呵,至少我是不知道的,就是cmd.exe /C +一個windows中註冊了後綴的文檔名,windows會自動地調用相關的程序來打開這個文檔,我試了一下,的確很好用,可是好像文件路徑中有空格的話就有點問題,我加上引號也沒法解決。 這裏做者強調了一下,不要假設你執行的程序是可執行的程序,要清楚本身的程序是單獨可執行的仍是被解釋的,本章的結束做者會介紹一個命令行工具來幫助咱們分析。 這裏還有一點,就是獲得process的輸出的方式是getInputStream,這是由於咱們要從Java 程序的角度來看,外部程序的輸出對於Java來講就是輸入,反之亦然。 最後的一個漏洞的地方就是錯誤的認爲exec方法會接受全部你在命令行或者Shell中輸入並接受的字符串。這些錯誤主要出如今命令做爲參數的狀況下,程序員錯誤的將全部命令行中能夠輸入的參數命令加入到exec中(這段翻譯的很差,湊合看吧)。下面的例子中就是一個程序員想重定向一個命令的輸出。 import java.util.*; import java.io.*; // StreamGobbler omitted for brevity public class BadWinRedirect { public static void main(String args[]) { try { Runtime rt = Runtime.getRuntime(); Process proc = rt.exec("java jecho 'Hello World' > test.txt"); // any error message? StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), "ERROR"); // any output? StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), "OUTPUT"); // kick them off errorGobbler.start(); outputGobbler.start(); // any error??? int exitVal = proc.waitFor(); System.out.println("ExitValue: " + exitVal); } catch (Throwable t) { t.printStackTrace(); } } } Running BadWinRedirect produces: E:classescomjavaworldjpitfallsarticle2>java BadWinRedirect OUTPUT>'Hello World' > test.txt ExitValue: 0 程序員的本意是將Hello World這個輸入重訂向到一個文本文件中,可是這個文件並無生成,jecho僅僅是將命令行中的參數輸出到標準輸出中,用戶以爲能夠像dos中重定向同樣將輸出重定向到一個文件中,但這並不能實現,用戶錯誤的將exec認爲是一個shell解釋器,但它並非,若是你想將一個程序的輸出重定向到其餘的程序中,你必須用程序來實現他。可用java.io中的包。 import java.util.*; import java.io.*; class StreamGobbler extends Thread { InputStream is; String type; OutputStream os; StreamGobbler(InputStream is, String type) { this(is, type, null); } StreamGobbler(InputStream is, String type, OutputStream redirect) { this.is = is; this.type = type; this.os = redirect; } public void run() { try { PrintWriter pw = null; if (os != null) pw = new PrintWriter(os); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String line=null; while ( (line = br.readLine()) != null) { if (pw != null) pw.println(line); System.out.println(type + ">" + line); } if (pw != null) pw.flush(); } catch (IOException ioe) { ioe.printStackTrace(); } } } public class GoodWinRedirect { public static void main(String args[]) { if (args.length < 1) { System.out.println("USAGE java GoodWinRedirect <outputfile>"); System.exit(1); } try { FileOutputStream fos = new FileOutputStream(args[0]); Runtime rt = Runtime.getRuntime(); Process proc = rt.exec("java jecho 'Hello World'"); // any error message? StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), "ERROR"); // any output? StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), "OUTPUT", fos); // kick them off errorGobbler.start(); outputGobbler.start(); // any error??? int exitVal = proc.waitFor(); System.out.println("ExitValue: " + exitVal); fos.flush(); fos.close(); } catch (Throwable t) { t.printStackTrace(); } } } Running GoodWinRedirect produces: E:classescomjavaworldjpitfallsarticle2>java GoodWinRedirect test.txt OUTPUT>'Hello World' ExitValue: 0 這裏就很少說了,看看就明白,緊接着做者給出了一個監測命令的小程序 import java.util.*; import java.io.*; // class StreamGobbler omitted for brevity public class TestExec { public static void main(String args[]) { if (args.length < 1) { System.out.println("USAGE: java TestExec "cmd""); System.exit(1); } try { String cmd = args[0]; Runtime rt = Runtime.getRuntime(); Process proc = rt.exec(cmd); // any error message? StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), "ERR"); // any output? StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), "OUT"); // kick them off errorGobbler.start(); outputGobbler.start(); // any error??? int exitVal = proc.waitFor(); System.out.println("ExitValue: " + exitVal); } catch (Throwable t) { t.printStackTrace(); } } } 對這個程序進行運行: E:classescomjavaworldjpitfallsarticle2>java TestExec "e:javadocsindex.html" java.io.IOException: CreateProcess: e:javadocsindex.html error=193 at java.lang.Win32Process.create(Native Method) at java.lang.Win32Process.<init>(Unknown Source) at java.lang.Runtime.execInternal(Native Method) at java.lang.Runtime.exec(Unknown Source) at java.lang.Runtime.exec(Unknown Source) at java.lang.Runtime.exec(Unknown Source) at java.lang.Runtime.exec(Unknown Source) at TestExec.main(TestExec.java:45) 193在windows中是說這不是一個win32程序,這說明路徑中找不到這個網頁的關聯程序,下面做者決定用一個絕對路徑來試一下。 E:classescomjavaworldjpitfallsarticle2>java TestExec "e:program filesnetscapeprogramnetscape.exe e:javadocsindex.html" ExitValue: 0 好用了,這個我也試了一下,用的是IE。 最後,做者總結了幾條規則,防止咱們在進行Runtime.exec()調用時出現錯誤。 <!--[if !supportLists]-->1、 <!--[endif]-->在一個外部進程執行完以前你不能獲得他的退出狀態 <!--[if !supportLists]-->2、 <!--[endif]-->在你的外部程序開始執行的時候你必須立刻控制輸入、輸出、出錯這些流。 <!--[if !supportLists]-->3、 <!--[endif]-->你必須用Runtime.exec()去執行程序 <!--[if !supportLists]-->4、 <!--[endif]-->你不能象命令行同樣使用Runtime.exec()。 12:35 評論 / 瀏覽 (0 / 11) 分類:編程語言 2011-11-30 縮略顯示 FileInputStream/FileOutputStream的應用 javafileoutputstreamfileinputstream 這是一對繼承於InputStream和OutputStream的類,用於本地文件讀寫(二進制格式讀寫而且是順序讀寫,讀和寫要分別建立出不一樣的文件流對象); 本地文件讀寫編程的基本過程爲: ① 生成文件流對象(對文件讀操做時應該爲FileInputStream類,而文件寫應該爲FileOutputStream類); ② 調用FileInputStream或FileOutputStream類中的功能函數如read()、write(int b)等)讀寫文件內容; ③ 關閉文件(close())。 實例:流文件讀寫 流文件的單元是字節,因此它不但能夠讀寫文本文件,也能夠讀寫圖片、聲音、影像文件,這種特色很是有用,由於咱們能夠把這種文件變成流,而後在網絡上傳輸。 問題是有了通用的流文件之後,爲何還要專門的字符流呢?這是由於文本能夠用不一樣的方式存儲,能夠是普通的文本(UTF-8編碼方式),ASCII文本和Unicode文本,字符流對象能夠進行必要的轉換,從而讀出正確的文本。 有人認爲流文件不能讀寫文本文件,這實際上是個誤會,由於文本文件本質上也是由字節組成的,固然是流文件的一種。做爲讀寫文件的全體,這是沒問題的,可是,若是要處理每次讀入的內容,就最好使用字符流。 因此在文本文件處理時,使用字符流是個最經常使用的方法。 樣例: import java.io.*; public class FileStreamDemo { public static void main(String[] args) throws IOException { //建立兩個文件,face.gif是已經存在文件,newFace.gif是新建立的文件 File inFile = new File("face.gif"); File outFile = new File("newFace.gif"); //建立流文件讀入與寫出類 FileInputStream inStream = new FileInputStream(inFile); FileOutputStream outStream = new FileOutputStream(outFile); //經過available方法取得流的最大字符數 byte[] inOutb = new byte[inStream.available()]; inStream.read(inOutb); //讀入流,保存在byte數組 outStream.write(inOutb); //寫出流,保存在文件newFace.gif中 inStream.close(); outStream.close(); } } 實例:讀寫任意大文件應用 由於byte數組最大存儲值不超過64M,因此當一個文件大於60M 的時候,須要分開幾個流操做。咱們把上面的程序做一個修改,就能夠寫入任意大小的文件。這個程序應用了FileInputStream類的方法以下: read(byte[] b,int off,int len) 把特定位置的流內容讀入數組,已經讀入byte[]數組的內容,會在流文件中刪除。 程序運行的結果會產生一個新文件。 樣例: import java.io.*; public class FileStreamDemo2 { public static void main(String[] args) throws IOException { //建立兩個文件 File inFile = new File("tcty36.rm"); File outFile = new File("newtcty36.rm"); //最大的流爲60Mb,當文件的容量大於60Mb的時候便分開流 final int MAX_BYTE = 60000000; long streamTotal = 0; //接受流的容量 int streamNum = 0; //流須要分開的數量 int leave = 0; //文件剩下的字符數 byte[] inOutb; //byte數組接受文件的數據 //建立流文件讀入與寫出類 FileInputStream inStream = new FileInputStream(inFile); FileOutputStream outStream = new FileOutputStream(outFile); //經過available方法取得流的最大字符數 streamTotal = inStream.available(); //取得流文件須要分開的數量 streamNum = (int)Math.floor(streamTotal/MAX_BYTE); //分開文件以後,剩餘的數量 leave = (int)streamTotal % MAX_BYTE; //文件的容量大於60Mb時進入循環 if (streamNum > 0) { for(int i = 0; i < streamNum; ++i){ inOutb = new byte[MAX_BYTE]; //讀入流,保存在byte數組 inStream.read(inOutb, 0, MAX_BYTE); outStream.write(inOutb); //寫出流 outStream.flush(); //更新寫出的結果 } } //寫出剩下的流數據 inOutb = new byte[leave]; inStream.read(inOutb, 0, leave); outStream.write(inOutb); outStream.flush(); inStream.close(); outStream.close(); } } 6、管道PipedInputStream/PipedOutputStream類: 當須要在兩個線程中讀寫數據的時候,因爲線程的併發執行,讀寫的同步問題可能會發生困難,這時候能夠使用管道,管道事實上是一個隊列。 管道是由系統維護的一個緩衝區,固然程序員也能夠本身直接指定該緩衝區的大小(只須要設置管道流類中的PIPE_SIZE屬性的值)。當生產者生產出數據後,只須要將數據寫入管道中,消費者只須要從管道中讀取所須要的數據。利用管道的這種機制,能夠將一個線程的輸出結果直接鏈接到另外一個線程的輸入端口,實現二者之間的數據直接傳送。 線程1 線程2 臨時文件 管道 1.管道的鏈接: 方法之一是經過構造函數直接將某一個程序的輸出做爲另外一個程序的輸入,在定義對象時指明目標管道對象 PipedInputStream pInput=new PipedInputStream(); PipedOutputStream pOutput= new PipedOutputStream(pInput); 方法之二是利用雙方類中的任一個成員函數 connect()相鏈接 PipedInputStream pInput=new PipedInputStream(); PipedOutputStream pOutput= new PipedOutputStream(); pinput.connect(pOutput); 2.管道的輸入與輸出: 輸出管道對象調用write()成員函數輸出數據(即向管道的輸入端發送數據);而輸入管道對象調用read()成員函數能夠讀起數據(即從輸出管道中得到數據)。這主要是藉助系統所提供的緩衝機制來實現的。 實例:Java的管道的輸入與輸出 import java.io.*; public class PipedIO //程序運行後將sendFile文件的內容拷貝到receiverFile文件中 { public static void main(String args[]) { try { //構造讀寫的管道流對象 PipedInputStream pis=new PipedInputStream(); PipedOutputStream pos=new PipedOutputStream(); //實現關聯 pos.connect(pis); //構造兩個線程,而且啓動。 new Sender(pos,"c:\\text2.txt").start(); new Receiver(pis,"c:\\text3.txt").start(); } catch(IOException e) { System.out.println("Pipe Error"+ e); } } } //線程發送 class Sender extends Thread { PipedOutputStream pos; File file; //構造方法 Sender(PipedOutputStream pos, String fileName) { this.pos=pos; file=new File(fileName); } //線程運行方法 public void run() { try { //讀文件內容 FileInputStream fs=new FileInputStream(file); int data; while((data=fs.read())!=-1) { //寫入管道始端 pos.write(data); } pos.close(); } catch(IOException e) { System.out.println("Sender Error" +e); } } } //線程讀 class Receiver extends Thread { PipedInputStream pis; File file; //構造方法 Receiver(PipedInputStream pis, String fileName) { this.pis=pis; file=new File(fileName); } //線程運行 public void run() { try { //寫文件流對象 FileOutputStream fs=new FileOutputStream(file); int data; //從管道末端讀 while((data=pis.read())!=-1) { //寫入本地文件 fs.write(data); } pis.close(); } catch(IOException e) { System.out.println("Receiver Error" +e); } } } 7、隨機文件讀寫:RandomAccessFile類 它直接繼承於Object類而非InputStream/OutputStream類,從而能夠實現讀寫文件中任何位置中的數據(只須要改變文件的讀寫位置的指針)。 編程步驟: ① 生成流對象而且指明讀寫類型; ② 移動讀寫位置; ③ 讀寫文件內容; ④ 關閉文件。 另外因爲RandomAccessFile類實現了DataOutput與DataInput接口,於是利用它能夠讀寫Java中的不一樣類型的基本類型數據(好比採用readLong()方法讀取長整數,而利用readInt()方法能夠讀出整數值等)。 程序實例: 利用隨機數據流RandomAccessFile類來實現記錄用戶在鍵盤的輸入,每執行一次,將用戶的鍵盤輸入存儲在指定的UserInput.txt文件中。 import java.io.*; public class RandomFileRW { public static void main(String args[]) { StringBuffer buf=new StringBuffer(); char ch; try { while( (ch=(char)System.in.read()) !='\n') { buf.append(ch); } //讀寫方式能夠爲"r" or "rw" RandomAccessFile myFileStream=new RandomAccessFile("c:\\UserInput.txt","rw"); myFileStream.seek(myFileStream.length()) ; myFileStream.writeBytes(buf.toString()); //將用戶從鍵盤輸入的內容添加到文件的尾部 myFileStream.close(); } catch(IOException e) { } } } 8、DataInput/DataOutput接口: 實現與機器無關的各類數據格式讀寫(如readChar() 、readInt()、readLong()、readFloat(),而readLine()將返回一個String)。其中 RandomAccessFile類實現了該接口,具備比FileInputStream或FileOutputStream類更靈活的數據讀寫方式。 12:27 評論 / 瀏覽 (0 / 17) 分類:編程語言 2011-11-28 縮略顯示 Linux C 建立目錄函數mkdir相關 linuxc I.Linux C 建立目錄函數mkdir的mode設置問題 函數原型: #include <sys/stat.h> int mkdir(const char *path, mode_t mode); 參數: path是目錄名 mode是目錄權限 返回值: 返回0 表示成功, 返回 -1表示錯誤,而且會設置errno值。 mode模式位: mode 表示新目錄的權限,能夠取如下值: S_IRUSR S_IREAD S_IWUSR S_IWRITE S_IXUSR S_IEXEC S_IRWXU This is equivalent to (S_IRUSR | S_IWUSR | S_IXUSR). S_IRGRP Read permission bit for the group owner of the file. Usually 040. S_IWGRP Write permission bit for the group owner of the file. Usually 020. S_IXGRP Execute or search permission bit for the group owner of the file. Usually 010. S_IRWXG This is equivalent to (S_IRGRP | S_IWGRP | S_IXGRP). S_IROTH Read permission bit for other users. Usually 04. S_IWOTH Write permission bit for other users. Usually 02. S_IXOTH Execute or search permission bit for other users. Usually 01. S_IRWXO This is equivalent to (S_IROTH | S_IWOTH | S_IXOTH). S_ISUID This is the set-user-ID on execute bit, usually 04000. See How Change Persona. S_ISGID This is the set-group-ID on execute bit, usually 02000. See How Change Persona. S_ISVTX This is the sticky bit, usually 01000. 例子: #include <sys/types.h> #include <sys/stat.h> int status; status = mkdir("/home/newdir", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); 這樣就建立了一個newdir目錄,權限經過ls -al 查看爲 drwxr-xr-x 跟用linux命令mkdir建立的目錄權限位一致。 II. linux下C語言建立多級目錄 int CreateDir(const char *sPathName) { char DirName[256]; strcpy(DirName, sPathName); int i,len = strlen(DirName); if(DirName[len-1]!='/') strcat(DirName, "/"); len = strlen(DirName); for(i=1; i<len; i++) { if(DirName[i]=='/') { DirName[i] = 0; if( access(DirName, NULL)!=0 ) { if(mkdir(DirName, 0755)==-1) { perror("mkdir error"); return -1; } } DirName[i] = '/'; } } return 0; } III.linux c 編程:建立一個線程,監視某個目錄,一旦目錄裏出現新的文件,就將文件轉移到指定的目錄裏去。 /* 頭文件 */ #define SRCPATH "srcpath/" #define DSTPATH "dstpath/" int movefile() { DIR *dir; struct dirent *dt; FILE *fp1,*fp2; char filename1[256],filename2[256]; char buf[1024]; int readsize,writesize; if((dir = opendir(SRCPATH)) == NULL) { printf("opendir %s error\n",SRCPATH); return -1; } memset(filename1,0,sizeof(filename1)); strcpy(filename1,SRCPATH); memset(filename2,0,sizeof(filename2)); strcpy(filename2,DSTPATH); while(1) { while((dt = readdir(dir)) != NULL) { if(strcmp(dt->d_name,".")==0||strcmp(dt->d_name,"..")==0) { continue; } //若是這個目錄裏 還有目錄,能夠在這加判斷 //這裏假設初始爲空目錄 strcat(filename1,dt->d_name); strcat(filename2,dt->d_name); //若是進程資源較少能夠直接用linux系統命令 fp1 = fopen(filename1,"rb"); if(fp1==NULL) { printf("open %s failed /n",filename1); return -1; } fp2 = fopen(filename2,"wb"); if(fp2==NULL) { printf("open %s failed /n",filename2); fclose(fp1); return -1; } while((readsize = fread(buf,sizeof(buf),1,fp1))>0) { //total += readsize; memset(buf,0,sizeof(buf)); writesize = fwrite(buf,sizeof(buf),1,fp2); if(writesize!==readsize) { printf("write error"); return -2; fclose(fp1); fclose(fp2); } } fclose(fp1); fclose(fp2); rmdir(filename2); } } } int main(int argc,char **argv) { pthread_t id1; int ret; ret = pthread_create(&id1, NULL, (void*)movefile, NULL); return ret; } 14:56 評論 / 瀏覽 (0 / 18) 分類:編程語言 2011-11-28 縮略顯示 Linux下的C編程實戰之文件系統編程 linuxc編程 1.Linux文件系統 Linux支持多種文件系統,如ext、ext二、minix、iso9660、msdos、fat、vfat、nfs等。在這些具體文件系統的上層,Linux提供了虛擬文件系統(VFS)來統一它們的行爲,虛擬文件系統爲不一樣的文件系統與內核的通訊提供了一致的接口。 linux下的c語言開發 在Linux平臺下對文件編程能夠使用兩類函數:(1)Linux操做系統文件API;(2)C語言I/O庫函數。 前者依賴於Linux系統調用,後者實際上與操做系統是獨立的,由於在任何操做系統下,使用C語言I/O庫函數操做文件的方法都是相同的。本章將對這兩種方法進行實例講解。 2.Linux文件API Linux的文件操做API涉及到建立、打開、讀寫和關閉文件。 建立 int creat(const char *filename, mode_t mode); 參數mode指定新建文件的存取權限,它同umask一塊兒決定文件的最終權限(mode&umask),其中umask表明了文件在建立時須要去掉的一些存取權限。umask可經過系統調用umask()來改變: int umask(int newmask); 該調用將umask設置爲newmask,而後返回舊的umask,它隻影響讀、寫和執行權限。 打開 int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode); open函數有兩個形式,其中pathname是咱們要打開的文件名(包含路徑名稱,缺省是認爲在當前路徑下面),flags能夠去下面的一個值或者是幾個值的組合: 標誌 含義 O_RDONLY 以只讀的方式打開文件 O_WRONLY 以只寫的方式打開文件 O_RDWR 以讀寫的方式打開文件 O_APPEND 以追加的方式打開文件 O_CREAT 建立一個文件 O_EXEC 若是使用了O_CREAT並且文件已經存在,就會發生一個錯誤 O_NOBLOCK 以非阻塞的方式打開一個文件 O_TRUNC 若是文件已經存在,則刪除文件的內容 O_RDONLY、O_WRONLY、O_RDWR三個標誌只能使用任意的一個。 若是使用了O_CREATE標誌,則使用的函數是int open(const char *pathname,int flags,mode_t mode); 這個時候咱們還要指定mode標誌,用來表示文件的訪問權限。mode能夠是如下狀況的組合: 標誌 含義 S_IRUSR 用戶能夠讀 S_IWUSR 用戶能夠寫 S_IXUSR 用戶能夠執行 S_IRWXU 用戶能夠讀、寫、執行 S_IRGRP 組能夠讀 S_IWGRP 組能夠寫 S_IXGRP 組能夠執行 S_IRWXG 組能夠讀寫執行 S_IROTH 其餘人能夠讀 S_IWOTH 其餘人能夠寫 S_IXOTH 其餘人能夠執行 S_IRWXO 其餘人能夠讀、寫、執行 S_ISUID 設置用戶執行ID S_ISGID 設置組的執行ID 除了能夠經過上述宏進行「或」邏輯產生標誌之外,咱們也能夠本身用數字來表示,Linux總共用5個數字來表示文件的各類權限:第一位表示設置用戶ID;第二位表示設置組ID;第三位表示用戶本身的權限位;第四位表示組的權限;最後一位表示其餘人的權限。每一個數字能夠取1(執行權限)、2(寫權限)、4(讀權限)、0(無)或者是這些值的和。例如,要建立一個用戶可讀、可寫、可執行,可是組沒有權限,其餘人能夠讀、能夠執行的文件,並設置用戶ID位。那麼,咱們應該使用的模式是1(設置用戶ID)、0(不設置組 ID)、7(1+2+4,讀、寫、執行)、0(沒有權限)、5(1+4,讀、執行)即10705: open("test", O_CREAT, 10705); 上述語句等價於: open("test", O_CREAT, S_IRWXU | S_IROTH | S_IXOTH | S_ISUID ); 若是文件打開成功,open函數會返回一個文件描述符,之後對該文件的全部操做就能夠經過對這個文件描述符進行操做來實現。 讀寫 在文件打開之後,咱們纔可對文件進行讀寫了,Linux中提供文件讀寫的系統調用是read、write函數: int read(int fd, const void *buf, size_t length); int write(int fd, const void *buf, size_t length); 其中參數buf爲指向緩衝區的指針,length爲緩衝區的大小(以字節爲單位)。函數read()實現從文件描述符fd所指定的文件中讀取 length個字節到buf所指向的緩衝區中,返回值爲實際讀取的字節數。函數write實現將把length個字節從buf指向的緩衝區中寫到文件描述符fd所指向的文件中,返回值爲實際寫入的字節數。 以O_CREAT爲標誌的open實際上實現了文件建立的功能,所以,下面的函數等同creat()函數: int open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode); 定位 對於隨機文件,咱們能夠隨機的指定位置讀寫,使用以下函數進行定位: int lseek(int fd, offset_t offset, int whence); lseek()將文件讀寫指針相對whence移動offset個字節。操做成功時,返回文件指針相對於文件頭的位置。參數whence可以使用下述值: SEEK_SET:相對文件開頭 SEEK_CUR:相對文件讀寫指針的當前位置 SEEK_END:相對文件末尾 offset可取負值,例以下述調用可將文件指針相對當前位置向前移動5個字節: lseek(fd, -5, SEEK_CUR); 因爲lseek函數的返回值爲文件指針相對於文件頭的位置,所以下列調用的返回值就是文件的長度: lseek(fd, 0, SEEK_END); 關閉 當咱們操做完成之後,咱們要關閉文件了,只要調用close就能夠了,其中fd是咱們要關閉的文件描述符: int close(int fd); 例程:編寫一個程序,在當前目錄下建立用戶可讀寫文件「hello.txt」,在其中寫入「Hello, software weekly」,關閉該文件。再次打開該文件,讀取其中的內容並輸出在屏幕上。 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #define LENGTH 100 main() { int fd, len; char str[LENGTH]; fd = open("hello.txt", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); /* 建立並打開文件 */ if (fd) { write(fd, "Hello, Software Weekly", strlen("Hello, software weekly")); /* 寫入 Hello, software weekly字符串 */ close(fd); } fd = open("hello.txt", O_RDWR); len = read(fd, str, LENGTH); /* 讀取文件內容 */ str[len] = '\0'; printf("%s\n", str); close(fd); } 編譯並運行,執行結果以下圖: linux 3.C語言庫函數 C庫函數的文件操做其實是獨立於具體的操做系統平臺的,無論是在DOS、Windows、Linux仍是在VxWorks中都是這些函數: 建立和打開 FILE *fopen(const char *path, const char *mode); fopen()實現打開指定文件filename,其中的mode爲打開模式,C語言中支持的打開模式以下表: 標誌 含義 r, rb 以只讀方式打開 w, wb 以只寫方式打開。若是文件不存在,則建立該文件,不然文件被截斷 a, ab 以追加方式打開。若是文件不存在,則建立該文件 r+, r+b, rb+ 以讀寫方式打開 w+, w+b, wh+ 以讀寫方式打開。若是文件不存在時,建立新文件,不然文件被截斷 a+, a+b, ab+ 以讀和追加方式打開。若是文件不存在,建立新文件 其中b用於區分二進制文件和文本文件,這一點在DOS、Windows系統中是有區分的,但Linux不區分二進制文件和文本文件。 讀寫 C庫函數支持以字符、字符串等爲單位,支持按照某中格式進行文件的讀寫,這一組函數爲: int fgetc(FILE *stream); int fputc(int c, FILE *stream); char *fgets(char *s, int n, FILE *stream); int fputs(const char *s, FILE *stream); int fprintf(FILE *stream, const char *format, ...); int fscanf (FILE *stream, const char *format, ...); size_t fread(void *ptr, size_t size, size_t n, FILE *stream); size_t fwrite (const void *ptr, size_t size, size_t n, FILE *stream); fread()實現從流stream中讀取加n個字段,每一個字段爲size字節,並將讀取的字段放入ptr所指的字符數組中,返回實際已讀取的字段數。在讀取的字段數小於num時,多是在函數調用時出現錯誤,也多是讀到文件的結尾。因此要經過調用feof()和ferror()來判斷。 write()實現從緩衝區ptr所指的數組中把n個字段寫到流stream中,每一個字段長爲size個字節,返回實際寫入的字段數。 另外,C庫函數還提供了讀寫過程當中的定位能力,這些函數包括 int fgetpos(FILE *stream, fpos_t *pos); int fsetpos(FILE *stream, const fpos_t *pos); int fseek(FILE *stream, long offset, int whence); 等。 關閉 利用C庫函數關閉文件依然是很簡單的操做: int fclose (FILE *stream); 例程:將第2節中的例程用C庫函數來實現。 #include <stdio.h> #define LENGTH 100 main() { FILE *fd; char str[LENGTH]; fd = fopen("hello.txt", "w+"); /* 建立並打開文件 */ if (fd) { fputs("Hello, Software Weekly", fd); /* 寫入Hello, software weekly字符串 */ fclose(fd); } fd = fopen("hello.txt", "r"); fgets(str, LENGTH, fd); /* 讀取文件內容 */ printf("%s\n", str); fclose(fd); } 4.小結 Linux提供的虛擬文件系統爲多種文件系統提供了統一的接口,Linux的文件編程有兩種途徑:基於Linux系統調用;基於C庫函數。這兩種編程所涉及到文件操做有新建、打開、讀寫和關閉,對隨機文件還能夠定位。本章對這兩種編程方法都給出了具體的實例。 14:00 評論 / 瀏覽 (0 / 19) 分類:編程語言 2011-11-28 縮略顯示 基本IO函數的使用(open,write,read)(一) linux c 首先感謝做者的工做,謝謝了,轉到這裏都是我須要過的 =>#include <fcntl.h> =>/usr/include/bits/fcntl.h ,裏面有 /* open/fcntl - O_SYNC is only implemented on blocks devices and on files located on an ext2 file system */ #define O_ACCMODE 0003 #define O_RDONLY 00 #define O_WRONLY 01 #define O_RDWR 02 #define O_CREAT 0100 /* not fcntl */ #define O_EXCL 0200 /* not fcntl */ #define O_NOCTTY 0400 /* not fcntl */ #define O_TRUNC 01000 /* not fcntl */ #define O_APPEND 02000 #define O_NONBLOCK 04000 #define O_NDELAY O_NONBLOCK #define O_SYNC 010000 #define O_FSYNC O_SYNC #define O_ASYNC 020000 摘要:本文簡單介紹文件操做的三個函數(open,read,write)的基本用法。 詳細說明了open函數的用法。 做者:zieckey (zieckey@yahoo.com.cn) All Rights Reserved! 所需頭文件: #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> 函數定義: int open( const char * pathname, int flags); int open( const char * pathname,int flags, mode_t mode); 函數說明: 參數 pathname 指向欲打開的文件路徑字符串。下列是參數 flags 所能使用的旗標: O_RDONLY 以只讀方式打開文件 O_WRONLY 以只寫方式打開文件 O_RDWR以可讀寫方式打開文件。 上述三種旗標是互斥的,也就是不可同時使用,但可與下列的旗標利用 OR(|)運算符組合。 O_CREAT 若欲打開的文件不存在則自動創建該文件。 O_EXCL 若是 O_CREAT 也被設置, 此指令會去檢查文件是否存在。文件若不存在則創建該文件, 不然將致使打開文件錯誤。 此外,若 O_CREAT 與 O_EXCL 同時設置, 而且欲打開的文件爲符號鏈接,則會打開文件失敗。 O_NOCTTY 若是欲打開的文件爲終端機設備時,則不會將該終端機當成進程控制終端機。 O_TRUNC 若文件存在而且以可寫的方式打開時,此旗標會令文件長度清爲 0,而原來存於該文件的資料也會消失。 O_APPEND 當讀寫文件時會從文件尾開始移動, 也就是所寫入的數據會以附加的方式加入到文件後面。 O_NONBLOCK 以不可阻斷的方式打開文件,也就是不管有無數據讀取或等待,都會當即返回進程之中。 O_NDELAY 同 O_NONBLOCK。 O_SYNC 以同步的方式打開文件。 O_NOFOLLOW 若是參數 pathname 所指的文件爲一符號鏈接,則會令打開文件失敗。 O_DIRECTORY 若是參數 pathname 所指的文件並不是爲一目錄, 則 會令打開文件失敗。此爲 Linux2.2 之後特有的旗標,以免一些系 統安全問題。參數 mode 則有下列數種組合,只有在創建新文件時 纔會生效,此外真正建文件時的權限會受到 umask 值所影響,所以 該文件權限應該爲(mode-umaks). S_IRWXU00700 權限, 表明該文件全部者具備可讀、 可寫及可執行的權限。 S_IRUSR 或 S_IREAD,00400 權限,表明該文件全部者具備可讀取的權限。 S_IWUSR 或 S_IWRITE,00200 權限,表明該文件全部者具備可寫入的權限。 S_IXUSR 或 S_IEXEC,00100 權限,表明該文件全部者具備可執行的權限。 S_IRWXG 00070 權限,表明該文件用戶組具備可讀、 可寫及可執行的權限。 S_IRGRP 00040 權限,表明該文件用戶組具備可讀的權限。 S_IWGRP 00020 權限,表明該文件用戶組具備可寫入的權限。 S_IXGRP 00010 權限,表明該文件用戶組具備可執行的權限。 S_IRWXO 00007 權限,表明其餘用戶具備可讀、可寫及可執行的權限。 S_IROTH 00004 權限,表明其餘用戶具備可讀的權限 S_IWOTH 00002 權限,表明其餘用戶具備可寫入的權限。 S_IXOTH 00001 權限,表明其餘用戶具備可執行的權限。 返回值: 若全部欲覈查的權限都經過了檢查則返回 0 值,表示成功,只要有 一個權限被禁止則返回-1。 錯誤代碼: EEXIST 參數 pathname 所指的文件已存在,卻使用了 O_CREAT和 O_EXCL 旗標 EACCESS 參數 pathname 所指的文件不符合所要求測試的權限。 EROFS 欲測試寫入權限的文件存在於只讀文件系統內。 EFAULT 參數 pathname 指針超出可存取內存空間。 EINVAL 參數 mode 不正確。 ENAMETOOLONG 參數 pathname 太長。 ENOTDIR 參數 pathname 不是目錄。 ENOMEM 核心內存不足。 ELOOP 參數 pathname 有過多符號鏈接問題。 EIO I/O 存取錯誤。 範例: #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> int main(void) { int fd,size; char s[]="This program is used to show how to use open(),write(),read() function.\nHave fun!\n"; char buffer[80]; fd = open( "temp.log", O_WRONLY|O_CREAT );//以可讀寫的方式打開一個文件,若是不存在則建立該文件 if ( -1 == fd ) { printf("Open or create file named \"temp.log\" failed.\n"); return -1; } write( fd, s, sizeof(s) );//向該文件中寫入一個字符串 close( fd ); fd = open( "temp.log", O_RDONLY ); if ( -1 == fd ) { printf("Open file named \"temp.log\" failed.\n"); return -1; } size = read( fd, buffer, sizeof(buffer) );//讀取文件內容保存到buffer指定的字符串數組中,返回讀取的字符個數 close( fd ); printf( "%s", buffer ); return 0; } 13:44 評論 / 瀏覽 (0 / 3) 分類:編程語言 2011-11-18 縮略顯示 Android讀寫文件 android 1、 從resource中的raw文件夾中獲取文件並讀取數據(資源文件只能讀不能寫) String res = ""; try{ InputStream in = getResources().openRawResource(R.raw.bbi); //在\Test\res\raw\bbi.txt, int length = in.available(); byte [] buffer = new byte[length]; in.read(buffer); //res = EncodingUtils.getString(buffer, "UTF-8"); //res = EncodingUtils.getString(buffer, "UNICODE"); res = EncodingUtils.getString(buffer, "BIG5"); //依bbi.txt的編碼類型選擇合適的編碼,若是不調整會亂碼 in.close(); }catch(Exception e){ e.printStackTrace(); } myTextView.setText(res);//把獲得的內容顯示在TextView上 2、 從asset中獲取文件並讀取數據(資源文件只能讀不能寫) String fileName = "yan.txt"; //文件名字 String res=""; try{ InputStream in = getResources().getAssets().open(fileName); // \Test\assets\yan.txt這裏有這樣的文件存在 int length = in.available(); byte [] buffer = new byte[length]; in.read(buffer); res = EncodingUtils.getString(buffer, "UTF-8"); }catch(Exception e){ e.printStackTrace(); } 3、 從sdcard中去讀文件,首先要把文件經過\android-sdk-windows\tools\adb.exe把本地計算機上的文件copy到sdcard上去,adb.exe push e:/Y.txt /sdcard/, 不能夠用adb.exe push e:\Y.txt \sdcard\ 一樣: 把仿真器上的文件copy到本地計算機上用: adb pull ./data/data/com.tt/files/Test.txt e:/ String fileName = "/sdcard/Y.txt"; //也能夠用String fileName = "mnt/sdcard/Y.txt"; String res=""; try{ FileInputStream fin = new FileInputStream(fileName); //FileInputStream fin = openFileInput(fileName); //用這個就不行了,必須用FileInputStream int length = fin.available(); byte [] buffer = new byte[length]; fin.read(buffer); res = EncodingUtils.getString(buffer, "UTF-8"); fin.close(); }catch(Exception e){ e.printStackTrace(); } myTextView.setText(res); 4、 寫文件, 通常寫在\data\data\com.test\files\裏面,打開DDMS查看file explorer是能夠看到仿真器文件存放目錄的結構的 String fileName = "TEST.txt"; String message = "FFFFFFF11111FFFFF" ; writeFileData(fileName, message); public voidwriteFileData(String fileName,String message){ try{ FileOutputStream fout =openFileOutput(fileName, MODE_PRIVATE); byte [] bytes = message.getBytes(); fout.write(bytes); fout.close(); } catch(Exception e){ e.printStackTrace(); } } 5、 寫, 讀data/data/目錄(至關AP工做目錄)上的文件,用openFileOutput //寫文件在./data/data/com.tt/files/下面 public voidwriteFileData(String fileName,String message){ try{ FileOutputStream fout =openFileOutput(fileName, MODE_PRIVATE); byte [] bytes = message.getBytes(); fout.write(bytes); fout.close(); } catch(Exception e){ e.printStackTrace(); } } //------------------------------------------------------- //讀文件在./data/data/com.tt/files/下面 public String readFileData(String fileName){ String res=""; try{ FileInputStream fin = openFileInput(fileName); int length = fin.available(); byte [] buffer = new byte[length]; fin.read(buffer); res = EncodingUtils.getString(buffer, "UTF-8"); fin.close(); } catch(Exception e){ e.printStackTrace(); } return res; } 6、 寫, 讀sdcard目錄上的文件,要用FileOutputStream, 不能用openFileOutput //寫在/mnt/sdcard/目錄下面的文件 public voidwriteFileSdcard(String fileName,String message){ try{ //FileOutputStream fout = openFileOutput(fileName, MODE_PRIVATE); FileOutputStream fout = newFileOutputStream(fileName); byte [] bytes = message.getBytes(); fout.write(bytes); fout.close(); } catch(Exception e){ e.printStackTrace(); } } //讀在/mnt/sdcard/目錄下面的文件 public String readFileSdcard(String fileName){ String res=""; try{ FileInputStream fin = new FileInputStream(fileName); int length = fin.available(); byte [] buffer = new byte[length]; fin.read(buffer); res = EncodingUtils.getString(buffer, "UTF-8"); fin.close(); } catch(Exception e){ e.printStackTrace(); } return res; } 注: openFileOutput是在raw裏編譯過的,FileOutputStream是任何文件均可以 參考:http://dev.10086.cn/cmdn/wiki/index.php?doc-view-6017.html 12:12 評論 / 瀏覽 (0 / 30) 分類:移動開發 2011-11-09 縮略顯示 ASCII Characters 對照表 asc asc碼對照表 ------------------------------------------------------------- ASCII Characters Dec Hex Char Code Dec Hex Char 0 0 NUL 64 40 @ 1 1 SOH 65 41 A 2 2 STX 66 42 B 3 3 ETX 67 43 C 4 4 EOT 68 44 D 5 5 ENQ 69 45 E 6 6 ACK 70 46 F 7 7 BEL 71 47 G 8 8 BS 72 48 H 9 9 HT 73 49 I 10 0A LF 74 4A J 11 0B VT 75 4B K 12 0C FF 76 4C L 13 0D CR 77 4D M 14 0E SO 78 4E N 15 0F SI 79 4F O 16 10 SLE 80 50 P 17 11 CS1 81 51 Q 18 12 DC2 82 52 R 19 13 DC3 83 53 S 20 14 DC4 84 54 T 21 15 NAK 85 55 U 22 16 SYN 86 56 V 23 17 ETB 87 57 W 24 18 CAN 88 58 X 25 19 EM 89 59 Y 26 1A SIB 90 5A Z 27 1B ESC 91 5B [ 28 1C FS 92 5C / 29 1D GS 93 5D ] 30 1E RS 94 5E ^ 31 1F US 95 5F _ 32 20 (space) 96 60 ` 33 21 ! 97 61 a 34 22 " 98 62 b 35 23 # 99 63 c 36 24 $ 100 64 d 37 25 % 101 65 e 38 26 & 102 66 f 39 27 ' 103 67 g 40 28 ( 104 68 h 41 29 ) 105 69 i 42 2A * 106 6A j 43 2B + 107 6B k 44 2C , 108 6C l 45 2D - 109 6D m 46 2E . 110 6E n 47 2F / 111 6F o 48 30 0 112 70 p 49 31 1 113 72 q 50 32 2 114 72 r 51 33 3 115 73 s 52 34 4 116 74 t 53 35 5 117 75 u 54 36 6 118 76 v 55 37 7 119 77 w 56 38 8 120 78 x 57 39 9 121 79 y 58 3A : 122 7A z 59 3B ; 123 7B { 60 3C < 124 7C | 61 3D = 125 7D } 62 3E > 126 7E ~ 63 3F ? 127 7F 目前計算機中用得最普遍的字符集及其編碼,是由美國國家標準局(ANSI)制定的ASCII碼(American Standard Code for Information Interchange,美國標準信息交換碼),它已被國際標準化組織(ISO)定爲國際標準,稱爲ISO 646標準。適用於全部拉丁文字字母,ASCII碼有7位碼和8位碼兩種形式。 由於1位二進制數能夠表示(21=)2種狀態:0、1;而2位二進制數能夠表示(22)=4種狀態:00、01、10、11;依次類推,7位二進制數能夠表示(27=)128種狀態,每種狀態都惟一地編爲一個7位的二進制碼,對應一個字符(或控制碼),這些碼能夠排列成一個十進制序號0~127。因此,7位 ASCII碼是用七位二進制數進行編碼的,能夠表示128個字符。 第0~32號及第127號(共34個)是控制字符或通信專用字符,如控制符:LF(換行)、CR(回車)、FF(換頁)、DEL(刪除)、BEL(振鈴)等;通信專用字符:SOH(文頭)、EOT(文尾)、ACK(確認)等; 第33~126號(共94個)是字符,其中第48~57號爲0~9十個阿拉伯數字;65~90號爲26個大寫英文字母,97~122號爲26個小寫英文字母,其他爲一些標點符號、運算符號等。 注意:在計算機的存儲單元中,一個ASCII碼值佔一個字節(8個二進制位),其最高位(b7)用做奇偶校驗位。所謂奇偶校驗,是指在代碼傳送過程當中用來檢驗是否出現錯誤的一種方法,通常分奇校驗和偶校驗兩種。奇校驗規定:正確的代碼一個字節中1的個數必須是奇數,若非奇數,則在最高位b7添1;偶校驗規定:正確的代碼一個字節中1的個數必須是偶數,若非偶數,則在最高位b7添1。 第128~255號爲擴展字符(不經常使用),如須要請下載:完整的8位ASCII字符表 09:36 評論 / 瀏覽 (0 / 7) 分類:非技術 2011-11-03 縮略顯示 Android輸入事件流程中的EventHub分析及源碼演示 android Android2.3的輸入事件流程與之前版本有了較大的不一樣,這裏作一下詳細的分析,最後我把本身分析時用的演示代碼放在了這裏: http://code.google.com/p/flying-on-android/ 下面的分析都是基於這些源碼的,你們能夠下載下來一邊看源碼一邊看文檔。源碼裏只要關注FlyingEvent這個類就能夠了。若是隻想看一下演示結果,能夠直接把包裏的flying放到機器的/system/bin目錄執行,打開logcat後就能夠看到演示輸出。運行程序時,機器屏幕會有異象產生,很正常,由於這個程序本來是用於顯示SurfaceFlinger的,此次爲了演示EventHub稍微改了一下。你們只要關注 FlyingEvent.cpp這個文件就行了。 你們也能夠用源碼本身編譯出演示程序,只要把解壓後的flying文件夾放到/frameworks/base/cmds/目錄下,而後切換到flying目錄下使用mm編譯。 先大體介紹一下整個流程,再作重點分析。輸入事件流程一共涉及到下面這幾個文件: /frameworks/base/services/java/com/android/server/WindowManagerService.java /frameworks/base/services/java/com/android/server/InputManager.java /frameworks/base/services/jni/com_android_server_InputManager.cpp /frameworks/base/libs/ui/InputReader.cpp /frameworks/base/libs/ui/InputDispatcher.cpp /frameworks/base/libs/ui/EventHub.cpp 其中,WindowManagerService.java和InputManager.java主要向Android爲窗口系統提供服務,EventHub.cpp主要用來讀取設備文件中的RawEvent,而InputReader.cpp和InputDispatcher.cpp算是它們之間的對接層。 它們的關係是:WindowManagerService經過InputManager提供的接口開啓一個線程驅動InputReader不斷地從 /dev/input/目錄下面的設備文件讀取事件,而後經過InputDispatcher分發給鏈接到WindowManagerService服務的客戶端。 InputReader從設備文件中讀取的是RawEvent,在交給InputDispatcher進行分發以前,它須要先把RawEvent進行轉化分類,拆分紅KeyEvent、MotionEvent、TrackEvent各類類型等。這篇文章主要關注的就是這個RawEvent的拆分過程,因此咱們的重點在EventHub.cpp中。而且,爲了簡單化分析過程,在這裏個人分析只關注觸摸屏事件。看它是如何從RawEvent被拆分紅應用層用戶事件MotionEvent的。 看下面的分析以前,最好先去上面提到的地址把源碼下載下來,參照裏面的FlyingEvent.cpp。 整個過程大體分紅這麼幾步: 1、初始化。 先new一個EventHub的實例:mEventHub(new EventHub), 接下來,開啓一個線程經過mEventHub不停地從設備文件中讀取RawEvent並處理: while (1) { RawEvent event; mEventHub->getEvent(&event); process(event); } EventHub在初始化的時候作一些事情, 1、搜索當前的輸入設備每搜索到一個就會產生一個類型爲DEVICE_ADDED的事件,當讀取這種RawEvent時,InputReader會把搜索到的這個設備記錄下來。 2、若是搜索到了鍵盤時,就會加載鍵盤佈局文件。加載完成後產生一個類型爲FINISHED_DEVICE_SCAN的事件。這樣,後邊從驅動讀取用戶按鍵時,就會去加載的鍵盤佈局文件中尋找映射的鍵值封裝成KeyEvent返回給用戶。 2、EventHub初始化完畢後,就開始等待用戶輸入。線程一直阻塞在mEventHub->getEvent(&event),直到有用戶事件產生纔會返回。 當有一個事件產生時,傳遞給process進行處理。 3、事件拆分 FlyingEvent.process裏面主要調用了FlyingEvent.consume方法來處理用戶事件。這裏只分析touch事件。touch事件能夠分爲三種:down,move,up。 down類型的touch事件須要四個RawEvent來完成,第一個是X座標(ABS_X),第二個是Y座標(ABS_Y),第三個表明方向(ABS_PRESSURE)(0的時候是up,1的時候是down,因此這裏應該是1),第四個是結束標誌(SYN_REPORT)。 move類型的touch事件須要三個RawEvent來完成,第一個是X座標,第二個是Y座標,第三個是結束標誌。 up類型的touch事件須要兩個RawEvent來完成,第一個表明方向(0的時候是up,1的時候是down,因此這裏應該是0),第四個是結束標誌。 可能你已經注意到了up事件是沒有座標信息的,它的座標信息與down(沒有move時)或最後一個move(down和up之間有move事件產生)事件的座標相同。 從FlyingEvent.consume方法中,每個事件最終都會生成一個TouchEvent,而後調用printTouchEvent進行打印,最後把它存儲到eventBuffer中。 參考文章 李先靜的「Android輸入事件流程「,不過使用的Android版本比較老了。 http://blog.csdn.net/absurd/archive/2009/05/17/4195363.aspx (摘自:http://blog.csdn.net/a345017062/article/details/6417929) 19:58 評論 / 瀏覽 (0 / 35) 分類:移動開發 2011-10-21 縮略顯示 svn還原恢復 svn 1.對文件和目錄的修改還原 svn revert PATH... 描述 恢復全部對文件和目錄的修改,而且解決全部的衝突狀態。svn revert不會只是恢復工做拷貝中一個項目的內容,也包括了對屬性修改的恢復。最終,你能夠使用它來取消全部已經作過的預約操做(例如,文件預約要添加或刪除能夠「恢復」)。 例子 丟棄對一個文件的修改: $ svn revert foo.c Reverted foo.c 若是你但願恢復一整個目錄的文件,能夠使用--recursive選項: $ svn revert --recursive . Reverted newdir/afile Reverted foo.c Reverted bar.txt 2.還原到之前版本 svn update -r 200 test.php(將版本庫中的文件test.php還原到版本200) 3.列出本地與SVN當前版本差別 svn status -v path(顯示文件和子目錄狀態) 簡寫:svn st 第一列保持相同,第二列顯示工做版本號,第三和第四列顯示最後一次修改的版本號和修改人。 另外,可執行script -q tty.log後,就開始記錄終端的輸入輸出信息,結束的時候按ctrl+D便可獲得終端的內容文件tty.log 4. svn比較差別 svn diff path(將修改的文件與基礎版本比較) 例如:svn diff test.php svn diff -r m:n path(對版本m和版本n比較差別) 注:svn status、svn diff和 svn revert這三條命令在沒有網絡的狀況下也能夠執行的,緣由是svn在本地的.svn中保留了本地版本的原始拷貝。 11:19 評論 / 瀏覽 (0 / 43) 分類:非技術 2011-10-18 縮略顯示 linux下查看內存使用狀況 在Linux下查看內存咱們通常用free命令: [root@scs-2 tmp]# free total used free shared buffers cached Mem: 3266180 3250004 16176 0 110652 2668236 -/+ buffers/cache: 471116 2795064 Swap: 2048276 80160 1968116 下面是對這些數值的解釋: total:總計物理內存的大小。 used:已使用多大。 free:可用有多少。 Shared:多個進程共享的內存總額。 Buffers/cached:磁盤緩存的大小。 第三行(-/+ buffers/cached): used:已使用多大。 free:可用有多少。 第四行就很少解釋了。 區別:第二行(mem)的used/free與第三行(-/+ buffers/cache) used/free的區別。 這兩個的區別在於使用的角度來看,第一行是從OS的角度來看,由於對於OS,buffers/cached 都是屬於被使用,因此他的可用內存是16176KB,已用內存是3250004KB,其中包括,內核(OS)使用+Application(X, oracle,etc)使用的+buffers+cached. 第三行所指的是從應用程序角度來看,對於應用程序來講,buffers/cached 是等於可用的,由於buffer/cached是爲了提升文件讀取的性能,當應用程序需在用到內存的時候,buffer/cached會很快地被回收。 因此從應用程序的角度來講,可用內存=系統free memory+buffers+cached。 如上例: 2795064=16176+110652+2668236 接下來解釋何時內存會被交換,以及按什麼方交換。 當可用內存少於額定值的時候,就會開會進行交換。 如何看額定值: cat /proc/meminfo [root@scs-2 tmp]# cat /proc/meminfo MemTotal: 3266180 kB MemFree: 17456 kB Buffers: 111328 kB Cached: 2664024 kB SwapCached: 0 kB Active: 467236 kB Inactive: 2644928 kB HighTotal: 0 kB HighFree: 0 kB LowTotal: 3266180 kB LowFree: 17456 kB SwapTotal: 2048276 kB SwapFree: 1968116 kB Dirty: 8 kB Writeback: 0 kB Mapped: 345360 kB Slab: 112344 kB Committed_AS: 535292 kB PageTables: 2340 kB VmallocTotal: 536870911 kB VmallocUsed: 272696 kB VmallocChunk: 536598175 kB HugePages_Total: 0 HugePages_Free: 0 Hugepagesize: 2048 kB 用free -m查看的結果: [root@scs-2 tmp]# free -m total used free shared buffers cached Mem: 3189 3173 16 0 107 2605 -/+ buffers/cache: 460 2729 Swap: 2000 78 1921 查看/proc/kcore文件的大小(內存鏡像): [root@scs-2 tmp]# ll -h /proc/kcore -r-------- 1 root root 4.1G Jun 12 12:04 /proc/kcore 備註: 佔用內存的測量 測量一個進程佔用了多少內存,linux爲咱們提供了一個很方便的方法,/proc目錄爲咱們提供了全部的信息,實際上top等工具也經過這裏來獲取相應的信息。 /proc/meminfo 機器的內存使用信息 /proc/pid/maps pid爲進程號,顯示當前進程所佔用的虛擬地址。 /proc/pid/statm 進程所佔用的內存 [root@localhost ~]# cat /proc/self/statm 654 57 44 0 0 334 0 輸出解釋 CPU 以及CPU0。。。的每行的每一個參數意思(以第一行爲例)爲: 參數 解釋 /proc//status Size (pages) 任務虛擬地址空間的大小 VmSize/4 Resident(pages) 應用程序正在使用的物理內存的大小 VmRSS/4 Shared(pages) 共享頁數 0 Trs(pages) 程序所擁有的可執行虛擬內存的大小 VmExe/4 Lrs(pages) 被映像到任務的虛擬內存空間的庫的大小 VmLib/4 Drs(pages) 程序數據段和用戶態的棧的大小 (VmData+ VmStk )4 dt(pages) 04 查看機器可用內存 /proc/28248/>free total used free shared buffers cached Mem: 1023788 926400 97388 0 134668 503688 -/+ buffers/cache: 288044 735744 Swap: 1959920 89608 1870312 咱們經過free命令查看機器空閒內存時,會發現free的值很小。這主要是由於,在linux中有這麼一種思想,內存不用白不用,所以它儘量的cache和buffer一些數據,以方便下次使用。但實際上這些內存也是能夠馬上拿來使用的。 因此 空閒內存=free+buffers+cached=total-used 17:52 評論 / 瀏覽 (0 / 13) 分類:操做系統 2011-08-29 縮略顯示 android 鏡像製做方法 android 一:update.zip包的製做 1:新建一個目標,在此目錄下準備好須要的文件,如system目錄文件、boot.img、recovery.img等. mkdir testupdate cp system/ testupdate/ -tf 注:若是文件是system.img鏡像能夠用unyaffs解壓出來獲得system 2:用make-update-script工具生成update-script腳本,以下 cp make-update-script testupdate/ cp android-info.txt testupdate/ cd testupdate ./make-update-script system android-info.txt > update-script rm make-update-script android-info.txt vi update-script //根據須要適當修改些腳本 說明:system是要更新的目錄,android-info.txt是板的版本信息,update-script是輸出文件名 3:創建一個目錄名稱爲META-INF/com/google/android,把上面生成的腳本放進去 mkdir -p META-INF/com/google/android mv update-script META-INF/com/google/android/ 4:壓縮文件 zip -r update.zip system META-INF 5:給壓縮文件添加簽名 mv update.zip ../signapk/ cd ../signapk/ java -jar signapk.jar testkey.x509.pem testkey.pk8 update.zip signed-update.zip 6:刪除多餘的文件,並把生成的包重命名 rm update.zip mv signed-update.zip ../update.zip cd ../ 7:大功告成,把更新包update.zip拷到sdcard根目錄下去驗證吧! 注意: 1)若是文件裏有鏈接,應該在獲取update-script以後在原文件裏刪除連接文件,再打包,不然symlink將出錯; 2)若是原文件裏有空目錄,所獲的簽名將失去此記錄,因此若是空目錄必須存在,更新以後的文件將與原文件不一樣(少了空目錄) 二:ramdisk.img 製做 方法1: 解壓: 1) mv ramdisk.img ramdisk.img.gz 2) gunzip ramdisk,img.gz 3) mkdir ramdisk;cd ramdisk 4) cpio -i -F ../ramdisk.img 壓縮: 1) 產生要pack的目錄list,也能夠本身列 cpio -i -t -F ../ramdisk.img > list 2) 利用剛生成的list文件列表,cpio歸檔 cpio -o -H newc -O new.img < list 3) gzip new.img 方法2: 解壓: gunzip -c ../your-ramdisk-file | cpio -i 壓縮: find . | cpio -o -H newc | gzip > ../newramdisk.cpio.gz 注意:在android裏的作法是 1)先獲得ramdisk所須要的文件,好比root目錄 2)用mkbootfs製做ramdisk.img,用法以下 mkbootfs root | gzip > ramdisk.img 這裏須要驗證哪一個能用android寫下去 三:boot.img的製做 1:android正常作法 1):鏈接 mkbootimg --kernel your-kernel-file --ramdisk newramdisk.cpio.gz --cmdline "mem=128 console=ttymxc0,115200n8 init=/init rw" --output mynewimage.img 或 mkbootimg --kernel your-kernel-file --ramdisk newramdisk.cpio.gz --cmdline --output mynewimage.img 2):提取img中的kernel和ramdisk ./split_bootimg.pl mynewimage.img 2:uboot 直接把uImage重命名爲boot.img便可 四:system.img的製做(只爲 yaffs2格式) 1)壓制:./mkyaffs2image system/ system.img 2)解壓:./unyaffs system.img 四:system.img的製做(只爲yaffs2格式) 1)壓制:./mkyaffs2image system/ system.img 2)解壓:./unyaffs system.img 五:recovery.img的製做 1:若是recovery的鏡像是隻有文件系統部分時候能夠如第四所示範 2:若是recovery爲ramdisk形式 ============================================= 制 做ramdisk的過程。 1.在/mnt下建立rdmnt 和 rdimg 目錄 mkdir rdmnt mkdir rdimg 2.建立一個ramdisk文件,大小32768 X 1k。 dd if=/dev/zero of=rdimg/ramdisk bs=1k count=32768 3.使用ext2方式格式該文件 mke2fs -F -v -m0 rdimg/ramdisk 4.將該ramdisk文件和rdmnt掛載 mount -o loop rdimg/ramdisk rdmnt/ 5.拷貝文件到掛載目錄中。 文件系統目錄在:/home/xrqun/workdir/filesys/ cp –av /home/xrqun/workdir/filesys/* rdmnt 6.卸載ramdisk umount rdmnt 7壓縮 ramdisk文件 gzip –c -9 <rdimg/ramdisk > rdimg/ramdisk.gz 8.拷貝該ramdisk.gz映像到tftpboot目錄下 cp rdimg/ramdisk.gz /tftpboot/ 9. 使用mkimage工具 mkimage -n "uboot.ramdisk.filesys" -A arm -O linux -T ramdisk -C gzip -d ramdisk.gz uboot.ramdisk.gz 參考:http://liaowb1234.blog.163.com/blog/static/771555472010027104534626/ http://www.cnblogs.com/sdphome/archive/2011/03/20/1989826.html 16:30 評論 / 瀏覽 (0 / 94) 分類:移動開發 2011-08-24 縮略顯示 Eclipse下svn屬性設置 androidframeworks svn_externals: src/android ###/frameworks/base/core/java/android src/com ###/frameworks/base/core/java/com src/com/android/internal/policy ###/frameworks/base/policy/src/com/android/internal/policy src/com/android/server ###/frameworks/base/services/java/com/android/server src/com/android/systemui/statusbar ###/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar src/android/telephony ###/frameworks/base/telephony/java/android/telephony src/com/android/internal/telephony ###/frameworks/base/telephony/java/com/android/internal/telephony src/android/opengl ###/frameworks/base/opengl/java/android/opengl src/javax/microedition/khronos ###/frameworks/base/opengl/java/javax/microedition/khronos src/android/drm ###/frameworks/base/media/java/android/drm src/android/media ###/frameworks/base/media/java/android/media src/android/graphics ###/frameworks/base/graphics/java/android/graphics src/android/renderscript ###/frameworks/base/graphics/java/android/renderscript src/com/android/internal/graphics ###/frameworks/base/graphics/java/com/android/internal/graphics svn_ignore: assets libs build_oms.xml .classpath .project bin 16:52 評論 / 瀏覽 (0 / 83) 分類:移動開發 2011-08-24 縮略顯示 linux/Unix環境下的make和makefile詳解 makelinux腳本 不管是在linux仍是在Unix環境中,make都是一個很是重要的編譯命令。無論是本身進行項目開發仍是安裝應用軟件,咱們都常常要用到make或make install。利用make工具,咱們能夠將大型的開發項目分解成爲多個更易於管理的模塊,對於一個包括幾百個源文件的應用程序,使用make和 makefile工具就能夠簡潔明快地理順各個源文件之間紛繁複雜的相互關係。並且如此多的源文件,若是每次都要鍵入gcc命令進行編譯的話,那對程序員來講簡直就是一場災難。而make工具則可自動完成編譯工做,而且能夠只對程序員在上次編譯後修改過的部分進行編譯。所以,有效的利用make和 makefile工具能夠大大提升項目開發的效率。同時掌握make和makefile以後,您也不會再面對着Linux下的應用軟件手足無措了。 但使人遺憾的是,在許多講述linux應用的書籍上都沒有詳細介紹這個功能強大但又很是複雜的編譯工具。在這裏我就向你們詳細介紹一下make及其描述文件makefile。 Makefile文件 Make工具最主要也是最基本的功能就是經過makefile文件來描述源程序之間的相互關係並自動維護編譯工做。而makefile 文件須要按照某種語法進行編寫,文件中須要說明如何編譯各個源文件並鏈接生成可執行文件,並要求定義源文件之間的依賴關係。makefile 文件是許多編譯器--包括 Windows NT 下的編譯器--維護編譯信息的經常使用方法,只是在集成開發環境中,用戶經過友好的界面修改 makefile 文件而已。 在 UNIX 系統中,習慣使用 Makefile 做爲 makfile 文件。若是要使用其餘文件做爲 makefile,則可利用相似下面的 make 命令選項指定 makefile 文件: $ make -f Makefile.debug 例如,一個名爲prog的程序由三個C源文件filea.c、fileb.c和filec.c以及庫文件LS編譯生成,這三個文件還分別包含本身的頭文件a.h 、b.h和c.h。一般狀況下,C編譯器將會輸出三個目標文件filea.o、fileb.o和filec.o。假設filea.c和fileb.c都要聲明用到一個名爲defs的文件,但filec.c不用。即在filea.c和fileb.c裏都有這樣的聲明: #include "defs" 那麼下面的文檔就描述了這些文件之間的相互聯繫: --------------------------------------------------------- #It is a example for describing makefile prog : filea.o fileb.o filec.o cc filea.o fileb.o filec.o -LS -o prog filea.o : filea.c a.h defs cc -c filea.c fileb.o : fileb.c b.h defs cc -c fileb.c filec.o : filec.c c.h cc -c filec.c ---------------------------------------------------------- 這個描述文檔就是一個簡單的makefile文件。 從上面的例子注意到,第一個字符爲 # 的行爲註釋行。第一個非註釋行指定prog由三個目標文件filea.o、fileb.o和filec.o連接生成。第三行描述瞭如何從prog所依賴的文件創建可執行文件。接下來的四、六、8行分別指定三個目標文件,以及它們所依賴的.c和.h文件以及defs文件。而五、七、9行則指定了如何從目標所依賴的文件創建目標。 當filea.c或a.h文件在編譯以後又被修改,則 make 工具可自動從新編譯filea.o,若是在先後兩次編譯之間,filea.C 和a.h 均沒有被修改,並且 test.o 還存在的話,就沒有必要從新編譯。這種依賴關係在多源文件的程序編譯中尤爲重要。經過這種依賴關係的定義,make 工具可避免許多沒必要要的編譯工做。固然,利用 Shell 腳本也能夠達到自動編譯的效果,可是,Shell 腳本將所有編譯任何源文件,包括哪些沒必要要從新編譯的源文件,而 make 工具則可根據目標上一次編譯的時間和目標所依賴的源文件的更新時間而自動判斷應當編譯哪一個源文件。 Makefile文件做爲一種描述文檔通常須要包含如下內容: ◆ 宏定義 ◆ 源文件之間的相互依賴關係 ◆ 可執行的命令 Makefile中容許使用簡單的宏指代源文件及其相關編譯信息,在linux中也稱宏爲變量。在引用宏時只需在變量前加$符號,但值得注意的是,若是變量名的長度超過一個字符,在引用時就必須加圓括號()。 下面都是有效的宏引用: $(CFLAGS) $2 $Z $(Z) 其中最後兩個引用是徹底一致的。 須要注意的是一些宏的預約義變量,在Unix系統中,$*、$@、$?和$<四個特殊宏的值在執行命令的過程當中會發生相應的變化,而在GNU make中則定義了更多的預約義變量。關於預約義變量的詳細內容, 宏定義的使用能夠使咱們脫離那些冗長乏味的編譯選項,爲編寫makefile文件帶來很大的方便。 --------------------------------------------------------- # Define a macro for the object files OBJECTS= filea.o fileb.o filec.o # Define a macro for the library file LIBES= -LS # use macros rewrite makefile prog: $(OBJECTS) cc $(OBJECTS) $(LIBES) -o prog …… --------------------------------------------------------- 此時若是執行不帶參數的make命令,將鏈接三個目標文件和庫文件LS;可是若是在make命令後帶有新的宏定義: make "LIBES= -LL -LS" 則命令行後面的宏定義將覆蓋makefile文件中的宏定義。若LL也是庫文件,此時make命令將鏈接三個目標文件以及兩個庫文件LS和LL。 在Unix系統中沒有對常量NULL做出明確的定義,所以咱們要定義NULL字符串時要使用下述宏定義: STRINGNAME= Make命令 在make命令後不只能夠出現宏定義,還能夠跟其餘命令行參數,這些參數指定了須要編譯的目標文件。其標準形式爲: target1 [target2 …]:[:][dependent1 …][;commands][#…] [(tab) commands][#…] 方括號中間的部分表示可選項。Targets和dependents當中能夠包含字符、數字、句點和"/"符號。除了引用,commands中不能含有"#",也不容許換行。 在一般的狀況下命令行參數中只含有一個":",此時command序列一般和makefile文件中某些定義文件間依賴關係的描述行有關。若是與目標相關連的那些描述行指定了相關的command序列,那麼就執行這些相關的command命令,即便在分號和(tab)後面的aommand字段甚至有多是NULL。若是那些與目標相關連的行沒有指定command,那麼將調用系統默認的目標文件生成規則。 若是命令行參數中含有兩個冒號"::",則此時的command序列也許會和makefile中全部描述文件依賴關係的行有關。此時將執行那些與目標相關連的描述行所指向的相關命令。同時還將執行build-in規則。 若是在執行command命令時返回了一個非"0"的出錯信號,例如makefile文件中出現了錯誤的目標文件名或者出現了以連字符打頭的命令字符串,make操做通常會就此終止,但若是make後帶有"-i"參數,則make將忽略此類出錯信號。 Make命自己可帶有四種參數:標誌、宏定義、描述文件名和目標文件名。其標準形式爲: Make [flags] [macro definitions] [targets] Unix系統下標誌位flags選項及其含義爲: -f file 指定file文件爲描述文件,若是file參數爲"-"符,那麼描述文件指向標準輸入。若是沒有"-f"參數,則系統將默認當前目錄下名爲 makefile或者名爲Makefile的文件爲描述文件。在linux中, GNU make 工具在當前工做目錄中按照GNUmakefile、makefile、Makefile的順序搜索 makefile文件。 -i 忽略命令執行返回的出錯信息。 -s 沉默模式,在執行以前不輸出相應的命令行信息。 -r 禁止使用build-in規則。 -n 非執行模式,輸出全部執行命令,但並不執行。 -t 更新目標文件。 -q make操做將根據目標文件是否已經更新返回"0"或非"0"的狀態信息。 -p 輸出全部宏定義和目標文件描述。 -d Debug模式,輸出有關文件和檢測時間的詳細信息。 linux下make標誌位的經常使用選項與Unix系統中稍有不一樣,下面咱們只列出了不一樣部分: -c dir 在讀取 makefile 以前改變到指定的目錄dir。 -I dir 當包含其餘 makefile文件時,利用該選項指定搜索目錄。 -h help文擋,顯示全部的make選項。 -w 在處理 makefile 以前和以後,都顯示工做目錄。 經過命令行參數中的target ,可指定make要編譯的目標,而且容許同時定義編譯多個目標,操做時按照從左向右的順序依次編譯target選項中指定的目標文件。若是命令行中沒有指定目標,則系統默認target指向描述文件中第一個目標文件。 一般,makefile 中還定義有 clean 目標,可用來清除編譯過程當中的中間文件,例如: clean: rm -f *.o 運行 make clean 時,將執行 rm -f *.o 命令,最終刪除全部編譯過程當中產生的全部中間文件。 隱含規則 在make 工具中包含有一些內置的或隱含的規則,這些規則定義瞭如何從不一樣的依賴文件創建特定類型的目標。Unix系統一般支持一種基於文件擴展名即文件名後綴的隱含規則。這種後綴規則定義瞭如何將一個具備特定文件名後綴的文件(例如.c文件),轉換成爲具備另外一種文件名後綴的文件(例如.o文件): .c:.o $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< 系統中默認的經常使用文件擴展名及其含義爲: .o 目標文件 .c C源文件 .f FORTRAN源文件 .s 彙編源文件 .y Yacc-C源語法 .l Lex源語法 在早期的Unix系統系統中還支持Yacc-C源語法和Lex源語法。在編譯過程當中,系統會首先在makefile文件中尋找與目標文件相關的.C文件,若是還有與之相依賴的.y和.l文件,則首先將其轉換爲.c文件後再編譯生成相應的.o文件;若是沒有與目標相關的.c文件而只有相關的.y文件,則系統將直接編譯.y文件。 而GNU make 除了支持後綴規則外還支持另外一種類型的隱含規則--模式規則。這種規則更加通用,由於能夠利用模式規則定義更加複雜的依賴性規則。模式規則看起來很是相似於正則規則,但在目標名稱的前面多了一個 % 號,同時可用來定義目標和依賴文件之間的關係,例以下面的模式規則定義瞭如何將任意一個 file.c 文件轉換爲 file.o 文件: %.c:%.o $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< #EXAMPLE# 下面將給出一個較爲全面的示例來對makefile文件和make命令的執行進行進一步的說明,其中make命令不只涉及到了C源文件還包括了Yacc 語法。本例選自"Unix Programmer's Manual 7th Edition, Volume 2A" Page 283-284 下面是描述文件的具體內容: --------------------------------------------------------- #Description file for the Make command #Send to print P=und -3 | opr -r2 #The source files that are needed by object files FILES= Makefile version.c defs main.c donamc.c misc.c file.c dosys.c gram.y lex.c gcos.c #The definitions of object files OBJECTS= vesion.o main.o donamc.o misc.o file.o dosys.o gram.o LIBES= -LS LINT= lnit -p CFLAGS= -O make: $(OBJECTS) cc $(CFLAGS) $(OBJECTS) $(LIBES) -o make size make $(OBJECTS): defs gram.o: lex.c cleanup: -rm *.o gram.c install: @size make /usr/bin/make cp make /usr/bin/make ; rm make #print recently changed files print: $(FILES) pr $? | $P touch print test: make -dp | grep -v TIME>1zap /usr/bin/make -dp | grep -v TIME>2zap diff 1zap 2zap rm 1zap 2zap lint: dosys.c donamc.c file.c main.c misc.c version.c gram.c $(LINT) dosys.c donamc.c file.c main.c misc.c version.c gram.c rm gram.c arch: ar uv /sys/source/s2/make.a $(FILES) ---------------------------------------------------------- 一般在描述文件中應象上面同樣定義要求輸出將要執行的命令。在執行了make命令以後,輸出結果爲: $ make cc -c version.c cc -c main.c cc -c donamc.c cc -c misc.c cc -c file.c cc -c dosys.c yacc gram.y mv y.tab.c gram.c cc -c gram.c cc version.o main.o donamc.o misc.o file.o dosys.o gram.o -LS -o make 13188+3348+3044=19580b=046174b 最後的數字信息是執行"@size make"命令的輸出結果。之因此只有輸出結果而沒有相應的命令行,是由於"@size make"命令以"@"起始,這個符號禁止打印輸出它所在的命令行。 描述文件中的最後幾條命令行在維護編譯信息方面很是有用。其中"print"命令行的做用是打印輸出在執行過上次"make print"命令後全部改動過的文件名稱。系統使用一個名爲print的0字節文件來肯定執行print命令的具體時間,而宏$?則指向那些在print 文件改動過以後進行修改的文件的文件名。若是想要指定執行print命令後,將輸出結果送入某個指定的文件,那麼就可修改P的宏定義: make print "P= cat>zap" 在linux中大多數軟件提供的是源代碼,而不是現成的可執行文件,這就要求用戶根據本身系統的實際狀況和自身的須要來配置、編譯源程序後,軟件才能使用。只有掌握了make工具,才能讓咱們真正享受到到Linux這個自由軟件世界的帶給咱們無窮樂趣。 另外一篇,http://wiki.ubuntu.org.cn/%E8%B7%9F%E6%88%91%E4%B8%80%E8%B5%B7%E5%86%99Makefile 14:35 評論 / 瀏覽 (0 / 55) 分類:移動開發 2011-08-24 縮略顯示 envsetup.sh腳本分析 android腳本 build/envsetup.sh腳本分析 在編譯源代碼以前一般須要在android源代碼頂層目錄執行 . ./build/envsetup.sh 目的是爲了使用 腳本 envsetup.sh 裏面定義了一些函數: function help() function get_abs_build_var() function get_build_var() function check_product() function check_variant() function setpaths() function printconfig() function set_stuff_for_environment() function set_sequence_number() function settitle() function choosetype() function chooseproduct() function choosevariant() function tapas() function choosecombo() function print_lunch_menu() function lunch() function gettop function m() function findmakefile() function mm() function mmm() function croot() function pid() function gdbclient() function jgrep() function cgrep() function resgrep() function getprebuilt function tracedmdump() function runhat() function getbugreports() function startviewserver() function stopviewserver() function isviewserverstarted() function smoketest() function runtest() function runtest_py() function godir () choosecombo 命令分析: function choosecombo() { choosesim $1 echo echo choosetype $2 echo echo chooseproduct $3 echo echo choosevariant $4 echo set_stuff_for_environment printconfig } 會依次進行以下選擇: Build for the simulator or the device? 1. Device 2. Simulator Which would you like? [1] Build type c Build type choices are: 1. release 2. debug Which would you like? [1] Product choices are: 1. emulator 2. generic 3. sim 4. littleton You can also type the name of a product if you know it. Which would you like? [littleton] Variant choices are: 1. user 2. userdebug 3. eng Which would you like? [eng] user 默認選擇之後會出現: TARGET_PRODUCT=littleton TARGET_BUILD_VARIANT=user TARGET_SIMULATOR=false TARGET_BUILD_TYPE=release TARGET_ARCH=arm HOST_ARCH=x86 HOST_OS=linux HOST_BUILD_TYPE=release BUILD_ID= ========== function chooseproduct()函數分析: choices=(`/bin/ls build/target/board/*/BoardConfig.mk vendor/*/*/BoardConfig.mk 2> /dev/null`) 讀取 build/target/board/* 目錄下的板配置文件:BoardConfig.mk 讀取 vendor/*/*/目錄下的板配置文件:BoardConfig.mk choices 的值爲: build/target/board/emulator/BoardConfig.mk build/target/board/generic/BoardConfig.mk build/target/board/sim/BoardConfig.mk vendor/marvell/littleton/BoardConfig.mk 通過: for choice in ${choices[@]} do # The product name is the name of the directory containing # the makefile we found, above. prodlist=(${prodlist[@]} `dirname ${choice} | xargs basename`) done 的處理,prodlist的值爲: emulator generic sim littleton 因此選擇菜單爲: Product choices are: 1. emulator 2. generic 3. sim 4. littleton 若是選擇 4,那麼 TARGET_PRODUCT 被賦值爲: littleton。 board_config_mk := \ $(strip $(wildcard \ $(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)/BoardConfig.mk \ vendor/*/$(TARGET_DEVICE)/BoardConfig.mk \ )) 怎樣添加一個模塊 LOCAL_PATH:= $(call my-dir) #編譯靜態庫 include $(CLEAR_VARS) LOCAL_MODULE = libhellos LOCAL_CFLAGS = $(L_CFLAGS) LOCAL_SRC_FILES = hellos.c LOCAL_C_INCLUDES = $(INCLUDES) LOCAL_SHARED_LIBRARIES := libcutils LOCAL_COPY_HEADERS_TO := libhellos LOCAL_COPY_HEADERS := hellos.h include $(BUILD_STATIC_LIBRARY) #編譯動態庫 include $(CLEAR_VARS) LOCAL_MODULE = libhellod LOCAL_CFLAGS = $(L_CFLAGS) LOCAL_SRC_FILES = hellod.c LOCAL_C_INCLUDES = $(INCLUDES) LOCAL_SHARED_LIBRARIES := libcutils LOCAL_COPY_HEADERS_TO := libhellod LOCAL_COPY_HEADERS := hellod.h include $(BUILD_SHARED_LIBRARY) BUILD_TEST=true ifeq ($(BUILD_TEST),true) #使用靜態庫 include $(CLEAR_VARS) LOCAL_MODULE := hellos LOCAL_STATIC_LIBRARIES := libhellos LOCAL_SHARED_LIBRARIES := LOCAL_LDLIBS += -ldl LOCAL_CFLAGS := $(L_CFLAGS) LOCAL_SRC_FILES := mains.c LOCAL_C_INCLUDES := $(INCLUDES) include $(BUILD_EXECUTABLE) #使用動態庫 include $(CLEAR_VARS) LOCAL_MODULE := hellod LOCAL_MODULE_TAGS := debug LOCAL_SHARED_LIBRARIES := libc libcutils libhellod LOCAL_LDLIBS += -ldl LOCAL_CFLAGS := $(L_CFLAGS) LOCAL_SRC_FILES := maind.c LOCAL_C_INCLUDES := $(INCLUDES) include $(BUILD_EXECUTABLE) endif # ifeq ($(WPA_BUILD_SUPPLICANT),true) ######################## #local_target_dir := $(TARGET_OUT)/etc/wifi #include $(CLEAR_VARS) #LOCAL_MODULE := wpa_supplicant.conf #LOCAL_MODULE_TAGS := user #LOCAL_MODULE_CLASS := ETC #LOCAL_MODULE_PATH := $(local_target_dir) #LOCAL_SRC_FILES := $(LOCAL_MODULE) #include $(BUILD_PREBUILT) ######################## 系統變量解析 LOCAL_MODULE - 編譯的目標對象 LOCAL_SRC_FILES - 編譯的源文件 LOCAL_C_INCLUDES - 須要包含的頭文件目錄 LOCAL_SHARED_LIBRARIES - 連接時須要的外部庫 LOCAL_PRELINK_MODULE - 是否須要prelink處理 BUILD_SHARED_LIBRARY - 指明要編譯成動態庫 LOCAL_PATH - 編譯時的目錄 $(call 目錄,目錄….) 目錄引入操做符 如該目錄下有個文件夾名稱 src,則能夠這樣寫 $(call src),那麼就會獲得 src 目錄的完整路徑 include $(CLEAR_VARS) -清除以前的一些系統變量 CLEAR_VARS:= $(BUILD_SYSTEM)/clear_vars.mk 在 build/core/config.mk 定義 CLEAR_VARS:= $(BUILD_SYSTEM)/clear_vars.mk 經過include 包含自定義的.mk文件(便是自定義編譯規則)或是引用系統其餘的.mk文件(系統定義的編譯規則)。 LOCAL_SRC_FILES - 編譯的源文件 能夠是.c, .cpp, .java, .S(彙編文件)或是.aidl等格式 不一樣的文件用空格隔開。若是編譯目錄子目錄,採用相對路徑,如子目錄/文件名。也能夠經過$(call 目錄),指明編譯某目錄 下全部.c/.cpp/.java/.S/ .aidl文件.追加文件 LOCAL_SRC_FILES += 文件 LOCAL_C_INCLUDES - 須要包含的頭文件目錄 能夠是系統定義路徑,也能夠是相對路徑. 如該編譯目錄下有個include目錄,寫法是include/*.h LOCAL_SHARED_LIBRARIES - 連接時須要的外部共享庫 LOCAL_STATIC_LIBRARIES - 連接時須要的外部外部靜態 LOCAL_JAVA_LIBRARIES 加入jar包 LOCAL_MODULE - 編譯的目標對象 module 是指系統的 native code,一般針對c,c++代碼 ./system/core/sh/Android.mk:32:LOCAL_MODULE:= sh ./system/core/libcutils/Android.mk:71:LOCAL_MODULE := libcutils ./system/core/cpio/Android.mk:9:LOCAL_MODULE := mkbootfs ./system/core/mkbootimg/Android.mk:8:LOCAL_MODULE := mkbootimg ./system/core/toolbox/Android.mk:61:LOCAL_MODULE:= toolbox ./system/core/logcat/Android.mk:10:LOCAL_MODULE:= logcat ./system/core/adb/Android.mk:65:LOCAL_MODULE := adb ./system/core/adb/Android.mk:125:LOCAL_MODULE := adbd ./system/core/init/Android.mk:20:LOCAL_MODULE:= init ./system/core/vold/Android.mk:24:LOCAL_MODULE:= vold ./system/core/mountd/Android.mk:13:LOCAL_MODULE:= mountd LOCAL_PACKAGE_NAME Java 應用程序的名字用該變量定義 ./packages/apps/Music/Android.mk:9:LOCAL_PACKAGE_NAME := Music ./packages/apps/Browser/Android.mk:14:LOCAL_PACKAGE_NAME := Browser ./packages/apps/Settings/Android.mk:8:LOCAL_PACKAGE_NAME := Settings ./packages/apps/Stk/Android.mk:10:LOCAL_PACKAGE_NAME := Stk ./packages/apps/Contacts/Android.mk:10:LOCAL_PACKAGE_NAME := Contacts ./packages/apps/Mms/Android.mk:8:LOCAL_PACKAGE_NAME := Mms ./packages/apps/Camera/Android.mk:8:LOCAL_PACKAGE_NAME := Camera ./packages/apps/Phone/Android.mk:11:LOCAL_PACKAGE_NAME := Phone ./packages/apps/VoiceDialer/Android.mk:8:LOCAL_PACKAGE_NAME := VoiceDialer BUILD_SHARED_LIBRARY - 指明要編譯成動態庫。 編譯的目標,用include 操做符 UILD_STATIC_LIBRARY來指明要編譯成靜態庫。 若是是java文件的話,會用到系統的編譯腳本host_java_library.mk,用BUILD_PACKAGE來指明。三個編譯 ------------------- include $(BUILD_STATIC_LIBRARY) BUILD_STATIC_LIBRARY:= $(BUILD_SYSTEM)/static_library.mk ------------------- include $(BUILD_SHARED_LIBRARY) ./build/core/config.mk:50:BUILD_SHARED_LIBRARY:= $(BUILD_SYSTEM)/shared_library.mk ------------------- include $(BUILD_HOST_SHARED_LIBRARY) BUILD_HOST_SHARED_LIBRARY:= $(BUILD_SYSTEM)/host_shared_library.mk ------------------- include $(BUILD_EXECUTABLE) build/core/config.mk:51:BUILD_EXECUTABLE:= $(BUILD_SYSTEM)/executable.mk ------------------- include $(BUILD_HOST_EXECUTABLE) ./build/core/config.mk:53:BUILD_HOST_EXECUTABLE:= $(BUILD_SYSTEM)/host_executable.mk ------------------- BUILD_HOST_JAVA_LIBRARY:= $(BUILD_SYSTEM)/host_java_library.mk ------------------- BUILD_JAVA_LIBRARY ./build/core/config.mk:58:BUILD_JAVA_LIBRARY:= $(BUILD_SYSTEM)/java_library.mk ------------------ BUILD_STATIC_JAVA_LIBRARY 編譯靜態JAVA庫 ./build/core/config.mk:59:BUILD_STATIC_JAVA_LIBRARY:= $(BUILD_SYSTEM)/static_java_library.mk ------------------ BUILD_HOST_JAVA_LIBRARY 編譯本機用的JAVA庫 ./build/core/config.mk:60:BUILD_HOST_JAVA_LIBRARY:= $(BUILD_SYSTEM)/host_java_library.mk ------------------ BUILD_HOST_STATIC_LIBRARY:= $(BUILD_SYSTEM)/host_static_library.mk BUILD_HOST_SHARED_LIBRARY:= $(BUILD_SYSTEM)/host_shared_library.mk BUILD_STATIC_LIBRARY:= $(BUILD_SYSTEM)/static_library.mk BUILD_RAW_STATIC_LIBRARY := $(BUILD_SYSTEM)/raw_static_library.mk BUILD_SHARED_LIBRARY:= $(BUILD_SYSTEM)/shared_library.mk BUILD_EXECUTABLE:= $(BUILD_SYSTEM)/executable.mk BUILD_RAW_EXECUTABLE:= $(BUILD_SYSTEM)/raw_executable.mk BUILD_HOST_EXECUTABLE:= $(BUILD_SYSTEM)/host_executable.mk BUILD_PACKAGE:= $(BUILD_SYSTEM)/package.mk BUILD_HOST_PREBUILT:= $(BUILD_SYSTEM)/host_prebuilt.mk BUILD_PREBUILT:= $(BUILD_SYSTEM)/prebuilt.mk BUILD_MULTI_PREBUILT:= $(BUILD_SYSTEM)/multi_prebuilt.mk BUILD_JAVA_LIBRARY:= $(BUILD_SYSTEM)/java_library.mk BUILD_STATIC_JAVA_LIBRARY:= $(BUILD_SYSTEM)/static_java_library.mk BUILD_HOST_JAVA_LIBRARY:= $(BUILD_SYSTEM)/host_java_library.mk BUILD_DROIDDOC:= $(BUILD_SYSTEM)/droiddoc.mk BUILD_COPY_HEADERS := $(BUILD_SYSTEM)/copy_headers.mk BUILD_KEY_CHAR_MAP := $(BUILD_SYSTEM)/key_char_map.mk ============ LOCAL_PRELINK_MODULE Prelink利用事先連接代替運行時連接的方法來加速共享庫的加載,它不只能夠加快起動速度,還能夠減小部份內存開銷, 是各類Linux架構上用於減小程序加載時間、縮短系統啓動時間和加快應用程序啓動的很受歡迎的一個工具。程序運行時的 動態連接尤爲是重定位(relocation)的開銷對於大型系統來講是很大的。 動態連接和加載的過程開銷很大,而且在大多數的系統上, 函數庫並不會經常被更動, 每次程序被執行時所進行的連接 動做都是徹底相同的,對於嵌入式系統來講尤爲如此。所以,這一過程能夠改在運行時以前就能夠預先處理好,即花一些時間 利用Prelink工具對動態共享庫和可執行文件進行處理,修改這些二進制文件並加入相應的重定位等信息,節約了原本在程序 啓動時的比較耗時的查詢函數地址等工做,這樣能夠減小程序啓動的時間,同時也減小了內存的耗用。 Prelink的這種作法固然也有代價:每次更新動態共享庫時,相關的可執行文件都須要從新執行一遍Prelink才能保 證有效,由於新的共享庫中的符號信息、地址等極可能與原來的已經不一樣了,這就是爲何 android framework代碼一改動, 這時候就會致使相關的應用程序從新被編譯。 這種代價對於嵌入式系統的開發者來講可能稍微帶來一些複雜度,不過好在對用戶來講幾乎是能夠忽略的。 -------------------- 變量設置爲false那麼將不作prelink操做 LOCAL_PRELINK_MODULE := false 默認是須要prlink的,同時須要在 build/core/prelink-linux-arm.map 中加入 libhellod.so 0x96000000 這個map文件好像是制定動態庫的地址的,在前面註釋上面有一些地址範圍的信息,注意庫與庫之間的間隔數, 若是指定很差的話編譯的時候會提示說地址空間衝突的問題。另外,注意排序,這裏要把數大的放到前面去, 按照大小降序排序。 解析 LOCAL_PRELINK_MODULE 變量 build/core/dynamic_binary.mk:94:ifeq ($(LOCAL_PRELINK_MODULE),true) ifeq ($(LOCAL_PRELINK_MODULE),true) $(prelink_output): $(prelink_input) $(TARGET_PRELINKER_MAP) $(APRIORI) $(transform-to-prelinked) transform-to-prelinked定義: ./build/core/definitions.mk:1002:define transform-to-prelinked define transform-to-prelinked @mkdir -p $(dir $@) @echo "target Prelink: $(PRIVATE_MODULE) ($@)" $(hide) $(APRIORI) \ --prelinkmap $(TARGET_PRELINKER_MAP) \ --locals-only \ --quiet \ $/build/tools/apriori」 參考文檔: 動態庫優化——Prelink(預鏈接)技術 http://www.eefocus.com/article/09-04/71629s.html =============== LOCAL_ARM_MODE := arm 目前Android大部分都是基於Arm處理器的,Arm指令用兩種模式Thumb(每條指令兩個字節)和arm指令(每條指令四個字節) LOCAL_CFLAGS += -O3 -fstrict-aliasing -fprefetch-loop-arrays 經過設定編譯器操做,優化級別,-O0表示沒有優化,-O1爲缺省值,-O3優化級別最高 LOCAL_CFLAGS += -W -Wall LOCAL_CFLAGS += -fPIC -DPIC LOCAL_CFLAGS += -O2 -g -DADB_HOST=1 -Wall -Wno-unused-parameter LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE -DSH_HISTORY LOCAL_CFLAGS += -DUSEOVERLAY2 根據條件選擇相應的編譯參數 ifeq ($(TARGET_ARCH),arm) LOCAL_CFLAGS += -DANDROID_GADGET=1 LOCAL_CFLAGS := $(PV_CFLAGS) endif ifeq ($(TARGET_BUILD_TYPE),release) LOCAL_CFLAGS += -O2 endif LOCAL_LDLIBS := -lpthread LOCAL_LDLIBS += -ldl ifdef USE_MARVELL_MVED LOCAL_WHOLE_STATIC_LIBRARIES += lib_il_mpeg4aspdecmved_wmmx2lnx lib_il_h264decmved_wmmx2lnx LOCAL_SHARED_LIBRARIES += libMrvlMVED else LOCAL_WHOLE_STATIC_LIBRARIES += lib_il_h264dec_wmmx2lnx lib_il_mpeg4aspdec_wmmx2lnx endif ==================== 其餘一些變量和腳本: HOST_JNILIB_SUFFIX LOCAL_MODULE_SUFFIX LOCAL_MODULE_SUFFIX := $(HOST_JNILIB_SUFFIX) HOST_GLOBAL_LDFLAGS TARGET_GLOBAL_LDFLAGS PRIVATE_LDFLAGS LOCAL_LDLIBS LOCAL_C_INCLUDES LOCAL_STATIC_LIBRARIES LOCAL_STATIC_LIBRARIES += codecJPDec_WMMX2LNX miscGen_WMMX2LNX LOCAL_SHARED_LIBRARIES LOCAL_SHARED_LIBRARIES += libMrvlIPP LOCAL_SHARED_LIBRARIES += $(common_SHARED_LIBRARIES) LOCAL_SHARED_LIBRARIES += libMrvlIPP LOCAL_SHARED_LIBRARIES += libdl ifeq ($(TARGET_PRODUCT),littleton) LOCAL_C_INCLUDES += vendor/marvell/littleton/m2d \ LOCAL_SHARED_LIBRARIES += libOmxCore endif vendor/marvell/littleton/littleton.mk:27:PRODUCT_NAME := littleton vendor/marvell/littleton/littleton.mk:28:PRODUCT_DEVICE := littleton vendor/marvell/littleton/AndroidProducts.mk:13: $(LOCAL_DIR)/littleton.mk vendor/sample/products/sample_addon.mk:40:PRODUCT_NAME := sample_addon vendor/htc/dream-open/htc_dream.mk:6:PRODUCT_NAME := htc_dream ./vendor/htc/dream-open/htc_dream.mk:7:PRODUCT_DEVICE := dream-open ./vendor/htc/dream-open/AndroidProducts.mk:3: $(LOCAL_DIR)/htc_dream.mk build/target/product/generic.mk:26:PRODUCT_NAME := generic build/target/product/generic_with_google.mk:20:PRODUCT_NAME := generic_with_google build/target/product/min_dev.mk:6:PRODUCT_NAME := min_dev build/target/product/core.mk:2:PRODUCT_NAME := build/target/product/sim.mk:7:PRODUCT_NAME := sim build/target/product/sdk.mk:37:PRODUCT_NAME := sdk build/tools/buildinfo.sh:20:echo "ro.product.name=$PRODUCT_NAME" lunch sample_addon-eng