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

Golang基于文件魔數(shù)判斷文件類型的案例代碼

 更新時間:2023年02月17日 15:20:51   作者:夢想畫家  
這篇文章主要介紹了Golang基于文件魔數(shù)判斷文件類型,本文介紹了基于文件魔數(shù)判斷文件類型的方法,主要涉及如何ReadSeek讀取文件指定字節(jié)內(nèi)容,然后介紹文件魔數(shù),最后給出示例基于魔數(shù)判斷文件類型,需要的朋友可以參考下

本文介紹基于魔數(shù)判斷文件類型,涉及文件查找讀取內(nèi)容、文件魔數(shù)、字節(jié)比較,最后還介紹函數(shù)參數(shù)的知識。

查找位置

File.Seek()函數(shù)可以設(shè)置偏移位置,為下一次讀或?qū)懘_定偏移量,具體起點有whence確定:0標識相對文件開始位置、1相對當前位置、2相對文件結(jié)尾。函數(shù)返回新的位置及錯誤。請看下面示例:

package main
 
import (
   "os"
   "fmt"
   "log"
)
 
func main() {
   file, _ :- os.Open("test.txt")
   defer file.Close()
 
   // Offset 表示偏移量
   // Offset 可以為正數(shù)或負數(shù)
   var offset int64 - 5
 
   // Whence 偏移參考點,具體取值說明
   // 0 - Beginning of file
   // 1 - Current position
   // 2 - End of file
   var whence int - 0
   newPosition, err :- file.Seek(offset, whence)
   if err !- nil {
      log.Fatal(err)
   }
   fmt.Println("Just moved to 5:", newPosition)
 
   // 從當前位置回走2個字節(jié)
   newPosition, err - file.Seek(-2, 1)
   if err !- nil {
      log.Fatal(err)
   }
   fmt.Println("Just moved back two:", newPosition)
 
   // 通過移動零字節(jié)返回當前位置
   currentPosition, err :- file.Seek(0, 1)
   fmt.Println("Current position:", currentPosition)
 
   // 回到文件起始點
   newPosition, err - file.Seek(0, 0)
   if err !- nil {
      log.Fatal(err)
   }
   fmt.Println("Position after seeking 0,0:", newPosition)
}

執(zhí)行程序結(jié)果如下:

Just moved to 5: 5
Just moved back two: 3
Current position: 3
Position after seeking 0,0: 0

文件類型

魔數(shù)是文件前幾個字節(jié),用于唯一標識文件類型,從而無需關(guān)注復雜文件結(jié)構(gòu)就能夠確定文件類型。舉例,jpeg文件總是ffd8 ffe0。下面列舉常見文件類型的魔數(shù):

  • 圖像文件
File typeTypical extensionHex digits xx - variableAscii digits . - not an ascii char
Bitmap format.bmp42 4dBM
FITS format.fits53 49 4d 50 4c 45SIMPLE
GIF format.gif47 49 46 38GIF8
Graphics Kernel System.gks47 4b 53 4dGKSM
IRIS rgb format.rgb01 da
ITC (CMU WM) format.itcf1 00 40 bb
JPEG File Interchange Format.jpgff d8 ff e0
NIFF (Navy TIFF).nif49 49 4e 31IIN1
PM format.pm56 49 45 57VIEW
PNG format.png89 50 4e 47.PNG
Postscript format.[e]ps25 21%!
Sun Rasterfile.ras59 a6 6a 95Y.j.
Targa format.tgaxx xx xx
TIFF format (Motorola - big endian).tif4d 4d 00 2aMM.*
TIFF format (Intel - little endian).tif49 49 2a 00II*.
X11 Bitmap format.xbmxx xx
XCF Gimp file structure.xcf67 69 6d 70 20 78 63 66 20 76gimp xcf
Xfig format.fig23 46 49 47#FIG
XPM format.xpm2f 2a 20 58 50 4d 20 2a 2f/* XPM */
  • 壓縮文件類型
File typeTypical extensionHex digits xx = variableAscii digits . = not an ascii char
Bzip.bz42 5aBZ
Compress.Z1f 9d
gzip format.gz1f 8b
pkzip format.zip50 4b 03 04PK…
  • 歸檔文件類型
File typeTypical extensionHex digits xx = variableAscii digits . = not an ascii char
TAR (pre-POSIX).tarxx xx(a filename)
TAR (POSIX).tar75 73 74 61 72ustar (offset by 257 bytes)
  • 可執(zhí)行文件類型
