Whitespace path error

Hello, I’m new to go lang. while using a path of file which has a white space, I got an error.
how to fix that.

A source file with whitespace? Easy to solve, rename it that there will be no whitespace anymore.

Something else? Show relevant code and error message you get.

It’s the code:

func listOfFiles(dir string) ([]string, error) {
file, err := os.Open(dir)
if err != nil {
fmt.Println(“Error list:”, err)
os.Exit(1)
}
return file.Readdirnames(-1)
}

It’s 2 trials, one with no whitespace in path, the other with whitespace.
both folder are exist.

Please type the path
D:\wanted\GOtut\projects\subtitles\New1\

aaa.srt ----- done

======================
Please type the path
D:\wanted\GOtut\projects\subtitles\New 1
Error list: open D:\wanted\GOtut\projects\subtitles\New: The system cannot find the file specified.
exit status 1

How do you read in and pass the path?

Does it work when you hardcode the path?

By:
mDir = filepath.FromSlash(mDir)

when hardcode the path get error at both cases

w/ whitespace path:
the path is
D:\GO\New 1
Error list: open D:\GO\New 1: The system cannot find the file specified.
exit status 1

w/o whitespace path:
the path is
D:\GO\New1
Error list: open D:\GO\New1: The system cannot find the file specified.
exit status 1

Can you please provide a full and self contained example which shows your problem?

I can’t reproduce it:

$ ls {a1,"a 1"}                         
a1:
f1  f2

'a 1':
f1  f2
package main

import (
	"fmt"
	"os"
)

func listOfFiles(dir string) ([]string, error) {
	file, err := os.Open(dir)
	if err != nil {
		fmt.Println("Error list:", err)
		os.Exit(1)
	}
	return file.Readdirnames(-1)
}

func main() {
	files, err := listOfFiles("./a 1")
	fmt.Printf("%#v; %v\n", files, err)

	files, err = listOfFiles("./a1")
	fmt.Printf("%#v, %v\n", files, err)
}
$ go run file.go
[]string{"f1", "f2"}; <nil>
[]string{"f1", "f2"}, <nil>
$ go version
go version go1.10 linux/amd64

Perhaps a windows/linux thing… Therefore I will try on a windows machine as well tomorrow as soon as I’m in office.

I realize that this pathes are different than the ones in the first post, so are you sure those pathes do actually exist?

Also do you see the difference in the error message between the hardcoded path and the otherwise entered? The hardcoded path is printed in full, while the other one is truncated at the whitespace. So by a very high chance you are either reading the input wrong or you do some postprocessing on the input which handles whitespace wrong.

Yes, I see the difference in the error message. but I think that the difference is not due to the method of entering path, it is due to the whitespace in the path. the path w/o whitespace is printed in full , while the other one is truncated at the whitespace. a similar error occurs in case of the filename includes a whitespace.

Type the path!
D:\wanted\GOtut\projects\subtitles\New1
aab.txt ----- done
aac.txt ----- done
Error read data: open aad 1.txt: The system cannot find the file specified.
exit status 1

It’s the full source file.

package main

import (
“fmt”
“io/ioutil”
“os”
“path/filepath”
“strings”
)

type data []string

var mDir string

func main() {
for {

  fmt.Println("Type the path!")
  fmt.Scanln(&mDir)
  mDir = filepath.FromSlash(mDir)
  data1, _ := listOfFiles(mDir)
  for i := 0; i < len(data1); i++ {
  	if strings.Contains(data1[i], ".txt") {
  		d1 := readFromFile(data1[i])
  		d1.modify()
  		d1.saveToFile(data1[i])
  		fmt.Println(data1[i], " ----- done")
  	}
  }
  fmt.Println("======================")

}
}

func listOfFiles(dir string) ([]string, error) {
file, err := os.Open(dir)
if err != nil {
fmt.Println(“Error list:”, err)
os.Exit(1)
}
return file.Readdirnames(-1)
}

func (d data) modify() {
for i := 0; i < len(d)-1; i += 8 {
s1 := d[i+6]
d[i+6] = d[i+5]
d[i+5] = d[i+4]
d[i+4] = d[i+3]
d[i+3] = s1
}
}

func (d data) tostring() string {
return strings.Join([]string(d), “\n”)
}

func (d data) saveToFile(filename string) error {
return ioutil.WriteFile(filename, []byte(d.tostring()), 0666)
}

func readFromFile(filename string) data {
bs, err := ioutil.ReadFile(filename)
if err != nil {
fmt.Println(“Error read data:”, err)
os.Exit(1)
}

s := strings.Split(string(bs), “\n”)
return data(s)
}

Manually entered:

Hardcoded:

Please compare both, the hardcoded one is printed in full.


Also I was able to narrow down your problem. Its fmt.Scanln (emphasis mine):

Scan scans text read from standard input, storing successive space-separated values into successive arguments.

So this one truncates at the space. os.Open will probably have no problems with spaces if the path exists at all.

but the error occurs too in case of the filename has a whitespace not only folders

see that:

Type the path!
D:\wanted\GOtut\projects\subtitles\New1
aab.txt ----- done
aac.txt ----- done
Error read data: open aad 1.txt: The system cannot find the file specified.
exit status 1

Which I fear might be coincidental.

Currently you create a list of workitems from the given path, you then filter this list by .txt (which would also try to process a file like my.txt.pdf!) and then try to open them in your current working dir, since you do not change the working dir into the given directory, nor do you joint the given path and the found filenames.

So my assumption is, that you actually have aab.txt and aac.txt in the directory from where you run the programm, but not a file aad 1.txt.


Last but not least, try to avoid whitespace and umlauts in your filenames in general, try even to stick to lowercase only.

you were right about having aab.txt and aac.txt in the directory from where you run the programm, but not a file aad 1.txt.
so I edited the code of functions that read and write file to become

func (d data) saveToFile(filename string) error {
return ioutil.WriteFile(mDir + filename, []byte(d.tostring()), 0666)
}

func readFromFile(filename string) data {
bs, err := ioutil.ReadFile(mDir + filename)
if err != nil {
fmt.Println(“Error read data:”, err)
os.Exit(1)
}

s := strings.Split(string(bs), “\n”)
return data(s)
}

so all files modified

in a word the problem is fmt.Scanln as you say

Is there a solution for that?

Be carful with that, you should prefer path.Join to join pathes.


For the Scan problem there are two solutions:

  1. Write a proper CLI which takes its target as a command line argument, Remember to escape whitespace in the call then, depending on the shell you use.
  2. Don’t use scan but ReadLine from bufio as in this post on stackoverflow: https://stackoverflow.com/a/20895629/826797

ReadLine from bufio is a good solution :+1: :ok_hand:
I replaced the method to filter list by func Ext(path string) string from filepath so no processing a file like my.txt.pdf

thanks sir

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.