1// Copyright 2016 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package os_test 6 7import ( 8 "bytes" 9 "errors" 10 "fmt" 11 "io/fs" 12 "log" 13 "os" 14 "path/filepath" 15 "sync" 16 "time" 17) 18 19func ExampleOpenFile() { 20 f, err := os.OpenFile("notes.txt", os.O_RDWR|os.O_CREATE, 0644) 21 if err != nil { 22 log.Fatal(err) 23 } 24 if err := f.Close(); err != nil { 25 log.Fatal(err) 26 } 27} 28 29func ExampleOpenFile_append() { 30 // If the file doesn't exist, create it, or append to the file 31 f, err := os.OpenFile("access.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) 32 if err != nil { 33 log.Fatal(err) 34 } 35 if _, err := f.Write([]byte("appended some data\n")); err != nil { 36 f.Close() // ignore error; Write error takes precedence 37 log.Fatal(err) 38 } 39 if err := f.Close(); err != nil { 40 log.Fatal(err) 41 } 42} 43 44func ExampleChmod() { 45 if err := os.Chmod("some-filename", 0644); err != nil { 46 log.Fatal(err) 47 } 48} 49 50func ExampleChtimes() { 51 mtime := time.Date(2006, time.February, 1, 3, 4, 5, 0, time.UTC) 52 atime := time.Date(2007, time.March, 2, 4, 5, 6, 0, time.UTC) 53 if err := os.Chtimes("some-filename", atime, mtime); err != nil { 54 log.Fatal(err) 55 } 56} 57 58func ExampleFileMode() { 59 fi, err := os.Lstat("some-filename") 60 if err != nil { 61 log.Fatal(err) 62 } 63 64 fmt.Printf("permissions: %#o\n", fi.Mode().Perm()) // 0o400, 0o777, etc. 65 switch mode := fi.Mode(); { 66 case mode.IsRegular(): 67 fmt.Println("regular file") 68 case mode.IsDir(): 69 fmt.Println("directory") 70 case mode&fs.ModeSymlink != 0: 71 fmt.Println("symbolic link") 72 case mode&fs.ModeNamedPipe != 0: 73 fmt.Println("named pipe") 74 } 75} 76 77func ExampleErrNotExist() { 78 filename := "a-nonexistent-file" 79 if _, err := os.Stat(filename); errors.Is(err, fs.ErrNotExist) { 80 fmt.Println("file does not exist") 81 } 82 // Output: 83 // file does not exist 84} 85 86func ExampleExpand() { 87 mapper := func(placeholderName string) string { 88 switch placeholderName { 89 case "DAY_PART": 90 return "morning" 91 case "NAME": 92 return "Gopher" 93 } 94 95 return "" 96 } 97 98 fmt.Println(os.Expand("Good ${DAY_PART}, $NAME!", mapper)) 99 100 // Output: 101 // Good morning, Gopher! 102} 103 104func ExampleExpandEnv() { 105 os.Setenv("NAME", "gopher") 106 os.Setenv("BURROW", "/usr/gopher") 107 108 fmt.Println(os.ExpandEnv("$NAME lives in ${BURROW}.")) 109 110 // Output: 111 // gopher lives in /usr/gopher. 112} 113 114func ExampleLookupEnv() { 115 show := func(key string) { 116 val, ok := os.LookupEnv(key) 117 if !ok { 118 fmt.Printf("%s not set\n", key) 119 } else { 120 fmt.Printf("%s=%s\n", key, val) 121 } 122 } 123 124 os.Setenv("SOME_KEY", "value") 125 os.Setenv("EMPTY_KEY", "") 126 127 show("SOME_KEY") 128 show("EMPTY_KEY") 129 show("MISSING_KEY") 130 131 // Output: 132 // SOME_KEY=value 133 // EMPTY_KEY= 134 // MISSING_KEY not set 135} 136 137func ExampleGetenv() { 138 os.Setenv("NAME", "gopher") 139 os.Setenv("BURROW", "/usr/gopher") 140 141 fmt.Printf("%s lives in %s.\n", os.Getenv("NAME"), os.Getenv("BURROW")) 142 143 // Output: 144 // gopher lives in /usr/gopher. 145} 146 147func ExampleUnsetenv() { 148 os.Setenv("TMPDIR", "/my/tmp") 149 defer os.Unsetenv("TMPDIR") 150} 151 152func ExampleReadDir() { 153 files, err := os.ReadDir(".") 154 if err != nil { 155 log.Fatal(err) 156 } 157 158 for _, file := range files { 159 fmt.Println(file.Name()) 160 } 161} 162 163func ExampleMkdirTemp() { 164 dir, err := os.MkdirTemp("", "example") 165 if err != nil { 166 log.Fatal(err) 167 } 168 defer os.RemoveAll(dir) // clean up 169 170 file := filepath.Join(dir, "tmpfile") 171 if err := os.WriteFile(file, []byte("content"), 0666); err != nil { 172 log.Fatal(err) 173 } 174} 175 176func ExampleMkdirTemp_suffix() { 177 logsDir, err := os.MkdirTemp("", "*-logs") 178 if err != nil { 179 log.Fatal(err) 180 } 181 defer os.RemoveAll(logsDir) // clean up 182 183 // Logs can be cleaned out earlier if needed by searching 184 // for all directories whose suffix ends in *-logs. 185 globPattern := filepath.Join(os.TempDir(), "*-logs") 186 matches, err := filepath.Glob(globPattern) 187 if err != nil { 188 log.Fatalf("Failed to match %q: %v", globPattern, err) 189 } 190 191 for _, match := range matches { 192 if err := os.RemoveAll(match); err != nil { 193 log.Printf("Failed to remove %q: %v", match, err) 194 } 195 } 196} 197 198func ExampleCreateTemp() { 199 f, err := os.CreateTemp("", "example") 200 if err != nil { 201 log.Fatal(err) 202 } 203 defer os.Remove(f.Name()) // clean up 204 205 if _, err := f.Write([]byte("content")); err != nil { 206 log.Fatal(err) 207 } 208 if err := f.Close(); err != nil { 209 log.Fatal(err) 210 } 211} 212 213func ExampleCreateTemp_suffix() { 214 f, err := os.CreateTemp("", "example.*.txt") 215 if err != nil { 216 log.Fatal(err) 217 } 218 defer os.Remove(f.Name()) // clean up 219 220 if _, err := f.Write([]byte("content")); err != nil { 221 f.Close() 222 log.Fatal(err) 223 } 224 if err := f.Close(); err != nil { 225 log.Fatal(err) 226 } 227} 228 229func ExampleReadFile() { 230 data, err := os.ReadFile("testdata/hello") 231 if err != nil { 232 log.Fatal(err) 233 } 234 os.Stdout.Write(data) 235 236 // Output: 237 // Hello, Gophers! 238} 239 240func ExampleWriteFile() { 241 err := os.WriteFile("testdata/hello", []byte("Hello, Gophers!"), 0666) 242 if err != nil { 243 log.Fatal(err) 244 } 245} 246 247func ExampleMkdir() { 248 err := os.Mkdir("testdir", 0750) 249 if err != nil && !os.IsExist(err) { 250 log.Fatal(err) 251 } 252 err = os.WriteFile("testdir/testfile.txt", []byte("Hello, Gophers!"), 0660) 253 if err != nil { 254 log.Fatal(err) 255 } 256} 257 258func ExampleMkdirAll() { 259 err := os.MkdirAll("test/subdir", 0750) 260 if err != nil { 261 log.Fatal(err) 262 } 263 err = os.WriteFile("test/subdir/testfile.txt", []byte("Hello, Gophers!"), 0660) 264 if err != nil { 265 log.Fatal(err) 266 } 267} 268 269func ExampleReadlink() { 270 // First, we create a relative symlink to a file. 271 d, err := os.MkdirTemp("", "") 272 if err != nil { 273 log.Fatal(err) 274 } 275 defer os.RemoveAll(d) 276 targetPath := filepath.Join(d, "hello.txt") 277 if err := os.WriteFile(targetPath, []byte("Hello, Gophers!"), 0644); err != nil { 278 log.Fatal(err) 279 } 280 linkPath := filepath.Join(d, "hello.link") 281 if err := os.Symlink("hello.txt", filepath.Join(d, "hello.link")); err != nil { 282 if errors.Is(err, errors.ErrUnsupported) { 283 // Allow the example to run on platforms that do not support symbolic links. 284 fmt.Printf("%s links to %s\n", filepath.Base(linkPath), "hello.txt") 285 return 286 } 287 log.Fatal(err) 288 } 289 290 // Readlink returns the relative path as passed to os.Symlink. 291 dst, err := os.Readlink(linkPath) 292 if err != nil { 293 log.Fatal(err) 294 } 295 fmt.Printf("%s links to %s\n", filepath.Base(linkPath), dst) 296 297 var dstAbs string 298 if filepath.IsAbs(dst) { 299 dstAbs = dst 300 } else { 301 // Symlink targets are relative to the directory containing the link. 302 dstAbs = filepath.Join(filepath.Dir(linkPath), dst) 303 } 304 305 // Check that the target is correct by comparing it with os.Stat 306 // on the original target path. 307 dstInfo, err := os.Stat(dstAbs) 308 if err != nil { 309 log.Fatal(err) 310 } 311 targetInfo, err := os.Stat(targetPath) 312 if err != nil { 313 log.Fatal(err) 314 } 315 if !os.SameFile(dstInfo, targetInfo) { 316 log.Fatalf("link destination (%s) is not the same file as %s", dstAbs, targetPath) 317 } 318 319 // Output: 320 // hello.link links to hello.txt 321} 322 323func ExampleUserCacheDir() { 324 dir, dirErr := os.UserCacheDir() 325 if dirErr == nil { 326 dir = filepath.Join(dir, "ExampleUserCacheDir") 327 } 328 329 getCache := func(name string) ([]byte, error) { 330 if dirErr != nil { 331 return nil, &os.PathError{Op: "getCache", Path: name, Err: os.ErrNotExist} 332 } 333 return os.ReadFile(filepath.Join(dir, name)) 334 } 335 336 var mkdirOnce sync.Once 337 putCache := func(name string, b []byte) error { 338 if dirErr != nil { 339 return &os.PathError{Op: "putCache", Path: name, Err: dirErr} 340 } 341 mkdirOnce.Do(func() { 342 if err := os.MkdirAll(dir, 0700); err != nil { 343 log.Printf("can't create user cache dir: %v", err) 344 } 345 }) 346 return os.WriteFile(filepath.Join(dir, name), b, 0600) 347 } 348 349 // Read and store cached data. 350 // … 351 _ = getCache 352 _ = putCache 353 354 // Output: 355} 356 357func ExampleUserConfigDir() { 358 dir, dirErr := os.UserConfigDir() 359 360 var ( 361 configPath string 362 origConfig []byte 363 ) 364 if dirErr == nil { 365 configPath = filepath.Join(dir, "ExampleUserConfigDir", "example.conf") 366 var err error 367 origConfig, err = os.ReadFile(configPath) 368 if err != nil && !os.IsNotExist(err) { 369 // The user has a config file but we couldn't read it. 370 // Report the error instead of ignoring their configuration. 371 log.Fatal(err) 372 } 373 } 374 375 // Use and perhaps make changes to the config. 376 config := bytes.Clone(origConfig) 377 // … 378 379 // Save changes. 380 if !bytes.Equal(config, origConfig) { 381 if configPath == "" { 382 log.Printf("not saving config changes: %v", dirErr) 383 } else { 384 err := os.MkdirAll(filepath.Dir(configPath), 0700) 385 if err == nil { 386 err = os.WriteFile(configPath, config, 0600) 387 } 388 if err != nil { 389 log.Printf("error saving config changes: %v", err) 390 } 391 } 392 } 393 394 // Output: 395} 396