golang - fs 패키지 까보기 (1)

임태빈·2022년 12월 25일
0

패키지까보기

목록 보기
1/1

golang 내부 코드를 까보면서 어떻게 동작하는지 공부해보기 위해 작성하게 되었습니다.

// An FS provides access to a hierarchical file system.
//
// The FS interface is the minimum implementation required of the file system.
// A file system may implement additional interfaces,
// such as ReadFileFS, to provide additional or optimized functionality.
type FS interface {
	// Open opens the named file.
	//
	// When Open returns an error, it should be of type *PathError
	// with the Op field set to "open", the Path field set to name,
	// and the Err field describing the problem.
	//
	// Open should reject attempts to open names that do not satisfy
	// ValidPath(name), returning a *PathError with Err set to
	// ErrInvalid or ErrNotExist.
	Open(name string) (File, error)
}

주석을 해석해보니 FS 인터페이스는 파일 시스템에 접근을 제공해주는 것으로 보입니다.

Open이라는 함수는 ValidPath함수를 만족하지 못할 경우, ErrInvaild, ErrNotExist 등을 리턴해줍니다.

// ValidPath reports whether the given path name
// is valid for use in a call to Open.
//
// Path names passed to open are UTF-8-encoded,
// unrooted, slash-separated sequences of path elements, like “x/y/z”.
// Path names must not contain an element that is “.” or “..” or the empty string,
// except for the special case that the root directory is named “.”.
// Paths must not start or end with a slash: “/x” and “x/” are invalid.
//
// Note that paths are slash-separated on all systems, even Windows.
// Paths containing other characters such as backslash and colon
// are accepted as valid, but those characters must never be
// interpreted by an FS implementation as path element separators.
func ValidPath(name string) bool {
	if !utf8.ValidString(name) {
		return false
	}

	if name == "." {
		// special case
		return true
	}

	// Iterate over elements in name, checking each.
	for {
		i := 0
		for i < len(name) && name[i] != '/' {
			i++
		}
		elem := name[:i]
		if elem == "" || elem == "." || elem == ".." {
			return false
		}
		if i == len(name) {
			return true // reached clean ending
		}
		name = name[i+1:]
	}
}

ValidPath는 주어진 경로가 Open할 수 있는지에 대해 식별해줍니다.
Path는 utf-8로 인코딩 되어 있어야 하며 slash기반으로 경로를 구분해주어야 합니다.
또한, .은 기준이 되는 루트 폴더에만 붙일 수 있고 slash는 처음과 끝에 붙으면 안됩니다.
아래 테스트 코드를 보시면 이해할 수 있습니다.

// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package fs_test

import (
	. "io/fs"
	"testing"
)

var isValidPathTests = []struct {
	name string
	ok   bool
}{
	{".", true},
	{"x", true},
	{"x/y", true},

	{"", false},
	{"..", false},
	{"/", false},
	{"x/", false},
	{"/x", false},
	{"x/y/", false},
	{"/x/y", false},
	{"./", false},
	{"./x", false},
	{"x/.", false},
	{"x/./y", false},
	{"../", false},
	{"../x", false},
	{"x/..", false},
	{"x/../y", false},
	{"x//y", false},
	{`x\`, true},
	{`x\y`, true},
	{`x:y`, true},
	{`\x`, true},
}

func TestValidPath(t *testing.T) {
	for _, tt := range isValidPathTests {
		ok := ValidPath(tt.name)
		if ok != tt.ok {
			t.Errorf("ValidPath(%q) = %v, want %v", tt.name, ok, tt.ok)
		}
	}
}
profile
golang과 서버 개발을 하고 있는 개발자입니다.

0개의 댓글