包的創建方式:
main 包 是應用程序的入口包, 其他的包不能使用
另外: 包內也可以嵌套定義包,
訪問不同包下的函數需要導入包, 訪問同一個包下不同文件的函數,不需要導入包。
點操作:
包名前加上. 那麼可以不用寫具體包名。
import .“fmt”
Println() 代替了 fmt.println()
但還是別這樣用 ,當代碼量大了,那麼就會引起不必要的誤會
包 起別名:
import p1 "package1" 那麼p1就是package1的別名
導入 別的包下的模塊的使用
Init 函數
Go文件中的init函數沒有參數、沒有返回值, 在main函數執行之前進行初始化。
如果一個Go文件中存在多個init函數, 那麼將會按照定義的順序執行初始化。
如果一個 package 下有多個go文件,而每個go文件中都有各自的init 函數 那麼init函數的初始化執行順序: 將所有go文件按照字符串 進行排序, 按照排序的的順序執行init函數。
對於不同包: 如果存在多級依賴 :
則安照,遞歸的思想來處理init(package)
導入包 不能形成循環以來 ,否則 程序就無限遞歸下去了。
一個包可以被導入多次,但 init()函數只執行一次。
使用 包的注意事項
如果只是爲了使用 包中的 init函數 , 那麼只需要 在導入包名時 :在包名前 用 _ 導入這個包
今天發現Goland 的功能還挺強的 : 可以模擬虛擬機的使用, 用命令進行調試 和運行程序
看圖片 下方: 我是不是在命令行進行運行程序啦? 挺美好的吧。
time 包
go 語言提供一個 強大的 go語言包, 可以實現各種函數調用
僅僅時間就具體道 皮秒 納秒等 。
go語言的彩蛋: t1.Format(2006/1/2 15:04:05) 這個彩蛋 ,別的時間設置都是錯誤的, 據說是爲了紀念Go語言的誕生時間。
time 包下提供各種強大的api ,需要注意的時 ,如果要Add Sub時間: 就需要轉爲time.duration(int) * Minute/Second 等才能使用
os 包 :大多是關於文件的API
os.Mkdir() 創建文件夾
os.MkdirAll () 遞歸創建文件夾
返回值有兩個 ,一個是文件路徑, 一個是錯誤類型
//Create 創建文件
package main
import (
"fmt"
"os"
)
func main(){
//創建絕對路徑文件
//os.Create 文件不存在時 會創建文件, 文件存在時 會將其截斷(置空)
file1,err := os.Create("/Users/mac/go/file_test/1.txt")
if err != nil{
fmt.Println(err)
}
fmt.Println(file1)// 打印地址
//創建絕對路徑下的文件
FileName2 := "2.txt"
file2, err:= os.Create(FileName2)
if err != nil{
fmt.Println(err)
}
fmt.Println(file2)
}
FileName3 := "aa.txt"
file3,err := os.Open(FileName3)// Open 只讀方式打開文件
if err != nil{
fmt.Println(err)
}
fmt.Println(file3)
//os.ModePerm 默認是 0777
//目標文件, 打開方式, 目標文件不存在時創建文件的權限
file4 ,err := os.OpenFile(FileName3, os.O_RDWR, os.ModePerm)
if err != nil{
fmt.Println(err)
return
}
fmt.Println(file4)
//關閉文件
file4.Close()
//刪除文件
//os.Remove(" dest file's absolute path")
err1 :=os.Remove("/Users/mac/go/file_test/1.txt")
if err1 != nil{
fmt.Println(err1)
}
fmt.Println("刪除目錄成功")
//Remove 刪除目錄的前提是 : 該目錄必須是一個空目錄纔可以刪除
//RemoveALl() 遞歸刪除一個目錄下的所有文件和子目錄
err2 := os.RemoveAll(" dest path")
if err2 != nil{
fmt.Println(err2)
}
fmt.Println(err2)
I/O 包
Reader接口 :
1 : os包下的 File 類實現了Read方法
2 IO 包下的 Reader 接口
FileName4 := "path"
file, err :=os.Open(FileName4) //Read 方式打開文件
if err != nil{
fmt.Println(err)
}
//關閉文件
defer file.Close()
DS := make([]byte,4,4)// 用切片接收數據
n ,err := file.Read(DS) // n: 讀取到的長度
if err != nil{
fmt.Println(err)
}
fmt.Println(n)// 打印讀取的數據
fmt.Println(string(DS))
//如果數據讀完了|| 或者文件爲空: 那麼 err == io.EOF n==0
io包下的 read 方法有多種:
//寫入數據 : 每次 會從文件的開頭寫入, 如果文件中已有數據,新寫入的將會覆蓋原有的數據
//想要追加寫的話 需要在打開文件描述苻的時候指定 os.O_APPEND
FileName5 := "path5"
file, err = os.OpenFile(FileName5, os.O_RDWR|os.O_APPEND, os.ModePerm)
if err != nil{
fmt.Println(err)
}
//否則 ,打開文件成功
bs :=[]byte{'A','B','C','D'}
//將切片文件寫入
n,err3 := file.Write(bs)
if err3 != nil{
fmt.Println(err3)
}
fmt.Println("寫入了",n,"個字節數據")
//寫出數據的一部分:
file.Write(bs[:3])//寫入切片中的前三個
//直接寫出字符串
n2,err :=file.WriteString("hello world")
println(n2," ",err)
n3, err :=file.Write([]byte("today"))//可以將 字符牀做成一個切片
println(n3," ",err)
複製文件:
原理: 就是 讀取一個文件 ,然後寫入到另外一個文件中。 緩衝區我們使用切片
還可以使用 io提供的API
n, err := io.Copy(destFile, srcFile) // 結束err返回值爲nil
值得注意的是 每個文件句柄都是需要判斷文件是否打開成功。
ReadFile(filename string) ([]byte, error) 結束的時候 ,返回值error ==nil
下邊是複製文件的兩種方式 : 還有一種手動複製的,我就不實現了。
最簡單的一種 : 我們自己手動實現一個 文件複製
第一種: io.Copy(dest, src)
第二種: ioutil.ReadFile() + ioutil.WriteFile() //底層用切片模擬緩存 ,一次性將文件複製到緩存中, 然後進行復制。因此:不建議大文件使用
func CopyFile1(srcFile,destFile string)(int64,error){
file1,err := os.Open(srcFile)
if err != nil{
return 0, err
}
//否則打開srcFile文件成功
file2,err := os.OpenFile(destFile,os.O_WRONLY|os.O_CREATE|os.O_APPEND,os.ModePerm )
if err != nil{
return 0,err
}
defer file2.Close()
defer file1.Close()
return io.Copy(file2,file1)
}
func CopyFile2(srcFile, destFile string)(int, error){
//打開文件
//內存(棧)中會自動建立一個緩衝區 ; 因此不適合較大文件的複製
bs,err := ioutil.ReadFile(srcFile)
if err != nil{
fmt.Println(err)
return 0,err
}
err = ioutil.WriteFile(destFile,bs,os.ModePerm)//或者寫成0777一樣的
if err != nil{
return 0, err
}
return len(bs),nil
}
另外IO包下還提供CopyN 和 CopyBuffer