操纵文件:go中的文件
#编程 #教程 #github #go

如何在GO中创建文件

基本指南,逐步

您日常生活中最应该做的一件事是通过应用编程基础来解决问题。

这些基础之一是能够在文件中读写的能力。

那些开发软件的人最终在某个时候处理文件处理。

在本文中,我将向您展示如何创建 crud (创建,读取,更新,删除,删除) file 使用GO。P>

值得注意的是,在此示例中,我将使用GO的资源,而无需为我的软件导入任何外部库。

案例,您想对创建此示例的每个图书馆进行更深入的研究,您可以consultar a documentação da Standard Library do Go

如果您希望直接进入阅读文章的发明的方式,则可以访问repositório no GitHub


告诉我代码

GO中的任何软件都来自主要包装中包含的电源的起点。我将在同一funa main中一直写入。

下面我们具有软件的基础结构:

package main

import (
    "bufio"
    "fmt"
    "io"
    "os"
)

func main() {
    // Agora só falta implementar
    // Duas barras e um texto indica um comentário
}

实用中的碎屑

创造

我将首先实施 c 重新crud,然后在旅途中做到这一点,我将使用母亲©koud1语言的所有本地人。

go的os软件包允许您访问各种操作系统功能,并且由于我们想要使用文件,没有什么比使用允许它的软件包更公平的。

f, err := os.Create("test.txt")
if err != nil {
    panic(err)
}
// Não esqueça de fechar o arquivo quando a criação for concluída.
defer func(f *os.File) {
    err := f.Close()
    if err != nil {
        panic(err)
    }
}(f)

在主函数中,我们有一个差异f,它接收值os.Create()

请注意,差异f还有另一个称为err的方差。

也创建了。

在我们拥有koud7时,

表示我们正在创建一个差异,同时我们分配了一个值。 :=是用于繁殖和推断类型的Marmota(GO徽标)操作员。

该过程归结为:

1)创建变量f

(或您想要的文件,文件或名称),还创建一个差异以接收错误err

母亲©all(函数)go os软件包的Create工作如下:它接收a name 作为parano并返回两个值:第一个返回是文件本身(在这种情况下,是文件的指针,但我不会在此处输入指针的仪式),也将作为返回错误接收。

2)使用母亲©所有defer来确保文件创建后将关闭。

defer in Go中用于确保执行函数稍后

defer 指令议程a函数在包含要完成的函数后要调用。

这似乎令人困惑,但是您会意识到,换句话说,该功能被“推迟”到要执行的其余方式上。

常见的用途是要推迟的限制是关闭文件,以确保,不管文件打开后发生的事情如何,它将在fun -un -un -unded结束时关闭。
例如:

file, err := os.Open("file.txt")
if err != nil {
    log.Fatal(err)
}

defer file.Close()

// Outras operações no arquivo...
// O arquivo será fechado quando a função terminar

在此示例中,仅在执行函数中其余路后才调用file.Close()这是因为即使文件中的后续操作会导致错误,并且您从函数中返回比预期的,该文件仍将正确关闭。

推迟关闭

在这种情况下使用延期的另一种方法与矮函数一起使用。 闭合是矮人的功能。

通常建议将闭嘴与延期声明一起使用,尤其是当我们处理也涉及错误的操作时,作为文件关闭或GO中的连接。

defer与封闭结合的主要原因之一是闭合可以访问和操纵创建的范围中定义的变量。

因此,它可以处理在实际执行DEFA之前可能随着时间变化的值或状态。
这是使用闭合并延期关闭文件的示例:

f, err := os.Open("file.txt")
if err != nil {
    log.Fatal(err)
}

defer func(f *os.File) {
    if err := f.Close(); err != nil {
        log.Fatal(err) // ou qualquer outra manipulação de erro
    }
}(f)

// Outras operações no arquivo...

简而言之,在使用koud18创建文件后,我们需要将其关闭。根据母亲在标准库中的实现>文件的截断


从文件中读取

文件读数分为两个步骤。首先,我们使用koud19打开文件,然后使用bufio.NewReader()读取文件。

f, err := os.Open("test.txt")
if err != nil {
    panic(err)
}
defer func(f *os.File) {
    err := f.Close()
    if err != nil {
        panic(err)
    }
}(f)

reader := bufio.NewReader(f)
buffer := make([]byte, 10)
for {
    n, err := reader.Read(buffer)
    if err != nil && err != io.EOF {
        panic(err)
    }
    if n == 0 {
        break
    }
    fmt.Print(string(buffer[:n]))
}

现在创建了两个变化。 readerbuffer。 _您可以在没有缓冲区的情况下打开文件,但请记住,根据文件的大小,它可以超过可显示内存并最终生成错误。

可变reader现在存储母亲的归还©all bufio.NewReader(f)我们正通过了这个母亲的parano©a all。

与缓冲区一起工作的很酷的事情是能够定义您一次要阅读的切片的大小。在示例中,我正在使用母亲©All make创建一个size 10的koud27。

buffer := make([]byte, 10)

make函数是GO的形式,它分配并初始化了切片,地图或char的对象。在这种情况下,我正在使用切片类型。

