最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Golang實現(xiàn)超時機制讀取文件的方法示例

 更新時間:2025年01月10日 10:55:15   作者:夢想畫家  
讀寫文件是Go程序的基本任務,包括使用程序查看文件內容、創(chuàng)建或修改文件,Go提供了os,ioutil,io以及bufio包實現(xiàn)文件操作,本文介紹如果在讀文件過程中增加超時機制,避免文件太大一直占用資源,需要的朋友可以參考下

協(xié)程與通道

協(xié)程(Goroutine)是輕量級線程,可實現(xiàn)函數(shù)或方法與主程序流并行執(zhí)行。使用go關鍵字:go func(){}。通道是協(xié)程直接的通訊管道,主要用于在協(xié)程間傳輸數(shù)據(jù),即往通道寫數(shù)據(jù)、從通道讀數(shù)據(jù)。

通過chan關鍵字聲明通道,可以使用var或:=兩種方式聲明,也可以聲明待緩存的通道,語法如下:

channelName:= make(chan Type, n)

舉例:

dataStream := make(chan string, 1)

往通道寫數(shù)據(jù):

dataStream <- "data"

從通道讀數(shù)據(jù):

varName := <-dataStream

關閉通道:

close(dataStream)

Go 超時機制

超時對于連接到外部資源或需要限制執(zhí)行時間的場景來說非常重要。這是因為太長的服務器端處理將消耗太多的資源,導致并發(fā)性下降,甚至服務不可用。

利用select語句及并行協(xié)程實現(xiàn)超時,必須導入time包。然后使用time.After()參數(shù)創(chuàng)建通道,調用time.After(1 * time.Second)將在1秒后填充通道。下面示例通過通道和select實現(xiàn)超時:

package main
import (
    "fmt"
    "time"
)
func main() {
    dataChannel:= make(chan string, 1)

    go func() {
        time.Sleep(2 * time.Second)
        dataChannel <- "result 1"
    }()

    select {
        case results := <- dataChannel:
            fmt.Println(results)
        case <-time.After(1 * time.Second):
            fmt.Println("timeout 1")
    }
}

首先創(chuàng)建緩存通道dataChannel,調用函數(shù)模擬復雜業(yè)務,2秒后從非阻塞通道返回結果。select語句實現(xiàn)超時。results := <- dataChannel等待結果,time.After(1 * time.Second)語句1秒后返回值,因此select首先等待1秒,超過1秒將超時。

下面利用該機制實現(xiàn)讀取文件超時機制實現(xiàn)。

讀取整個文件

Go中讀整個文件一般使用ioutil/os包中的Read File()函數(shù),讀取整個文件值字節(jié)slice。ioutil包最好別用于讀取大文件,對于小文件完全夠用。

os包包含執(zhí)行參數(shù)數(shù)組Args,包括執(zhí)行命令的所有參數(shù),為字符串類型數(shù)組。

package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"strconv"
	"time"
)

func main() {

	filePath := os.Args[1]
	timeOut, _ := strconv.ParseFloat(os.Args[2], 64)

	// buffered channel of dataStream
	dataStream := make(chan string, 1)
	// Run ReadFileToString function in it's own goroutine and pass back it's
	// response into dataStream channel.
	go func() {
		data, _ := ReadFileToString(filePath)
		dataStream <- data
		close(dataStream)
	}()

	// Listen on dataStream channel AND a timeout channel - which ever happens first.
	select {
	case res := <-dataStream:
		fmt.Println(res)
	case <-time.After(time.Duration(timeOut) * time.Second):
		fmt.Println("Program execution out of time ")
	}
}
func ReadFileToString(file string) (string, error) {
	content, err := ioutil.ReadFile(file)
	// error encountered during reading the data
	if err != nil {
		return "", err
	}
	// convert bytes to string
	return string(content), nil
}

我們可以使用不同的超時時間進行測試:

go run main.go text.txt 1.0

go run main.go text.txt 0.9

按行讀文件

可以使用 bufio.Scanner 按行讀文件,使用bufio.NewScanner(file)構造函數(shù)創(chuàng)建Scanner,然后通過Scan()和Text()方法逐行讀取內容。使用Err()方法檢查讀取文件過程中的錯誤。

package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"strconv"
	"time"
)

func main() {
	//get filepath and timeout on the terminal
	filePath := os.Args[1]
	timeOut, _ := strconv.ParseFloat(os.Args[2], 64)
	//creating  channels
	dataStream := make(chan string, 1)
	readerr := make(chan error)

	// Run ReadFileLineByLine function in its own goroutine and pass back it's
	// response into dataStream channel.
	go ReadFileLineByLine(filePath, dataStream, readerr)

loop:
	for {
		// select statement will block this thread until one of the three conditions below is met

		select {
		case data := <-dataStream:
			// Process each line
			fmt.Println(data)
		case <-time.After(time.Duration(timeOut) * time.Second):
			fmt.Println("Program execution out of time ")
			break loop
		case err := <-readerr:
			if err != nil {
				log.Fatal(err)
			}
			break loop
		}
	}
}

func ReadFileLineByLine(filePath string, data chan string, er chan error) {
	// open file
	file, err := os.Open(filePath)
	if err != nil {
		fmt.Println(err)
	}
	// close the file at the end of the program
	defer file.Close()

	// read the file line by line using scanner
	scanner := bufio.NewScanner(file)

	for scanner.Scan() {
		data <- scanner.Text()
	}
	close(data) // close causes the range on the channel to break out of the loop
	er <- scanner.Err()
}

當然也可以使用不同超時時間進行測試,如超時場景:

go run main.go test.txt 0.1
# Program execution out of time

按塊方式讀文件

