读取文件并在Go中显示其内容

读取文件并在Go中显示其内容,go,Go,我是新手,我想做一个简单的程序,从用户那里读取文件名并将其内容显示给用户。这就是我到目前为止所做的: fname := "D:\myfolder\file.txt" f, err := os.Open(fname) if err != nil { fmt.Println(err) } var buff []byte defer f.Close() buff = make([]byte, 1024) for { n, err := f.Read(buff) if n

我是新手,我想做一个简单的程序,从用户那里读取文件名并将其内容显示给用户。这就是我到目前为止所做的:

fname := "D:\myfolder\file.txt"

f, err := os.Open(fname)
if err != nil {
    fmt.Println(err)
}

var buff []byte
defer f.Close()
buff = make([]byte, 1024)
for {
    n, err := f.Read(buff)

    if n > 0 {
        fmt.Println(string(buff[:n]))
    }
    if err == io.EOF {
        break
    }
}
但我得到了一个错误:

文件名、目录名或卷标语法不正确


我怀疑
fname
中的反斜杠就是原因。尝试使用双反斜杠(
\\
)。

我怀疑是因为
fname
中的反斜杠。请尝试使用双反斜杠(
\\
)。

将文件名放在反引号中。这使其成为原始字符串文字。对于原始字符串文本,不会处理转义序列,例如
\f

fname := `D:\myfolder\file.txt`

将文件名放在反引号中。这使其成为原始字符串文字。对于原始字符串文本,不会处理转义序列,例如
\f

fname := `D:\myfolder\file.txt`

您也可以改用unix“/”路径分隔符。 他做这项工作

fname := "D:/myfolder/file.txt"

您也可以改用unix“/”路径分隔符。 他做这项工作

fname := "D:/myfolder/file.txt"

祝贺你学习成功!虽然问题是关于示例中的一个特定错误,但让我们逐行将其细分,并了解一些可能遇到的其他问题:

fname:=“D:\myfolder\file.txt”
与C和许多其他语言一样,Go使用反斜杠字符作为“转义序列”。也就是说,以反斜杠开头的某些字符会被翻译成其他很难看到的字符(例如,
\t
变成制表符,否则可能无法与空格区分)

修复方法是在不处理转义序列的情况下使用原始字符串文字(使用反勾号而不是引号):

fname:=`D:\myfolder\file.txt`
这通过删除无效的
\m
\f
转义序列修复了您看到的初始错误。通过阅读Go规范的章节,可以找到完整的转义序列列表和更多解释

f,err:=os.Open(fname)
如果出错!=零{
fmt.Println(错误)
}
这个区块的第一行是好的,但是可以改进。如果发生错误,我们的程序没有理由继续执行,因为我们甚至无法打开文件,所以我们应该打印它(可能是标准错误)并退出,最好是使用非零退出状态来指示发生了错误。此外,作为一个好习惯,如果打开成功,我们可能希望在函数结束时关闭文件。将它放在Open调用的正下方是一种传统做法,当其他人正在阅读您的代码时,它会变得更容易。我将改写为:

f,err:=os.Open(fname)
如果出错!=零{
fmt.Fprintln(os.Stderr,err)
操作系统出口(2)
//用对log.Fatal的调用替换这两行也是很常见的
}
延迟f.关闭()
最后一块有点复杂,我们可以用多种方式重写它。现在看起来是这样的:

var buff[]字节
延迟f.关闭()
buff=make([]字节,1024)
为了{
n、 错误:=f.Read(buff)
如果n>0{
fmt.Println(字符串(buff[:n]))
}
如果err==io.EOF{
打破
}
}
但我们不需要定义我们自己的缓冲,因为标准库为我们提供了和包,可以为我们实现这一点。不过,在这种情况下,我们可能不需要它们,因为我们还可以用一个调用来替换迭代,该调用会执行自己的内部缓冲。我们还可以使用其他复制变体之一,例如,如果我们想使用自己的缓冲区。它还缺少一些错误处理,因此我们将添加它。现在整个区块变成:

\错误:=io.Copy(os.Stdout,f)
如果出错!=零{
fmt.Fprintf(os.Stderr,“读取文件时出错:`%s'\n”,错误)
操作系统出口(2)
}
//我们完了!

祝贺您学习Go!虽然问题是关于示例中的一个特定错误,但让我们逐行将其细分,并了解一些可能遇到的其他问题:

fname:=“D:\myfolder\file.txt”
与C和许多其他语言一样,Go使用反斜杠字符作为“转义序列”。也就是说,以反斜杠开头的某些字符会被翻译成其他很难看到的字符(例如,
\t
变成制表符,否则可能无法与空格区分)

修复方法是在不处理转义序列的情况下使用原始字符串文字(使用反勾号而不是引号):

fname:=`D:\myfolder\file.txt`
这通过删除无效的
\m
\f
转义序列修复了您看到的初始错误。通过阅读Go规范的章节,可以找到完整的转义序列列表和更多解释

f,err:=os.Open(fname)
如果出错!=零{
fmt.Println(错误)
}
这个区块的第一行是好的,但是可以改进。如果发生错误,我们的程序没有理由继续执行,因为我们甚至无法打开文件,所以我们应该打印它(可能是标准错误)并退出,最好是使用非零退出状态来指示发生了错误。此外,作为一个好习惯,如果打开成功,我们可能希望在函数结束时关闭文件。将它放在Open调用的正下方是一种传统做法,当其他人正在阅读您的代码时,它会变得更容易。我将改写为:

f,err:=os.Open(fname)
如果出错!=零{
fmt.Fprintln(os.Stderr,err)
操作系统出口(2)
//用对log.Fatal的调用替换这两行也是很常见的
}
延迟f.关闭()
最后一块有点复杂,我们可以用多种方式重写它。现在看起来是这样的:

var buff[]字节
延迟f.关闭()
buff=make([]字节,1024)
为了{
n、 错误:=f.Read(buff)
如果n>0{
fmt.Println(字符串(buff[:n]))
}
如果err==io.EOF{
打破
}
}
但我们不需要