您可以咨询documentação do Go以了解有关GO中的类型包的更多信息。

继续对示例进行解释,然后我使用forlaão做一些事情:

  • n, err := reader.Read(buffer)在这里,我正在访问母亲©todo读取我用来创建读者并保存在变量n中的koud24功能。 _错误的差异我已经在其工作原理之前已经解释了。

在示例中观察我们处理io.EOF(文件结尾)。

if err != nil && err != io.EOF {
        panic(err)
    }

- 重要的是要记住执行此操作,因为阅读可以随时返回io.eof ,因此我们已经在Koud31上对其进行处理,并且当我们完成阅读文件时,我们知道这一点。

关于io.EOF(文件末尾):这是一个在文件操作中常见的错误,用于指示已达到文件的结尾。

作为编程中的约定,每当函数读取文件时,到达文件的末尾>,此函数返回io.eof

这是为了使您称呼读取功能,您可以知道何时停止阅读。

我们的示例非常简单,但它显示了我们如何使用koud38(一个从源中抽象数据读数的接口)。

我们使用循环(koud31)尝试一次在我们的koud22中读取reader koud40。

如果reader.read()找到一个不是io.eof的错误,则该程序进入恐慌。

我一直喜欢去定义他会进入底座的一件事,如果没有错误发生,因为实际上是称为koud43ð

的函数

如果没有读取字节(n == 0),则意味着我们可以到达io.eof,并且该文件无需阅读,因此我们离开了循环。

如果我们包含,我们处理了成功读取的字节。

入口,简而言之,io.EOF在GO(和许多其他语言)中使用,以表示阅读文件或其他条目来源已经结束。他将控制循环和其他结构,这些结构继续阅读,没有什么可阅读的。


更新

写在文件中

创建文件后,我们可以在其中写入。为此,我们使用F.Write()函数,该函数接受字节片作为参数。

size, err := f.Write([]byte("Criando conteúdo do arquivo"))
if err != nil {
    panic(err)
}

确保使用f.Sync()同步磁盘上的数据,以确保所有待处理数据有效地写在文件中。

err = f.Sync()
if err != nil {
    panic(err)
}

在文件中写入非常简单。在示例中,我使用一个名为size的方差来存储写入功能的返回和错误差异。

下面我使用fmt软件包和Printf函数在控制台上打印此信息,以使用Koud49(String)格式化文本,该koud49(string)将被包含文件代替,转换为字符串。

此外,我还以字节显示了文件的大小。

fmt.Printf("Tamanho: %d bytes\n", size)
    fmt.Printf("Conteúdo do arquivo: %s\n", string(arquivo))

还有另一个称为Writestring的座右铭,我不需要通过字节牛,但是,我必须确保100%的时间在哪种数据中会流量在那里流量​​是字符串类型。如果我可以选择使用一个字节链,无论它们在某个时候是否是字符串,我都会选择。

无论如何,当我们利用语言资源时,在文件中写数据变得非常狂热。


删除

擦除文件

使用GO删除文件非常简单。要删除文件,我们使用os.remove()。

err = os.Remove("test.txt")
if err != nil {
    panic(err)
}
fmt.Println("\nArquivo deletado com sucesso!")

Deployando

在本教程中,我向您展示了从根本上对文件进行CRUD操作。

下面我留下完整代码的示例。在帖子的开头,有Github的存储库的链接。

package main

import (
    "bufio"
    "fmt"
    "io"
    "os"
)

func main() {
    // Criar um novo arquivo
    f, err := os.Create("test.txt")
    if err != nil {
        panic(err)
    }
    defer func(f *os.File) {
        err := f.Close()
        if err != nil {
            panic(err)
        }
    }(f)

    // Escrevendo no arquivo criado
    size, err := f.Write([]byte("Criando conteúdo do arquivo"))
    if err != nil {
        panic(err)
    }

    // Sincroniza os dados no disco
    err = f.Sync()
    if err != nil {
        panic(err)
    }

    arquivo, err := os.ReadFile("test.txt")
    if err != nil {
        panic(err)
    }

    fmt.Println("Arquivo criado com sucesso!")
    fmt.Printf("Tamanho: %d bytes\n", size)
    fmt.Printf("Conteúdo do arquivo: %s\n", string(arquivo))

    // Abrindo um arquivo existente
    f2, err := os.Open("test.txt")
    if err != nil {
        panic(err)
    }
    defer func(arquivo2 *os.File) {
        err := arquivo2.Close()
        if err != nil {
            panic(err)
        }
    }(f2)

    // Lendo arquivo usando bufio
    reader := bufio.NewReader(f2)
    buffer := make([]byte, 10)
    for {
        n, err := reader.Read(buffer)
        if err != nil && err != io.EOF {
            panic(err)
        }
        if n == 0 {
            break
        }
        fmt.Print(string(buffer[:n]))
    }

    // Deletando um arquivo
    /*
        err = os.Remove("test.txt")
        if err != nil {
            panic(err)
        }
        fmt.Println("\nArquivo deletado com sucesso!")
    */
}

就像在任何编程语言中一样,我们可以探索许多细微差别,但我认为这是一个起点。

我希望本指南一直并鼓励所有人继续探索和学习!