Skip to content

Instantly share code, notes, and snippets.

@mipearson
Last active August 29, 2015 13:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mipearson/8853521 to your computer and use it in GitHub Desktop.
Save mipearson/8853521 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"io/ioutil"
"os"
"path"
)
func BiggestFile(directory string) (string, error) {
entries, err := ioutil.ReadDir(directory)
if err != nil {
return "", err
}
// The fun thing is, ReadDir returns the FileInfo structs, so we
// don't need to do this. We're just doing so to preserve parity
// with the node.js solution
files := make(chan os.FileInfo, len(entries))
for _, fi := range entries {
go func(fi os.FileInfo) {
file := path.Join(directory, fi.Name())
fi, err = os.Stat(file)
if err != nil {
fmt.Printf("error stat'ing %s: %s\n", file, err)
files <- nil
} else {
files <- fi
}
}(fi)
}
var biggest_filename string
var biggest_size int64
for i := 0; i < len(entries); i++ {
fi := <-files
if fi != nil && fi.Size() > biggest_size {
biggest_filename = fi.Name()
biggest_size = fi.Size()
}
}
return biggest_filename, nil
}
func main() {
if len(os.Args) == 2 {
biggest, err := BiggestFile(os.Args[1])
if err != nil {
panic(err)
}
fmt.Printf("Largest file in %s is %s\n", os.Args[1], biggest)
} else {
fmt.Printf("Expects one argument\n")
}
}
package main
import (
"fmt"
"os"
"path"
"sync"
)
func BiggestFile(directory string) (string, error) {
// In go we'd usually use ioutil.ReadDir, but to keep parity with the
// node solution we'll read only the directory entry names, which takes
// more LOC
dir, err := os.Open(directory)
if err != nil {
return "", err
}
entries, err := dir.Readdirnames(0)
if err != nil {
return "", err
}
var biggest_filename string
var biggest_size int64
var biggest_mutex sync.Mutex
// We'll feed booleans to this channel after each goroutine finishes
done := make(chan bool)
for _, name := range entries {
go func(name string) {
file := path.Join(directory, name)
fi, err := os.Stat(file)
if err != nil {
fmt.Printf("error stat'ing %s: %s\n", file, err)
} else {
// Lock our counters and reset if we've found a bigger file
// We could speed this up by using a RWMutex and read/write locks, but
// that'll take more LOC.
biggest_mutex.Lock()
if fi.Size() > biggest_size {
biggest_filename = fi.Name()
biggest_size = fi.Size()
}
biggest_mutex.Unlock()
}
done <- true
}(name)
}
// Wait for each goroutine to complete
for i := 0; i < len(entries); i++ {
<-done
}
return biggest_filename, nil
}
func main() {
if len(os.Args) == 2 {
biggest, err := BiggestFile(os.Args[1])
if err != nil {
panic(err)
}
fmt.Printf("Largest file in %s is %s\n", os.Args[1], biggest)
} else {
fmt.Printf("Expects one argument\n")
}
}
package main
import (
"fmt"
"io/ioutil"
"os"
"path"
"sync"
)
func BiggestFile(directory string) (string, error) {
entries, err := ioutil.ReadDir(directory)
if err != nil {
return "", err
}
// The fun thing is, ReadDir returns the FileInfo structs, so we
// don't need to do this. We're just doing so to preserve parity
// with the node.js solution
var biggest_filename string
var biggest_size int64
var biggest_mutex sync.Mutex
done := make(chan bool)
for _, fi := range entries {
go func(fi os.FileInfo) {
file := path.Join(directory, fi.Name())
fi, err = os.Stat(file)
if err != nil {
fmt.Printf("error stat'ing %s: %s\n", file, err)
} else {
biggest_mutex.Lock()
if fi.Size() > biggest_size {
biggest_filename = fi.Name()
biggest_size = fi.Size()
}
biggest_mutex.Unlock()
}
done <- true
}(fi)
}
// Wait ..
for i := 0; i < len(entries); i++ {
<-done
}
return biggest_filename, nil
}
func main() {
if len(os.Args) == 2 {
biggest, err := BiggestFile(os.Args[1])
if err != nil {
panic(err)
}
fmt.Printf("Largest file in %s is %s\n", os.Args[1], biggest)
} else {
fmt.Printf("Expects one argument\n")
}
}
package main
import (
"fmt"
"io/ioutil"
"os"
)
func BiggestFile(directory string) (string, error) {
entries, err := ioutil.ReadDir(directory)
if err != nil {
return "", err
}
var biggest_filename string
var biggest_size int64
for _, fi := range entries {
if fi.Size() > biggest_size {
biggest_filename = fi.Name()
biggest_size = fi.Size()
}
}
return biggest_filename, nil
}
func main() {
if len(os.Args) == 2 {
biggest, err := BiggestFile(os.Args[1])
if err != nil {
panic(err)
}
fmt.Printf("Largest file in %s is %s\n", os.Args[1], biggest)
} else {
fmt.Printf("Expects one argument\n")
}
}
@aussiegeek
Copy link

Simple and readable. Have you looked at fmt.Println?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment