有关golang的介绍请参考我的另一篇博文.
本文通过递归遍历src目录, 统计代码行数. 涉及到的知识点有:
1. 目录遍历.
2. 读取文件.
3. 使用channel进行goroutine间的通信.
4. 使用sync包进行传统的共享内存方式的同步.
5. 错误处理.
6. defer语句的使用.
在程序中有详细的注释:
// a simple go program for computing total line of souce files stored in one dir
package main
import (
"fmt"
"bufio"
"os"
"sync"
"strings"
)
var (
linesum int
mutex *sync.Mutex = new(sync.Mutex)
)
var (
// the dir where souce file stored
rootPath string = "/home/xing/Dropbox/source/go/src"
// exclude these sub dirs
nodirs [5]string = [...]string{"/bitbucket.org", "/github.com", "/goplayer", "/uniqush", "/code.google.com"}
// the suffix name you care
suffixname string = ".go"
)
func main() {
argsLen := len(os.Args)
if argsLen == 2 {
rootPath = os.Args[1]
} else if argsLen == 3 {
rootPath = os.Args[1]
suffixname = os.Args[2]
}
// sync chan using for waiting
done := make(chan bool)
go codeLineSum(rootPath, done)
<-done
fmt.Println("total line:", linesum)
}
// compute souce file line number
func codeLineSum(root string, done chan bool) {
var goes int // children goroutines number
godone := make(chan bool) // sync chan using for waiting all his children goroutines finished
isDstDir := checkDir(root)
defer func() {
if pan := recover(); pan != nil {
fmt.Printf("root: %s, panic:%#v\n", root, pan)
}
// waiting for his children done
for i := 0; i < goes; i++ {
<-godone
}
// this goroutine done, notify his parent
done <- true
}()
if !isDstDir {
return
}
rootfi, err := os.Lstat(root)
checkerr(err)
rootdir, err := os.Open(root)
checkerr(err)
defer rootdir.Close()
if rootfi.IsDir() {
fis, err := rootdir.Readdir(0)
checkerr(err)
for _, fi := range fis {
if strings.HasPrefix(fi.Name(), ".") {
continue
}
goes++
if fi.IsDir() {
go codeLineSum(root+"/"+fi.Name(), godone)
} else {
go readfile(root+"/"+fi.Name(), godone)
}
}
} else {
goes = 1 // if rootfi is a file, current goroutine has only one child
go readfile(root, godone)
}
}
func readfile(filename string, done chan bool) {
var line int
isDstFile := strings.HasSuffix(filename, suffixname)
defer func() {
if pan := recover(); pan != nil {
fmt.Printf("filename: %s, panic:%#v\n", filename, pan)
}
if isDstFile {
addLineNum(line)
fmt.Printf("file %s complete, line = %d\n", filename, line)
}
// this goroutine done, notify his parent
done <- true
}()
if !isDstFile {
return
}
file, err := os.Open(filename)
checkerr(err)
defer file.Close()
reader := bufio.NewReader(file)
for {
_, isPrefix, err := reader.ReadLine()
if err != nil {
break
}
if !isPrefix {
line++
}
}
}
// check whether this dir is the dest dir
func checkDir(dirpath string) bool {
// 判断该文件夹是否在被排除的范围之内
for _, dir := range nodirs {
if rootPath+dir == dirpath {
return false
}
}
return true
}
func addLineNum(num int) {
// 获取锁
mutex.Lock()
// defer语句在函数返回时调用, 确保锁被释放
defer mutex.Unlock()
linesum += num
}
// if error happened, throw a panic, and the panic will be recover in defer function
func checkerr(err error) {
if err != nil {
// 在发生错误时调用panic, 程序将立即停止正常执行, 开始沿调用栈往上抛, 直到遇到recover
// 对于java程序员, 可以将panic类比为exception, 而recover则是try...catch
panic(err.Error())
}
}
分享到:
相关推荐
用于统计软件工程源代码行数,可对指定的子目录下或整个目录树中 所有指定类型的源代码文件进行行数统计。 统计结果包含源代码中的注释行和空行,因为作者认为它们同样也 是源代码的必要组成部分。 对 Windows 下...
-------------------------------------------------- -----------------------------语言文件空白注释代码---------------- -------------------------------------------------- -------------降价3 8
一款基于GO语言,支持跨平台,可以统计项目代码行数的软件(命令行软件,无界面),支持多种自定义过滤。 主要用于代码安全审计服务相关的费用评估。 Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的...
`scounter`是一款简洁而强大的工具,它能够快速地对源代码进行统计,提供诸如代码行数、注释行数、空行数等关键信息。对于开发者来说,这些数据有助于量化项目的工作量,追踪代码的增长趋势,以及在团队中实施代码...
2. 简洁:代码行数较少,编写和理解起来更为直接。 3. 清晰:拥有良好的类型系统和内存管理机制,提供垃圾回收功能。 4. 有效率:编译成高效的机器码,执行速度快。 5. 并行机制:Go语言内置了goroutine并发模型,可...
# 统计测试以外的golang 代码行数和单词数 find . -name "*.go" -exec wc {} \; |grep -v "_test" |sort -u |awk -F" " '{a+=$1;b+=$2}END{print a, b}' 得到v0.1.0版本中golang代码4499 15630, v1.0.0中增长到...
release: on 27 Aug 2016代码行数统计:4483(含测试代码:2006行)原始结构:-> % tree ./macaron-1.1.8 -L 2./macaron-1.1.8├── README.md├── context.go├── context_test.go├── fixtures│ ├── ...
《通过Go语言重现实用工具:golang-cat项目解析》 在编程学习的过程中,实践是检验理论知识的...在实际操作中,你可以逐步完善项目,添加更多功能,如追加模式、忽略空行、统计行数等,从而更深入地探索Go语言的魅力。
它可以分析代码中的测试坏味,错误分析,行数统计,分析调用与依赖,Git分析以及自动化重构等。 迁移指南(中文版):《》 灵感来源: 和蚁人行:重构建模: 语言支持 Java(全部功能) Golang(支持:分析,待办...
- **插入/更新/删除**:使用`db.Exec()`方法执行INSERT, UPDATE, DELETE等语句,它返回一个`sql.Result`,你可以从中获取影响的行数和自增ID。 3. **参数化查询** 避免SQL注入,推荐使用参数化查询,Go通过占位符...