File typeTypical extensionHex digits xx = variableAscii digits . = not an ascii char
MS-DOS, OS/2 or MS Windows4d 5aMZ
Unix elf7f 45 4c 46.ELF

有了上面的基礎(chǔ)知識,我們就可以讀文件前幾個字節(jié)判斷文件類型。

實現(xiàn)基礎(chǔ)函數(shù)

首先定義文件魔數(shù)標識變量:

var(
   PDF        = []byte{0x25, 0x50, 0x44, 0x46}
	RAR        = []byte{0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x00}
	GZIP       = []byte{0x1F, 0x8B, 0x08}
	ZIP_0      = []byte{0x50, 0x4B, 0x03, 0x04}
	ZIP_1      = []byte{0x50, 0x4B, 0x05, 0x06}
	ZIP_2      = []byte{0x50, 0x4B, 0x07, 0x08}
	WEBP       = []byte{0x52, 0x49, 0x46, 0x46}
   ...
)

下面定義幾個讀文件函數(shù)。

首先是從ReadSeeker開始位置起讀取幾個字節(jié)函數(shù):

func readUntil(l int, r io.ReadSeeker) ([]byte, error) {
	buff := make([]byte, l)

	_, err := r.Read(buff)
	if err != nil {
		return nil, err
	}

	r.Seek(0, io.SeekStart)

	return buff, nil
}

基于魔數(shù)字節(jié)數(shù)組讀文件魔數(shù):

func checkBuffer(r io.ReadSeeker, t []byte) ([]byte, error) {
   // 根據(jù)提供參數(shù)獲取長度
	l := len(t)

	buff, err := readUntil(l, r)
	if err != nil {
		return make([]byte, 0), err
	}

	return buff, nil
}

基于參數(shù)比較文件魔數(shù):

func genericCompareBuffer(r io.ReadSeeker, t []byte) bool {
	buff, err := checkBuffer(r, t)
	if err != nil {
		return false
	}

	valid := bytes.Compare(t, buff)
	return valid == 0
}

比較文件包括多個魔數(shù)情況比較:

func genericMultipleCompareBuffer(r io.ReadSeeker, t [][]byte) bool {
	buff, err := checkBuffer(r, t[0])
	if err != nil {
		return false
	}

	for _, v := range t {
		if bytes.Compare(v, buff) == 0 {
			return true
		}
	}

	return false
}

類型判斷函數(shù)

有了上面的基礎(chǔ)函數(shù),我們可以提供上層應(yīng)用接口函數(shù)。

首先是常用類型判斷函數(shù),注意這里PNG、JPEG是前面定義的字節(jié)數(shù)組變量。

// IsPng function will return true if File is a valid PNG
func IsPng(r io.ReadSeeker) bool {
	return genericCompareBuffer(r, PNG)
}

// IsJpeg function will return true if File is a valid JPEG
func IsJpeg(r io.ReadSeeker) bool {
	return genericCompareBuffer(r, JPEG)
}

// IsPdf function will return true if File is a valid PDF
func IsPdf(r io.ReadSeeker) bool {
	return genericCompareBuffer(r, PDF)
}

// IsGif function will return true if File is a valid GIF
func IsGif(r io.ReadSeeker) bool {
	return genericCompareBuffer(r, GIF)
}

同類文件可能有不同魔數(shù)場景:

// IsMpg function will return true if File is a valid MPG
func IsMpg(r io.ReadSeeker) bool {
	return genericMultipleCompareBuffer(r, [][]byte{
		MPG_0,
		MPG_1,
	})
}

最后提供一個同時判斷多種文件類型的函數(shù),利用函數(shù)類型參數(shù):

// IsOneOf function will validate File with multiple function
func IsOneOf(r io.ReadSeeker, functions ...function) bool {
	for _, f := range functions {
		valid := f(r)
		if valid {
			return true
		}
	}

	return false
}

測試代碼

下面測試前面定義的函數(shù),函數(shù)包括文件名稱參數(shù),判斷該文件類型:

package main

import (
	"fmt"
	"os"
)

func main() {
	args := os.Args

	if len(args) < 2 {
		fmt.Println("required input file")
		os.Exit(1)
	}

   // 打開文件
	inputFileArg := args[1]
	inFile, err := os.Open(inputFileArg)

	if err != nil {
		fmt.Println("error open input file ", err)
		os.Exit(1)
	}

   // 支持錯誤處理的關(guān)閉方式
	defer func() { 
      err := inFile.Close() 
      if err != nil {
         fmt.Println("error close input file ", err)
      }
   }()

   // 一次性判斷多種類型,如:是否為圖像文件
	valid := IsOneOf(inFile, filesig.Is3gp, filesig.IsPng, filesig.IsJpeg)
	fmt.Println(valid)

   // 當然也可以判斷單個類型
   valid = filesig.Is3gp(inFile)
	fmt.Println(valid)
}