對于非常大的文件使用塊方式讀取非常有用,無需把整個文件加載到內存中,每次讀取固定塊大小內容。下面readFileChunk函數(shù)中需要創(chuàng)建緩沖區(qū),每次讀取該緩沖區(qū)大小的內容,直到io.EOF錯誤出現(xiàn),表明已經(jīng)到達文件結尾。

緩沖區(qū)大小、目標文件以及超時時間作為函數(shù)參數(shù),其他邏輯與上面示例一致:

package main

import (
   "fmt"
   "io"
   "log"
   "os"
   "strconv"
   "time"
)

func main() {
   dataStream := make(chan string, 1)
   filePath := os.Args[1]
   timeOut, _ := strconv.ParseFloat(os.Args[2], 64)
   chunkSize, _ := strconv.Atoi(os.Args[3])
   go readFileChunk (filePath, dataStream, int64(chunkSize))
   select {
   case resultData := <- dataStream:
      fmt.Println(resultData)
   case <-time.After(time.Duration(timeOut) * time.Millisecond):
      fmt.Println("timeout")
   }

}

func readFileChunk(filePath string, data chan string, chunkSize int64) {
   // open file
   f, err := os.Open(filePath)
   if err != nil {
      log.Fatal(err)
   }
   // remember to close the file at the end of the program
   defer f.Close()

   buf := make([]byte, chunkSize)
   for {
      readTotal, err := f.Read(buf)
      if err != nil && err != io.EOF {
         log.Fatal(err)
      }

      if err == io.EOF {
         break
      }

      data <- string(buf[:readTotal])
   }
   close(data)
}

總結

對于資源密集型程序正在執(zhí)行時,Golang超時機制是必要的,它有助于終止這種冗長的程序。本文通過示例展示了不同方式讀取文件的超時機制實現(xiàn)。

到此這篇關于Golang實現(xiàn)超時機制讀取文件的方法示例的文章就介紹到這了,更多相關Golang超時機制讀取文件內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Go語言開發(fā)區(qū)塊鏈只需180行代碼(推薦)

    Go語言開發(fā)區(qū)塊鏈只需180行代碼(推薦)

    這篇文章主要介紹了Go語言開發(fā)區(qū)塊鏈只需180行代碼,文章中將不會涉及工作量證明算法(PoW)以及權益證明算法(PoS)這類的共識算法。需要的朋友可以參考下
    2018-05-05
  • Go語言實現(xiàn)文件上傳

    Go語言實現(xiàn)文件上傳

    這篇文章主要為大家詳細介紹了Go語言實現(xiàn)文件上傳,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • Golang學習之內存逃逸分析

    Golang學習之內存逃逸分析

    內存逃逸分析是go的編譯器在編譯期間,根據(jù)變量的類型和作用域,確定變量是堆上還是棧上。本文將帶大家分析一下Golang中的內存逃逸,需要的可以了解一下
    2023-01-01
  • Go使用sync.Pool提高性能的代碼示例

    Go使用sync.Pool提高性能的代碼示例

    在高性能應用程序中,頻繁的內存分配和回收是性能瓶頸的常見原因之一,Go 語言提供了 sync.Pool 類型,它可以用來存儲和重用臨時對象,本文將詳細介紹如何在 Go 中使用 sync.Pool,并通過實際代碼示例來展示其對性能的提升效果,需要的朋友可以參考下
    2024-04-04
  • Golang多線程爬蟲高效抓取大量數(shù)據(jù)的利器

    Golang多線程爬蟲高效抓取大量數(shù)據(jù)的利器

    Golang多線程爬蟲是一種高效抓取大量數(shù)據(jù)的利器。Golang語言天生支持并發(fā)和多線程,可以輕松實現(xiàn)多線程爬蟲的開發(fā)。通過使用Golang的協(xié)程和通道,可以實現(xiàn)爬蟲的高效并發(fā)抓取、數(shù)據(jù)處理和存儲
    2023-05-05
  • Go內置零值標識符zero

    Go內置零值標識符zero

    大家學習和使用?Go?語言時,有一個神奇的概念:零值(zero-values),所以本文想給大家分享一個關于零值的新提案,目測已經(jīng)八九不離十了
    2023-08-08
  • Go語言中一些不常見的命令參數(shù)詳解

    Go語言中一些不常見的命令參數(shù)詳解

    這篇文章主要給大家介紹了關于Go語言中一些不常見的命令參數(shù)的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。
    2017-12-12
  • GO接收GET/POST參數(shù)及發(fā)送GET/POST請求的實例詳解

    GO接收GET/POST參數(shù)及發(fā)送GET/POST請求的實例詳解

    這篇文章主要介紹了GO接收GET/POST參數(shù)及發(fā)送GET/POST請求,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • Golang 字符串轉time類型實現(xiàn)

    Golang 字符串轉time類型實現(xiàn)

    本文主要介紹了Golang 字符串轉time類型實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-03-03
  • 使用go讀取gzip格式的壓縮包的操作

    使用go讀取gzip格式的壓縮包的操作

    這篇文章主要介紹了使用go讀取gzip格式的壓縮包的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12

最新評論

邵武市| 延津县| 资阳市| 深州市| 鄂托克前旗| 花垣县| 山西省| 南开区| 武乡县| 贵德县| 静安区| 太原市| 三江| 鸡东县| 廊坊市| 巩留县| 旬阳县| 额济纳旗| 宁晋县| 和平区| 封丘县| 丽水市| 民勤县| 甘肃省| 义乌市| 石嘴山市| 上思县| 泊头市| 年辖:市辖区| 江源县| 栾川县| 玉门市| 凤城市| 沂源县| 延庆县| 大洼县| 长泰县| 韶山市| 夹江县| 连云港市| 舟曲县|