1. 程式人生 > 程式設計 >golang實現ftp實時傳輸檔案的案例

golang實現ftp實時傳輸檔案的案例

一、專案簡介

本專案主要實現的功能是ftp客戶端不斷地將xml檔案和jpg檔案實時地上傳到伺服器,當然也可以是其他格式的檔案。每當ftp客戶端取到一個檔案之後,將檔案上傳到伺服器後,然後將其刪除。

專案實現可配置,如果開發者有類似的需求,只需要修改配置檔案就可以使用本專案去完成上傳檔案的功能。

本專案打日誌是按照當天時間來生成日誌檔案,每天每一種型別的日誌只打一個檔案。

二、專案結構圖片

golang實現ftp實時傳輸檔案的案例

三、專案程式碼

config配置中的程式碼

config.ini

[path]
  xml_path     = D:\\dian\\out\\    # xml檔案所在的路徑
  img_path     = D:\\dian\\out\\wave\\ # 圖片檔案所在路徑
[ftp]
  ftpfile_path   = D:\\Itudou       # 在伺服器上的檔案儲存路徑
  ftp_server_ip  = 192.168.56.1      # ftp伺服器的IP
  ftp_server_port = 21           # ftp伺服器的埠
  ftp_server_name = 20123762        # ftp伺服器的使用者名稱
  ftp_server_pwd  = 123456         # ftp伺服器的密碼
  local_ip     = 192.168.56.1      # 本地主機的IP
  local_port    = 80           #本地主機埠
  comm_way     = udp          #ftp的通訊方式
[file]
  file_img     =.jpg          #檔案字尾為img
  file_xml     =.xml          #檔案字尾為xml
  log_print    = ture          #是否打日誌,生產環境上不打日誌,在調式程式的時候使用

讀配置檔案的程式碼

daos_config.go

package daosconfig
import (
  "bufio"
  "io"
  "os"
  "strings"
)
type Config struct {
  Mymap map[string]string
  strcet string
}
func (c *Config) InitConfig(path string) {
  c.Mymap = make(map[string]string)
  f,err := os.Open(path)
  if err != nil {
    panic(err)
  }
  defer f.Close()
  r := bufio.NewReader(f)
  for {
    b,_,err := r.ReadLine()
    if err != nil {
      if err == io.EOF {
        break
      }
      panic(err)
    }
    s := strings.TrimSpace(string(b))
    if strings.Index(s,"#") == 0 {
      continue
    }
    n1 := strings.Index(s,"[")
    n2 := strings.LastIndex(s,"]")
    if n1 > -1 && n2 > -1 && n2 > n1+1 {
      c.strcet = strings.TrimSpace(s[n1+1 : n2])
      continue
    }
    if len(c.strcet) == 0 {
      continue
    }
    index := strings.Index(s,"=")
    if index < 0 {
      continue
    }
    frist := strings.TrimSpace(s[:index])
    if len(frist) == 0 {
      continue
    }
    second := strings.TrimSpace(s[index+1:])
    pos := strings.Index(second,"\t#")
    if pos > -1 {
      second = second[0:pos]
    }
    pos = strings.Index(second," #")
    if pos > -1 {
      second = second[0:pos]
    }
    pos = strings.Index(second,"\t//")
    if pos > -1 {
      second = second[0:pos]
    }
    pos = strings.Index(second," //")
    if pos > -1 {
      second = second[0:pos]
    }
    if len(second) == 0 {
      continue
    }
    key := c.strcet + "=" + frist
    c.Mymap[key] = strings.TrimSpace(second)
  }
}
func (c Config) Read(node,key string) string {
  key = node + "=" + key
  v,found := c.Mymap[key]
  if !found {
    return ""
  }
  return v
}

ftp上傳檔案核心程式碼

daos_ftp.go

