1. 程式人生 > >Java程式設計師的日常——經驗貼(純乾貨)

Java程式設計師的日常——經驗貼(純乾貨)

工作當中遇到的事情比較雜,因此涉及的知識點也很多。這裡暫且記錄一下,今天遇到的知識點,純乾貨~

關於檔案的解壓和壓縮

如果你的系統不支援tar -z命令

如果是古老的Unix系統,可能並不認識tar -z命令,因此如果你想要壓縮或者解壓tar.gz的檔案,就需要使用gzip或者gunzip以及tar命令了。

關於tar.gz可以這麼理解,tar結尾的壓縮包,其實只負責把檔案打包,並沒有進行壓縮;而gz結尾的包,則是進行壓縮操作。

因此,tar.gz的檔案可以理解為,先進行打包,再進行壓縮。

那麼,壓縮的命令就可以這樣寫:

tar -cvf abc.tar abc
gzip -c abc.tar > abc.tar.gz

最終就會得出一個abc.tar.gz的檔案。同理如果想要進行解壓,可以這樣:

gunzip abc.tar.gz
=>該命令會首先得出一個abc.tar的檔案

tar -xvf abc.tar
=>該命令完成解壓的步驟

執行完這兩個命令,當前資料夾就會出現一個abc的檔案夾了。

如果你的系統支援tar -z命令

如果你的系統級別高一點,就不用這麼費事了,tar命令直接可以對gz進行操作:

tar -zxvf 壓縮檔名.tar.gz
=>這個命令可以直接完成對壓縮檔案的解壓

tar -zcvf 壓縮檔名.tar.gz 被壓縮檔名
=>這個命令可以直接完成對tar.gz的壓縮

檔案控制代碼佔用導致應用崩潰

在Java中如果執行過多的流操作或者開啟過多未關閉的Socket,並且沒有及時的關閉,就可能會出現too many open files的錯誤。這就是因為系統的檔案控制代碼數不夠了....

在linux中可以使用命令檢視檔案控制代碼數:

ulimit -n

也可以使用這個命令,進行修改:

ulimit -n 2048

但是修改這裡,是暫時的解決辦法,如果長時間不釋放檔案控制代碼,仍然會報錯。

所以還是應該回到程式中,檢查流操作:

BufferedReader in = null;
try{
    in = new BufferedReader(new FileReader(file));
    //你的業務邏輯
}catch(Exception e){
}finally{
    if(in != null){
        try{
            in.close();//及時的進行釋放
        }catch(Exception e){
        }
    }
}

如果是一些可以複用的流,還可以把它提取出來多次使用。

Linux系統下的亂碼問題

亂碼問題經常困擾著程式設計師的日常開發,關於編碼的問題就不詳細說了。有一個經常遇到的問題就是,我們開發好的一個應用,放在Linux下就會出現亂碼,仔細檢查每個編碼的配置,都是utf-8,簡直是百思不得其解。

其實這是JVM的問題,因為JVM預設會按照系統的編碼來執行,如果JVM的編碼不對,內部進行的檔案處理當然也就會出現亂碼。

首先檢視系統的預設編碼:

# locale
LANG=
LC_CTYPE="C"
LC_COLLATE="C"
LC_MONETARY="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_MESSAGES="C"
LC_ALL=

很多系統的編碼都是這個C,C是系統預設的Locale,預設由ANSI C來支援。也就是說預設的編碼是ANSI C!

這樣,它與我們的UTF-8肯定是不一致了。因此,可以這樣:

java -Dfile.encoding=UTF-8 xxxx

通過新增上面的引數來指定JVM使用的編碼。如果你是在tomcat中啟動的可以修改其中的java相關的引數;如果是其他的程式,那麼就依啟動時的jvm引數為準,修改對應的啟動命令即可。

使用javac以及java執行class

這個算是基礎知識了,但是一般的開發者可能只是用它試驗過helloworld。比如:

javac HelloWorld.java
=>編譯出HelloWorld.class
java HelloWorld
=>執行該類

實際情況中可能遠比這個複雜:

如何啟動eclipse中編譯出來的jar包

通過Eclipse進行打包,比較簡單:

  • 右鍵工程名字-Export
  • 選擇Jar File
  • 選擇指定的工程、以及編譯出的jar包所在的目錄
  • 點選finish進行打包即可

這個時候,如果你直接執行java -jar xxx.jar,可能會丟擲一個異常:

java -jar target.jar
fileMonitor.jar中沒有主清單屬性

這是因為這個jar中缺少了Main方法的定義。此時你可以這麼做,通過解壓工具進入到jar包中,修改META-INF下的MENIFEST.MF檔案。

Manifest-Version: 1.0
Main-Class: com.test.類名

注意Main-Class後面的冒號後面要有空格、並且最後一行要空著(如果沒有最後一行的的回車,就會報找不到Main-Class這個屬性的錯誤)。

如果你使用Javac以及java編譯類

如果你有一個類,這個類依賴於其他的jar包,比如:test.java依賴a.jar、b.jar。
那麼可以執行javac進行編譯:

javac -cp a.jar;b.jar test.java
=>注意如果是Linux,分號要換成冒號
javac -cp a.jar:b.jar test.java

然後使用java執行:

java -cp .;a.jar;b.jar test
=>如果是linux,分號換成冒號
java -cp .:a.jar:b.jar test

編寫shell指令碼

經常有人會編寫一些類似tomcat一鍵啟動的指令碼,這裡以linux為例:

#!/bin/sh
PRG="$0"
PRGDIR=`dirname "$PRG"`

[ -z "$ROOT_PATH" ] && ROOT_PATH=`cd "$PRGDIR/.." >/dev/null; pwd`
echo "設定 ROOT_PATH為 $ROOT_PATH"

[ -z "$JRE_HOME" ] && JRE_HOME=`cd "$ROOT_PATH/jre" >/dev/null; pwd`
echo "設定 JRE_HOME 為 $JRE_HOME"

"$JRE_HOME"/bin/java -Dfile.encoding=UTF-8 -jar "$AGENT_PATH"/lib/test.jar

有幾個可以值得借鑑的地方:

  • 第一點,就是如何設定環境變數,比如使用內建的jre

    PRG="$0"
    PRGDIR=`dirname "$PRG"`
    這兩句話是為了獲取啟動指令碼所在的目錄。
    [ -z "$ROOT_PATH" ] && ROOT_PATH=`cd "$PRGDIR/.." >/dev/null; pwd`
    這句話是設定了該啟動指令碼所處的應用的根目錄
    [ -z "$JRE_HOME" ] && JRE_HOME=`cd "$ROOT_PATH/lib/jre" >/dev/null; pwd`
    這句話是最終設定環境變數的命令。粗俗JRE_HOME就指定為應用內建的jre了。
  • 第二點,是如何啟動我們自己的類

    "$JRE_HOME"/bin/java -Dfile.encoding=UTF-8 -jar "$AGENT_PATH"/lib/test.jar

    上面這命令,是執行內建的jre中的java命令,使用java命令啟動了一個可執行的jar包,並且設定好了它的編碼。

Java學習交流QQ群:523047986  禁止閒聊,非喜勿進!