Go语言初尝


        对于语言设计之争, 唯一需要牢记的一句话是: 如果把 C 变成 C++, 那么 C 就消失了。


        Go 是一个轻量级的简洁的支持并发的语言,  可以用于探索性个人项目, 这是我想学这门语言的主要原因。 对于有一定编程经验的人来说, 学习一种新语言的方式是, 先概览下语言特性, 然后编写一个中等规模的程序, 尽可能地运用到大部分重要特性。 


        下面的程序用于计算一个目录下所有文件或目录的大小。  

       

package main

import (
  "fmt"
  "time"
  "os" 
  "log"
)

type ShortFileInfo struct {
	fileName string
	size     int64
}

func (fileInfo *ShortFileInfo) Desc() string {
   return fmt.Sprintf("{%s:%d}", fileInfo.fileName, fileInfo.size)
}

func produceFiles(dirName string) []os.FileInfo {
    path, err := os.Open(dirName)
    if err != nil {
        log.Fatal(err)
    }
    defer path.Close()
	fileInfos, err := path.Readdir(0);
	if err != nil {
	    log.Fatal(err)
	}
    return fileInfos;
}

func procFile(fileInfo os.FileInfo, baseDirName string, channelBuffer chan ShortFileInfo) {
	var filesize int64
	fileName := fileInfo.Name()
	if fileInfo.IsDir() {
		filesize = totalFilesizeInDir(fileInfo, baseDirName)
	} else {
		filesize = fileInfo.Size()    
	}
    shortFileInfo := ShortFileInfo{fileName, filesize};
	fmt.Println(time.Now().String() + " store: " + shortFileInfo.Desc())
    channelBuffer <- shortFileInfo 
}

func totalFilesizeInDir(fileInfo os.FileInfo, baseDirName string) int64 {
	var filesize int64 = 0
	fileInfos := produceFiles(baseDirName + "\\" + fileInfo.Name())
	for _, subfileInfo := range fileInfos {
		if subfileInfo.IsDir() {
			filesize += totalFilesizeInDir(subfileInfo, baseDirName + "\\" + fileInfo.Name())
		} else {
			filesize += subfileInfo.Size()
		}
	}	
	return filesize
}

func sleep(ns int) {
	time.Sleep(time.Duration(time.Second)*time.Duration(ns))
}

const (
	B int64 = 1
	KB int64 = 1024
	MB int64 = 1024*1024
	GB int64 = 1024*1024*1024
	TB int64 = 1024*1024*1024*1024
)

const formatF string = "%8.4f" 

func readableSize(sizeInBytes int64) string {
	switch {
		case B <= sizeInBytes && sizeInBytes < KB:
			return fmt.Sprintf("%dB", sizeInBytes)
		case KB <= sizeInBytes && sizeInBytes < MB:
			return fmt.Sprintf(formatF+"KB", float64(sizeInBytes)/float64(KB))
		case MB <= sizeInBytes && sizeInBytes < GB:
			return fmt.Sprintf(formatF+"MB", float64(sizeInBytes)/float64(MB))
		case GB <= sizeInBytes && sizeInBytes < TB:
			return fmt.Sprintf(formatF+"GB", float64(sizeInBytes)/float64(GB))
		case TB <= sizeInBytes:
			return fmt.Sprintf(formatF+"TB", float64(sizeInBytes)/float64(TB))
		default:
			return "0"
	}
}

func main() {

    baseDirName := "C:\\Users\\qin.shuq\\Desktop"
    
    fileList := produceFiles(baseDirName)
    fileNumber := len(fileList)
    channelBuffer := make(chan ShortFileInfo, fileNumber)
    fileInfoMap := make(map[string] int64, fileNumber)
	
    for _, fileInfo := range fileList {
        go procFile(fileInfo, baseDirName, channelBuffer)   
    }  
	
	for count := 0 ; count <= fileNumber ; {
		select {
			case fileInfo := <- channelBuffer: 
				fmt.Println(time.Now().String() + " fetch: " + fileInfo.Desc())
				fileInfoMap[fileInfo.fileName] = fileInfo.size
				count++
			default:
				if count == fileNumber {
					close(channelBuffer)
				}
				fmt.Println("Waiting for data ...")	
				sleep(2)	
		}
	}
	
	var totalSize int64 
	totalSize = 0
	for _ , filesize := range fileInfoMap {
		totalSize += filesize
	}
	fmt.Printf("Total size in %s:%dB %s", baseDirName , totalSize, readableSize(totalSize));

} 


               

你可能感兴趣的:(编程,go语言)