github.com/unigraph-dev/dgraph@v1.1.1-0.20200923154953-8b52b426f765/x/file.go (about)

     1  /*
     2   * Copyright 2017-2018 Dgraph Labs, Inc. and Contributors
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package x
    18  
    19  import (
    20  	"io"
    21  	"os"
    22  	"path/filepath"
    23  	"strings"
    24  
    25  	"github.com/dgraph-io/dgo/x"
    26  	"github.com/golang/glog"
    27  )
    28  
    29  // WriteFileSync is the same as bufio.WriteFile, but syncs the data before closing.
    30  func WriteFileSync(filename string, data []byte, perm os.FileMode) error {
    31  	f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
    32  	if err != nil {
    33  		return err
    34  	}
    35  	if _, err := f.Write(data); err != nil {
    36  		return err
    37  	}
    38  	if err := f.Sync(); err != nil {
    39  		return err
    40  	}
    41  	return f.Close()
    42  }
    43  
    44  // WalkPathFunc walks the directory 'dir' and collects all path names matched by
    45  // func f. If the path is a directory, it will set the bool argument to true.
    46  // Returns empty string slice if nothing found, otherwise returns all matched path names.
    47  func WalkPathFunc(dir string, f func(string, bool) bool) []string {
    48  	var list []string
    49  	err := filepath.Walk(dir, func(path string, fi os.FileInfo, err error) error {
    50  		if err != nil {
    51  			return err
    52  		}
    53  		if f(path, fi.IsDir()) {
    54  			list = append(list, path)
    55  		}
    56  		return nil
    57  	})
    58  	if err != nil {
    59  		glog.Errorf("Error while scanning %q: %s", dir, err)
    60  	}
    61  	return list
    62  }
    63  
    64  // FindFilesFunc walks the directory 'dir' and collects all file names matched by
    65  // func f. It will skip over directories.
    66  // Returns empty string slice if nothing found, otherwise returns all matched file names.
    67  func FindFilesFunc(dir string, f func(string) bool) []string {
    68  	return WalkPathFunc(dir, func(path string, isdir bool) bool {
    69  		return !isdir && f(path)
    70  	})
    71  }
    72  
    73  // FindDataFiles returns a list of data files as a string array. If str is a comma-separated list
    74  // of paths, it returns that list. If str is a single path that is not a directory, it returns that
    75  // path. If str is a directory, it returns the files in it that have one of the extensions in ext.
    76  func FindDataFiles(str string, ext []string) []string {
    77  	if len(str) == 0 {
    78  		return []string{}
    79  	}
    80  
    81  	list := strings.Split(str, ",")
    82  	if len(list) == 1 && list[0] != "-" {
    83  		// make sure the file or directory exists,
    84  		// and recursively search for files if it's a directory
    85  
    86  		fi, err := os.Stat(str)
    87  		if os.IsNotExist(err) {
    88  			glog.Errorf("File or directory does not exist: %s", str)
    89  			return []string{}
    90  		}
    91  		x.Check(err)
    92  
    93  		if fi.IsDir() {
    94  			matchFn := func(f string) bool {
    95  				for _, e := range ext {
    96  					if strings.HasSuffix(f, e) {
    97  						return true
    98  					}
    99  				}
   100  				return false
   101  			}
   102  			list = FindFilesFunc(str, matchFn)
   103  		}
   104  	}
   105  
   106  	return list
   107  }
   108  
   109  // IsMissingOrEmptyDir returns true if the path either does not exist
   110  // or is a directory that is empty.
   111  func IsMissingOrEmptyDir(path string) (bool, error) {
   112  	fi, err := os.Stat(path)
   113  	if err != nil {
   114  		if os.IsNotExist(err) {
   115  			return true, nil
   116  		}
   117  		return false, err
   118  	}
   119  
   120  	if !fi.IsDir() {
   121  		return false, nil
   122  	}
   123  
   124  	file, err := os.Open(path)
   125  	defer file.Close()
   126  	if err != nil {
   127  		return false, err
   128  	}
   129  
   130  	_, err = file.Readdir(1)
   131  	if err == nil {
   132  		return false, nil
   133  	} else if err != io.EOF {
   134  		return false, err
   135  	}
   136  
   137  	return true, nil
   138  }