package daosftp
import (
  "fmt"
  "net"
  "os"
  "strings"
  ftp "github.com/ftp"
  "io/ioutil"
  "regexp"
  "path/filepath"
  cfg "bjdaos_tool/pkg/daosconfig"
  "bjdaos_tool/pkg/env"
  "bjdaos_tool/pkg/daoslog"
)
func getListDir(dirPth string) (files []string,files1 []string,err error) {
  dir,err := ioutil.ReadDir(dirPth)
  if err != nil {
    return nil,nil,err
  }
  PthSep := string(os.PathSeparator)
  for _,fi := range dir {
    if fi.IsDir() {
      files1 = append(files1,dirPth+PthSep+fi.Name())
      getListDir(dirPth + PthSep + fi.Name())
    }else{
      files = append(files,dirPth+PthSep+fi.Name())
    }
  }
  return files,files1,nil
}
func GetAllFileName(path string,str string) (int,[]string ) {
  configPath := env.GetConfigPath()
  ftpConfig := new(cfg.Config)
  ftpConfig.InitConfig(configPath + "\\config.ini")
  logPrint := ftpConfig.Read("file","log_print")
  files,err := getListDir(path)
  if err != nil {
    daoslog.WriteLog(logPrint,"System","get file path err")
  }
  fileLen := len(files)
  fileSlice := make([]string,fileLen)
  suffix1 := ftpConfig.Read("file","file_img")
  suffix2 := ftpConfig.Read("file","file_xml")
  reg_front := regexp.MustCompile("\\d{8}")
  reg_end := regexp.MustCompile("\\d{14}")
  if str == suffix1{
    for i := 0; i < fileLen; i++{
      data_front := reg_front.FindString(files[i])
      date_end := reg_end.FindString(files[i])
      imgName := data_front + "_" + date_end + str
      fileSlice = append(fileSlice,imgName)
    }
  }else if str == suffix2 {
    for i := 0; i < fileLen; i++{
      data_front := reg_front.FindString(files[i])
      date_end := reg_end.FindString(files[i])
      imgName := data_front + "_" + date_end + str
      fileSlice = append(fileSlice,imgName)
    }
  }
  return fileLen,fileSlice
}
func getLocalIpAddr() string {
  configPath := env.GetConfigPath()
  ftpConfig := new(cfg.Config)
  ftpConfig.InitConfig(configPath + "\\config.ini")
  logPrint := ftpConfig.Read("file","log_print")
  network := ftpConfig.Read("ftp","comm_way")
  ip := ftpConfig.Read("ftp","local_ip")
  port := ftpConfig.Read("ftp","local_port")
  address := ip + ":" + port
  conn,err := net.Dial(network,address)
  if err != nil {
    daoslog.WriteLog(logPrint,"get local ip address err")
    return "127.0.0.1"
  }
  defer conn.Close()
  return strings.Split(conn.LocalAddr().String(),":")[0]
}
func ftpUploadFile(ftpserver,ftpuser,pw,localFile,remoteSavePath,saveName string) {
  configPath := env.GetConfigPath()
  ftpConfig := new(cfg.Config)
  ftpConfig.InitConfig(configPath + "\\config.ini")
  logPrint := ftpConfig.Read("file","log_print")
  ftpfile_path := ftpConfig.Read("ftp","ftpfile_path")
  ftp,err := ftp.Connect(ftpserver)
  if err != nil {
    daoslog.WriteLog(logPrint,"connect err")
  }
  err = ftp.Login(ftpuser,pw)
  if err != nil {
    daoslog.WriteLog(logPrint,"Login err")
  }
  ftp.ChangeDir(ftpfile_path)
  dir,err := ftp.CurrentDir()
  ftp.MakeDir(remoteSavePath)
  ftp.ChangeDir(remoteSavePath)
  dir,_ = ftp.CurrentDir()
  daoslog.WriteLog(logPrint,dir)
  file,err := os.Open(localFile)
  if err != nil {
    daoslog.WriteLog(logPrint,"Open err")
  }
  defer file.Close()
  err = ftp.Stor(saveName,file)
  if err != nil {
    daoslog.WriteLog(logPrint,"Stor err")
  }
  ftp.Logout()
  ftp.Quit()
  logcotent := fmt.Sprintf("%s:%s","success upload file",localFile)
  daoslog.WriteLog(logPrint,logcotent)
}
func RemoveFile(filePath string,fileName string){
  configPath := env.GetConfigPath()
  ftpConfig := new(cfg.Config)
  ftpConfig.InitConfig(configPath + "\\config.ini")
  logPrint := ftpConfig.Read("file","log_print")
  err := os.Remove(filePath + fileName)
  if err != nil {
    daoslog.WriteLog("false","file remove err!")
  } else {
    logcotent := fmt.Sprintf("%s:%s","file remove OK!",fileName)
    daoslog.WriteLog(logPrint,logcotent)
  }
}
func SendXmlFileToFtpServer(filePath string,fileType string) {
  configPath := env.GetConfigPath()
  ftpConfig := new(cfg.Config)
  ftpConfig.InitConfig(configPath + "\\config.ini")
  logPrint := ftpConfig.Read("file","log_print")
  flen,fileName := GetAllFileName(filePath,fileType)
  serverIp := getLocalIpAddr()
  ftpserverip := ftpConfig.Read("ftp","ftp_server_ip")
  ftpPort := ftpConfig.Read("ftp","ftp_server_port")
  ftpuser := ftpConfig.Read("ftp","ftp_server_name")
  pw := ftpConfig.Read("ftp","ftp_server_pwd")
  ftpserver := ftpserverip + ":" + ftpPort
  filepath.Walk(filePath,func(path string,f os.FileInfo,err error) error {
    if f == nil {
      return err
    }
    if f.IsDir() {
      return nil
    }
    for i := 0; i < flen; i++{
      if f.Name() == fileName[i] {
        logcotent := fmt.Sprintf("path=",path)
        daoslog.WriteLog(logPrint,logcotent)
        pathFields := strings.Split(path,"\\")
        var domainName string
        if len(pathFields) > 3 {
          domainName = pathFields[len(pathFields)-3]
        }
        ftpUploadFile(ftpserver,path,domainName,serverIp+"_"+fileName[i])
        RemoveFile(filePath,fileName[i])
      }
    }
    return nil
  })
}
func SendJpgFileToFtpServer(filePath string,fileName[i])
      }
    }
    return nil
  })
}

