Skip to content

Instantly share code, notes, and snippets.

@clarkmcc
Created March 16, 2021 18:43
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save clarkmcc/1fdab4472283bb68464d066d6b4169bc to your computer and use it in GitHub Desktop.
Save clarkmcc/1fdab4472283bb68464d066d6b4169bc to your computer and use it in GitHub Desktop.
Get all filenames inside an Golang embedded filesystem.
func getAllFilenames(fs *embed.FS, path string) (out []string, err error) {
if len(path) == 0 {
path = "."
}
entries, err := fs.ReadDir(path)
if err != nil {
return nil, err
}
for _, entry := range entries {
fp := filepath.Join(path, entry.Name())
if entry.IsDir() {
res, err := getAllFilenames(fs, fp)
if err != nil {
return nil, err
}
out = append(out, res...)
continue
}
out = append(out, fp)
}
return
}
@frederikhors
Copy link

The above code has problems on Windows.

Use this instead (note import path and not filepath):

func getAllFilenames(fs *embed.FS, dir string) (out []string, err error) {
	if len(dir) == 0 {
		dir = "."
	}

	entries, err := fs.ReadDir(dir)
	if err != nil {
		return nil, err
	}

	for _, entry := range entries {
		fp := path.Join(dir, entry.Name())
		if entry.IsDir() {
			res, err := getAllFilenames(fs, fp)
			if err != nil {
				return nil, err
			}

			out = append(out, res...)

			continue
		}

		out = append(out, fp)
	}

	return
}

@mrsoftware
Copy link

or you can simply use io/fs fs.WalkDir

func getAllFilenames(efs *embed.FS) (files []string, err error) {
	if err := fs.WalkDir(efs, ".", func(path string, d fs.DirEntry, err error) error {
		if d.IsDir() {
			return nil
		}
 
		files = append(files, path)

		return nil
	}); err != nil {
		return nil, err
	}

	return files, nil
}

@surdaft
Copy link

surdaft commented Feb 16, 2023

or you can simply use io/fs fs.WalkDir

func getAllFilenames(efs *embed.FS) (files []string, err error) {
	if err := fs.WalkDir(efs, ".", func(path string, d fs.DirEntry, err error) error {
		if d.IsDir() {
			return nil
		}
 
		files = append(files, path)

		return nil
	}); err != nil {
		return nil, err
	}

	return files, nil
}

This worked wonderfully, thanks for the tip! :)

@mbana
Copy link

mbana commented Jun 9, 2023

or you can simply use io/fs fs.WalkDir

func getAllFilenames(efs *embed.FS) (files []string, err error) {
	if err := fs.WalkDir(efs, ".", func(path string, d fs.DirEntry, err error) error {
		if d.IsDir() {
			return nil
		}
 
		files = append(files, path)

		return nil
	}); err != nil {
		return nil, err
	}

	return files, nil
}

Ditto. Worked as well. Thanks.

@eliofery
Copy link

eliofery commented Dec 9, 2023

Good job guys.

Modified your solution to suit my needs.
Maybe it will be just as useful for someone.

// example:
// efs - //go:embed all:views
// pathFiles - "views/parts"
func getAllFilenames(efs embed.FS, pathFiles string) ([]string, error) {
    files, err := fs.ReadDir(efs, pathFiles)
    if err != nil {
        return nil, err
    }

    // only file name
    // 1131 0001-01-01 00:00:00 foo.gohtml -> foo.gohtml
    arr := make([]string, 0, len(files))
    for _, file := range files {
        arr = append(arr, file.Name())
    }

    return arr, nil
}

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