ホームページ >バックエンド開発 >Golang >Golangでファイル転送機能を実装する方法

Golangでファイル転送機能を実装する方法

PHPz
PHPz転載
2023-03-29 11:26:39793ブラウズ
この記事では、主に Golang のファイル転送機能について詳しく紹介します 記事内のサンプルコードは非常に詳しく、特定の For参照値、興味のある友人は参照できます

この記事の例では、参考までに Golang でのファイル転送の具体的なコードを共有します。

##TCP を使用してファイル送信を完了します。基本的な考え方は次のとおりです:

1. 送信者 (クライアント) がファイル名をサーバーに送信し、サーバーはファイル名を保存します。

2. 受信者 (サーバー) は、ファイル名が正常に保存されたことを確認するために、ok メッセージをクライアントに返します。

3. メッセージを受信した送信者 (クライアント) は、サーバーへのファイル データの送信を開始します。

4. 受信者 (サーバー) はファイルの内容を読み取り、以前に保存したファイルに書き込みます。

Golangでファイル転送機能を実装する方法

#最初にファイル名を取得します。ファイル属性情報を取得するには、os パッケージの stat() 関数を使用します。関数によって返されるファイル プロパティにファイル名とファイル サイズを含めます。 Statパラメータ名はファイルアクセスの絶対パスで渡されます。 FileInfo の Name() 関数を使用すると、ファイル名を個別に抽出できます。

func Stat(name string) (FileInfo, error) 
type FileInfo interface {
   Name() string       
   Size() int64        
   Mode() FileMode     
   ModTime() time.Time 
   IsDir() bool        
   Sys() interface{}   
}
送信者:

package main
 
import (
    "fmt"
    "io"
    "net"
    "os"
)
 
func sendFile(conn net.Conn, filePath string) {
    // 只读打开文件
    f, err := os.Open(filePath)
    if err != nil {
        fmt.Println("os.Open err:", err)
        return
    }
    defer f.Close()
 
    // 从本文件中,读数据,写给网络接收端。 读多少,写多少。原封不动。
    buf := make([]byte, 1024)
    for {
        n, err := f.Read(buf)
        if err != nil {
            if err == io.EOF {
                fmt.Println("发送文件完成。")
            } else {
                fmt.Println("os.Open err:", err)
            }
            return
        }
        // 写到网络socket中
        _, err = conn.Write(buf[:n])
        if err != nil {
            fmt.Println("conn.Write err:", err)
            return
        }
    }
}
 
func main() {
    list := os.Args // 获取命令行参数
 
    if len(list) != 2 {
        fmt.Println("格式为:go run xxx.go 文件绝对路径")
        return
    }
    // 提取 文件的绝对路径
    filePath := list[1]
 
    //提取文件名
    fileInfo, err := os.Stat(filePath)
    if err != nil {
        fmt.Println("os.Stat err:", err)
        return
    }
    fileName := fileInfo.Name()
 
    // 主动发起连接请求
    conn, err := net.Dial("tcp", "127.0.0.1:8000")
    if err != nil {
        fmt.Println("net.Dial err:", err)
        return
    }
    defer conn.Close()
 
    // 发送文件名给 接收端
    _, err = conn.Write([]byte(fileName))
    if err != nil {
        fmt.Println("conn.Write err:", err)
        return
    }
    // 读取服务器回发的 OK
    buf := make([]byte, 1024)
    n, err := conn.Read(buf)
    if err != nil {
        fmt.Println("conn.Read err:", err)
        return
    }
 
    if "ok" == string(buf[:n]) {
        // 写文件内容给服务器——借助conn
        sendFile(conn, filePath)
    }
}
受信者:

package main
 
import (
    "fmt"
    "net"
    "os"
)
 
func recvFile(conn net.Conn, fileName string) {
    // 按照文件名创建新文件
    f, err := os.Create(fileName)
    if err != nil {
        fmt.Println("os.Create err:", err)
        return
    }
    defer f.Close()
 
    // 从 网络中读数据,写入本地文件
    buf := make([]byte, 1024)
    for {
        n, _ := conn.Read(buf)
        if n == 0 {
            fmt.Println("接收文件完成。")
            return
        }
        // 写入本地文件,读多少,写多少。
        f.Write(buf[:n])
    }
}
 
func main() {
    // 创建用于监听的socket
    listener, err := net.Listen("tcp", "127.0.0.1:8000")
    if err != nil {
        fmt.Println(" net.Listen err:", err)
        return
    }
    defer listener.Close()
 
    fmt.Println("接收端启动成功,等待发送端发送文件!")
 
    // 阻塞监听
    conn, err := listener.Accept()
    if err != nil {
        fmt.Println(" listener.Accept() err:", err)
        return
    }
    defer conn.Close()
 
    // 获取文件名,保存
    buf := make([]byte, 1024)
    n, err := conn.Read(buf)
    if err != nil {
        fmt.Println(" conn.Read err:", err)
        return
    }
    fileName := string(buf[:n])
 
    // 回写 ok 给发送端
    conn.Write([]byte("ok"))
 
    // 获取文件内容
    recvFile(conn, fileName)
}
以上がこの記事の全内容です、皆様の学習のお役に立てれば幸いです。

推奨される学習: 「

ビデオ チュートリアルに進む

以上がGolangでファイル転送機能を実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。