打日誌的程式碼

daos_log.go

package daoslog
import (
  "fmt"
  "log"
  "os"
  "github.com/golang/glog"
  "time"
  "bjdaos_tool/pkg/env"
)
func WriteLog(islog,logtype,errcontent string) {
  if islog == "false" {
    return
  }
  if logtype != "Info" && logtype!= "Debug" && logtype!= "Error" && logtype != "System" {
    glog.Error("this is not a logtype ")
    return
  }
  data := time.Now().Format("20060102")
  logPath := env.GetConLogPath()
  logFilea := logPath + "\\" + data+"_"+ logtype+".log"
  errcontent = "[" +errcontent + "]"
  logFile,err := os.OpenFile(logFilea,os.O_RDWR | os.O_CREATE,0777)
  if err != nil {
    fmt.Printf("open file error=%s\r\n",err.Error())
    os.Exit(-1)
  }
  logger := log.New(logFile,"{"+logtype+"} ",log.Ldate | log.Ltime | log.Lshortfile)
  logger.Println(errcontent)
}

路徑處理程式碼

daos-evn.go

package env
import (
  "os"
  "runtime"
)
var ostype = runtime.GOOS
func GetProjectPath() string{
  var projectPath string
  projectPath,_ = os.Getwd()
  return projectPath
}
func GetConfigPath() string{
  path := GetProjectPath()
  if ostype == "windows"{
    path = path + "\\" + "config\\"
  }else if ostype == "linux"{
    path = path +"/" + "config/"
  }
  return path
}
func GetConLogPath() string{
  path := GetProjectPath()
  if ostype == "windows"{
    path = path + "\\log\\"
  }else if ostype == "linux"{
    path = path + "/log/"
  }
  return path
}

四、總結

主函式:

main.go

package main
import (
  "bjdaos_tool/pkg/daosftp"
  "bjdaos_tool/pkg/env"
  cfg "bjdaos_tool/pkg/daosconfig"
)
func main(){
  configPath := env.GetConfigPath()
  ftpConfig := new(cfg.Config)
  ftpConfig.InitConfig(configPath + "\\config.ini")
  xml_path := ftpConfig.Read("path","xml_path")
  img_path := ftpConfig.Read("path","img_path")
  file_img := ftpConfig.Read("file","file_img")
  file_xml := ftpConfig.Read("file","file_xml")
  for{
    daosftp.SendXmlFileToFtpServer(xml_path,file_xml)
    daosftp.SendJpgFileToFtpServer(img_path,file_img)
  }
}

本專案依賴包:

golang實現ftp實時傳輸檔案的案例

完整程式碼:https://github.com/guoshijiang/go_ftp

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援我們。如有錯誤或未考慮完全的地方,望不吝賜教。