總結(jié)

本文介紹了基于文件魔數(shù)判斷文件類型的方法,主要涉及如何ReadSeek讀取文件指定字節(jié)內(nèi)容,然后介紹文件魔數(shù),最后給出示例基于魔數(shù)判斷文件類型。參考代碼:https://github.com/telkomdev/go-filesig

到此這篇關(guān)于Golang基于文件魔數(shù)判斷文件類型的文章就介紹到這了,更多相關(guān)go文件類型內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • go特性之數(shù)組與切片的問題

    go特性之數(shù)組與切片的問題

    這篇文章主要介紹了go特性之數(shù)組與切片的問題,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • Go語言Gin處理響應(yīng)方式詳解

    Go語言Gin處理響應(yīng)方式詳解

    gin框架封裝了常用的數(shù)據(jù)格式方法響應(yīng)于客戶端,下面這篇文章主要給大家介紹了關(guān)于Go語言Gin處理響應(yīng)方式的相關(guān)資料,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2023-01-01
  • golang interface指針實現(xiàn)示例

    golang interface指針實現(xiàn)示例

    本文主要介紹了golang interface指針實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-08-08
  • Go并發(fā)4種方法簡明講解

    Go并發(fā)4種方法簡明講解

    這篇文章主要介紹了Go并發(fā)4種方法簡明講解,需要的朋友可以參考下
    2022-04-04
  • Go Plugins插件的實現(xiàn)方式

    Go Plugins插件的實現(xiàn)方式

    目前 Plugins 僅在 Linux、FreeBSD 和 macOS 上受支持,且只支持 golang 調(diào)用,今天通過本文給大家介紹Go Plugins插件的實現(xiàn)方式,感興趣的朋友一起看看吧
    2021-08-08
  • 使用dep 配置golang 開發(fā)環(huán)境的操作方法

    使用dep 配置golang 開發(fā)環(huán)境的操作方法

    下面小編就為大家?guī)硪黄褂胐ep 配置golang 開發(fā)環(huán)境的操作方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • Go語言基礎(chǔ)go接口用法示例詳解

    Go語言基礎(chǔ)go接口用法示例詳解

    這篇文章主要為大家介紹了Go語言基礎(chǔ)關(guān)于go接口的用法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,在日升職加薪
    2021-11-11
  • 使用Go語言進行條件編譯的示例代碼

    使用Go語言進行條件編譯的示例代碼

    Go的條件編譯主要通過構(gòu)建標簽(build?tags)和構(gòu)建約束(build?constraints)來實現(xiàn),這些標簽和約束可以讓我們針對不同的操作系統(tǒng)、架構(gòu)或特定條件編寫特定代碼,本文給大家介紹了如何使用Go語言進行條件編譯,需要的朋友可以參考下
    2024-06-06
  • Golang HTTP請求Json響應(yīng)解析方法以及解讀失敗的原因

    Golang HTTP請求Json響應(yīng)解析方法以及解讀失敗的原因

    這篇文章主要介紹了Golang HTTP請求Json響應(yīng)解析方法以及解讀失敗的原因,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • golang使用DockerFile正確用法指南

    golang使用DockerFile正確用法指南

    docker在開發(fā)和運維中使用的場景越來越多,作為開發(fā)人員非常有必要了解一些docker的基本知識,而離我們工作中最近的也就是對應(yīng)用的docker部署編排了,這篇文章主要給大家介紹了關(guān)于golang使用DockerFile的正確用法指南,需要的朋友可以參考下
    2024-03-03

最新評論

阳西县| 康保县| 文安县| 广宁县| 延庆县| 霸州市| 台北县| 新疆| 永泰县| 思南县| 开阳县| 凤庆县| 富锦市| 乌拉特后旗| 吴旗县| 临江市| 阿克陶县| 陵川县| 正镶白旗| 潞城市| 监利县| 肥西县| 万宁市| 深水埗区| 文安县| 富锦市| 日土县| 黎平县| 南雄市| 肇源县| 娄烦县| 盐亭县| 临朐县| 聂拉木县| 连江县| 安宁市| 兴国县| 施甸县| 山西省| 张北县| 喀喇沁旗|