Go 文件读写

Golang之文件读写

读写文件,不添加文件路径,默认写入到GOPATH路径下

终端读写:

源码

func Sscanf
func Sscanf(str string, format string, a ...interface{}) (n int, err error)
解释:Sscanf scans the argument string, storing successive space-separated values into successive arguments as determined by the format.
It returns the number of items successfully parsed. Newlines in the input must match newlines in the format.
复制代码
package main

import "fmt"

//终端读写
type student struct {
    Name  string
    Age   int
    Score float32
}

func main() {
    var str = "stu01 18 89.92"
    var stu student
    fmt.Sscanf(str, "%s %d %f", &stu.Name, &stu.Age, &stu.Score)
    fmt.Println(stu)
}
复制代码

文本I/O缓冲:

源码

func NewReader
func NewReader(rd io.Reader) *Reader
NewReader returns a new Reader whose buffer has the default size.

-

复制代码
package main

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

func main() {
    reader := bufio.NewReader(os.Stdin)
    str, err := reader.ReadString('\n')
    if err != nil {
        fmt.Println("read string,err:", err)
        return
    }
    fmt.Printf("read str succ,ret:%s\n", str)
}
复制代码

打开文件,读取

复制代码
package main

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

//读取文件

func main() {
    //打开一个文件
    file, err := os.Open("D:/project/src/go_dev/day7/example4/123.log")
    if err != nil {
        fmt.Println("read file err:", err)
        return
    }
    //重点,文件要关闭
    defer file.Close()
    /*
        func NewReaderSize
        func NewReaderSize(rd io.Reader, size int) *Reader
            NewReaderSize returns a new Reader whose buffer has at least the specified size.
            If the argument io.Reader is already a Reader with large enough size, it returns the underlying Reader.
    */
    reader := bufio.NewReader(file)
  //文件若不是换行结尾,就算出错 str, err :
= reader.ReadString('\n') if err != nil { fmt.Println("read string failed,err:", err) return } fmt.Printf("read str success,result:%s\n", str) }
复制代码

ReadString源码

    /*
    func (*Reader) ReadString ¶

func (b *Reader) ReadString(delim byte) (string, error)
ReadString reads until the first occurrence of delim in the input, returning a string containing the data up to and including the delimiter.
    If ReadString encounters an error before finding a delimiter, it returns the data read before the error and the error itself (often io.EOF).
    ReadString returns err != nil if and only if the returned data does not end in delim. For simple uses, a Scanner may be more convenient.
     */

-读取一行的字符个数

复制代码
package main

import (
    "fmt"
    "os"
)

/*
从终端读取一行字符串,统计英文、数字、空格以及其他字符的数量
*/
import (
    "bufio"
    "io"
)

type CharCount struct {
    ChCount    int
    NumCount   int
    SpaceCount int
    OtherCount int
}

func main() {
    file, err := os.Open("D:/project/src/go_dev/day7/example4/123.log")
    if err != nil {
        fmt.Println("read file err:", err)
        return
    }
    defer file.Close()
    var count CharCount
    reader := bufio.NewReader(file)

    for {
        str, err := reader.ReadString('\n')
        if err == io.EOF {
            break
        }
        if err != nil {
            fmt.Printf("read file failed,err:%v", err)
            break
        }
        runeArr := []rune(str)
        for _, v := range runeArr {
            switch {
            case v >= 'a' && v <= 'z':
                fallthrough
            case v >= 'A' && v <= 'Z':
                count.ChCount++
            case v == ' ' || v == '\t':
                count.SpaceCount++
            case v >= '0' && v <= '9':
                count.NumCount++
            default:
                count.OtherCount++
            }
        }
    }
    fmt.Printf("char count:%d\n", count.ChCount)
    fmt.Printf("num count:%d\n", count.NumCount)
    fmt.Printf("space count:%d\n", count.SpaceCount)
    fmt.Printf("other count:%d\n", count.OtherCount)
}
字符统计
复制代码

文件写入

--

复制代码
package main

import (
    "bufio"
    "fmt"
    "os"
)
func main(){
    outputFile,outputError:=os.OpenFile("output.dat",os.O_WRONLY|os.O_CREATE,0666)
    if outputError!=nil{
        fmt.Printf("An error occurred with file crea ion\n")
        return
    }
    //在函数执行结束前,一定要关闭,谨记
    defer outputFile.Close()
    outputWriter:=bufio.NewWriter(outputFile)
    outputString:="hello world!\n"
    for i:=0;i<10;i++{
        outputWriter.WriteString(outputString)
    }
    outputWriter.Flush()//刷新落地
}
复制代码

golang的复制文件

复制代码
package main

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

func main() {
    //os.Args是string的切片,用来存储所有的命令行参数
    w, err := CopyFile(os.Args[1], os.Args[2])
    if err != nil {
        fmt.Println(err.Error())
    }
    fmt.Println(w)
}
func CopyFile(dstName, srcName string) (written int64, err error) {
    src, err := os.Open(srcName)
    if err != nil {
        return
    }
    defer src.Close()
    dst, err := os.OpenFile(dstName, os.O_WRONLY|os.O_CREATE, 0644)
    if err != nil {
        return
    }
    defer dst.Close()
    //把src内容写进dst里面
    return io.Copy(dst, src)
}
复制代码

命令行参数

复制代码
package main

import (
    "fmt"
    "os"
)

func main() {
    fmt.Printf("len of args:%d\n", len(os.Args))
    for i, v := range os.Args {
        fmt.Printf("args[%d]=%s\n", i, v)
    }
}
复制代码

flag包用于实现命令行参数

例如Linux下的 ls -l

复制代码
package main

