Implemented directory walk
This commit is contained in:
61
directory/Walk.go
Normal file
61
directory/Walk.go
Normal file
@ -0,0 +1,61 @@
|
||||
package directory
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const blockSize = 8 << 10
|
||||
|
||||
// Walk calls your callback function for every file name inside the directory.
|
||||
// It doesn't distinguish between files and directories.
|
||||
func Walk(directory string, callBack func(string)) {
|
||||
fd, err := syscall.Open(directory, 0, 0)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
defer syscall.Close(fd)
|
||||
buffer := make([]byte, blockSize)
|
||||
|
||||
for {
|
||||
n, err := syscall.ReadDirent(fd, buffer)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if n <= 0 {
|
||||
break
|
||||
}
|
||||
|
||||
readBuffer := buffer[:n]
|
||||
|
||||
for len(readBuffer) > 0 {
|
||||
dirent := (*syscall.Dirent)(unsafe.Pointer(&readBuffer[0]))
|
||||
readBuffer = readBuffer[dirent.Reclen:]
|
||||
|
||||
// Skip deleted files
|
||||
if dirent.Ino == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
// Skip hidden files
|
||||
if dirent.Name[0] == '.' {
|
||||
continue
|
||||
}
|
||||
|
||||
for i, c := range dirent.Name {
|
||||
if c != 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
bytePointer := (*byte)(unsafe.Pointer(&dirent.Name[0]))
|
||||
name := unsafe.String(bytePointer, i)
|
||||
callBack(name)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user