代码拉取完成,页面将自动刷新
package block
import (
"bufio"
"encoding/base64"
"errors"
"fmt"
"io"
"os"
"sync"
)
type FileBlockCache struct {
sizeMB int
mutex *sync.Mutex // 互斥锁
blocks [][]byte // 分块空间
}
// New 实例
func New() *FileBlockCache {
return &FileBlockCache{
sizeMB: 1024 * 1024, // 默认1MB
mutex: &sync.Mutex{},
}
}
// ReadBlocks 读取文件块列表
func (c *FileBlockCache) ReadBlocks(filePath string, blockSizeMb int) ([][]byte, error) {
c.mutex.Lock()
// 关闭锁
defer c.mutex.Unlock()
// 是否已经开始截取分组Block
if len(c.blocks) > 0 {
return c.blocks, nil
}
// 切块尺寸不能小于等于0
if c.sizeMB <= 0 || blockSizeMb <= 0 {
return nil, errors.New(`block size not lte zero`)
}
// 打开准备拆分的文件
file, err := os.Open(filePath)
if err != nil {
return nil, fmt.Errorf(`open file failed %w`, err)
}
// 使用完成关闭
defer func() { _ = file.Close() }()
// 初始化一下
var (
reader = bufio.NewReader(file)
blockSize = blockSizeMb * c.sizeMB
)
// 迭代处理
for {
buffer := make([]byte, blockSize) // 每次循环都创建一个新的缓冲区,接收新截取的文件内容
// 读取内容
n, err := reader.Read(buffer)
if err == io.EOF {
// 截取最后的文件内容
if n > 0 {
c.blocks = append(c.blocks, buffer[:n])
}
break
}
// 其他错误
if err != nil {
return nil, fmt.Errorf(`read block content failed %w`, err)
}
// 刷新到块空间(注:后续可以考虑把内存缓存改成其他缓存,例如:存储到临时文件块,或中间件,避免后续文件太大截取分组消耗完系统内存)
c.blocks = append(c.blocks, buffer[:n])
}
return c.blocks, nil
}
// ToBase64 读取文件块并转换为base64
func (c *FileBlockCache) ToBase64(filePath string, blockSizeMB int) ([]string, error) {
blocks, err := c.ReadBlocks(filePath, blockSizeMB)
if err != nil {
return nil, err
}
baseBlocks := make([]string, 0)
for _, block := range blocks {
baseBlocks = append(baseBlocks, base64.StdEncoding.EncodeToString(block))
}
return baseBlocks, nil
}
// SetSizeMb 设置切块单位,默认1MB
func (c FileBlockCache) SetSizeMb(sizeMb int) {
c.sizeMB = sizeMb
}
// GetBlocks 获取文件块空间
func (c *FileBlockCache) GetBlocks() [][]byte {
return c.blocks
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。