import (
    "flag"
    "fmt"
)
//flag包支持命令行参数
func main() {
    var confPath string
    var logLevel int
    flag.StringVar(&confPath, "c", "", "Please input conf path")
    flag.IntVar(&logLevel, "d", 0, "PLEASE INPUT LOG LEVEL")
    flag.Parse()
    fmt.Println("path:", confPath)
    fmt.Println("log leve:", logLevel)
}
复制代码

Golang之json序列化(struct,int,map,slice)

复制代码
package main

import (
    "encoding/json"
    "fmt"
)

//把结构体都改小写
type User struct {
    UserName string `json:"user_name"` //json的tag标记
    Nickname string `json:"nickname"`
    Age      int
    Birthday string
    Sex      string
    Email    string
    Phone    string
}

func testStruct() {
    user1 := &User{
        UserName: "超哥",
        Nickname: "大头哥",
        Age:      18,
        Birthday: "2008/8/8",
        Sex:      "",
        Email:    "mahuateng@qq.com",
        Phone:    "110",
    }

    //开始json序列化
    data, err := json.Marshal(user1)
    if err != nil {
        fmt.Printf("json.marshal failed,err:", err)
        return
    }
    fmt.Printf("%s\n", string(data))
}

func testInt() {
    var a = 18
    //开始json序列化
    data, err := json.Marshal(a)
    if err != nil {
        fmt.Printf("json.marshal failed,err:", err)
        return
    }
    fmt.Printf("%s\n", string(data))

}

func testMap() {
    var m map[string]interface{}     //声明map
    m = make(map[string]interface{}) //必须初始化map分配内存
    m["username"] = "user1"
    m["age"] = 18
    m["sex"] = "man"
    fmt.Println(m)
    data, err := json.Marshal(m)
    if err != nil {
        fmt.Printf("json.marshal failed,err:", err)
        return
    }
    fmt.Printf("%s\n", string(data))

}

func testSlice() {
    //定义一个slice,元素是map
    var m map[string]interface{}
    var s []map[string]interface{}
    m = make(map[string]interface{})
    m["username"] = "user1"
    m["age"] = 18
    m["sex"] = "man"
    s = append(s, m)
    m = make(map[string]interface{})
    m["username"]="user2"
    m["age"]=188
    m["sex"]="male"
    s=append(s,m)
    data, err := json.Marshal(s)
    if err != nil {
        fmt.Printf("json.marshal failed,err:", err)
        return
    }
    fmt.Printf("%s\n", string(data))

}
func main() {
    testStruct() //结构体的序列化
    testInt()//序列化数值
    testMap()//序列化map
    testSlice()//序列化切片
}
复制代码

golang之包和锁的机制

互斥锁

同一时刻只有一个携程在操作

复制代码
package main

import (
    "fmt"
    "math/rand"
    "sync"
    "time"
)
//互斥锁
var lock sync.Mutex

func testMap() {
    var a map[int]int
    a = make(map[int]int, 5)
    a[8] = 10
    a[3] = 10
    a[2] = 10
    a[1] = 10
    for i := 0; i < 2; i++ {
        func(b map[int]int) {
            lock.Lock()
            b[8] = rand.Intn(100)
            lock.Unlock()
        }(a)
    }
    lock.Lock()
    fmt.Println(a)
    lock.Unlock()
    time.Sleep(time.Second)
}
func main() {
    //互斥锁
    testMap()
}
复制代码

读写锁

读多写少的情况,用读写锁, 携程同时在操作读。

复制代码
package main

import (
    "fmt"
    "math/rand"
    "sync"
    "time"
)

//读写锁
var rwLock sync.RWMutex

func testRWLock() {
    var a map[int]int
    a = make(map[int]int, 5)
    a[8] = 10
    a[3] = 10
    a[2] = 10
    a[1] = 10
    a[18] = 10
    for i := 0; i < 2; i++ {
        go func(b map[int]int) {
            rwLock.Lock()
            b[8] = rand.Intn(100)
            rwLock.Unlock()
        }(a)
    }
    for i := 0; i < 100; i++ {
        go func(b map[int]int) {
            rwLock.RLock() //读锁
            fmt.Println(a)
            rwLock.RUnlock()
        }(a)
    }
    time.Sleep(time.Second * 20)

}
func main() {
    
    testRWLock()
    //读多写少的时候,用读写锁
}
复制代码

读写锁,互斥锁,性能比较

复制代码
package main

import (
    "fmt"
    "math/rand"
    "sync"
    "sync/atomic"
    "time"
)

//读写锁
var rwLock sync.RWMutex
var lock sync.Mutex

func testRWLock() {
    var a map[int]int
    a = make(map[int]int, 5)
    var count int32
    a[8] = 10
    a[3] = 10
    a[2] = 10
    a[1] = 10
    a[18] = 10
    for i := 0; i < 2; i++ {
        go func(b map[int]int) {
            //rwLock.Lock() //读写锁的代码
            lock.Lock() //互斥锁的代码
            b[8] = rand.Intn(100)
            time.Sleep(10 * time.Microsecond) //微妙
            //rwLock.Unlock()
            lock.Unlock()

        }(a)
    }
    for i := 0; i < 100; i++ {
        go func(b map[int]int) {
            for {
                //rwLock.RLock() //读写锁的代码
                lock.Lock()
                time.Sleep(time.Millisecond)
                //rwLock.RUnlock()
                lock.Unlock()
                atomic.AddInt32(&count, 1)
            }
        }(a)
    }
    time.Sleep(time.Second * 20)
    fmt.Println(atomic.LoadInt32(&count))
}
func main() {
    //互斥锁
    testRWLock()
    //读多写少的时候,用读写锁
}
复制代码
posted @   silencio。  阅读(154)  评论(0编辑  收藏  举报
(评论功能已被禁用)
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示