file.go
package volume
import (
"time"
"encoding/binary"
"errors"
"os"
"io"
)
//文件基本信息结构体
type FileInfo struct {
Fid uint64
Offset uint64
Size uint64
Ctime time.Time
Mtime time.Time
Atime time.Time
FileName string
}
//文件信息编码到切片中
func (iv *FileInfo)MarshalBinary() []byte {
data := make([]byte, 48 + len(iv.FileName))
binary.BigEndian.PutUint64(data[0:8], iv.Fid)
binary.BigEndian.PutUint64(data[8:16], iv.Offset)
binary.BigEndian.PutUint64(data[16:24], iv.Size)
binary.BigEndian.PutUint64(data[24:32], uint64(iv.Ctime.Unix()))
binary.BigEndian.PutUint64(data[32:40], uint64(iv.Mtime.Unix()))
binary.BigEndian.PutUint64(data[40:48], uint64(iv.Atime.Unix()))
copy(data[48:], []byte(iv.FileName))
return data
}
//文件信息解码到结构体中
func (iv *FileInfo)UnMarshalBinary(data []byte) (err error) {
defer func() {
if r := recover(); r != nil {
err = r.(error)
}
}()
iv.Fid = binary.BigEndian.Uint64(data[0:8])
iv.Offset = binary.BigEndian.Uint64(data[8:16])
iv.Size = binary.BigEndian.Uint64(data[16:24])
iv.Ctime = time.Unix(int64(binary.BigEndian.Uint64(data[24:32])), 0)
iv.Mtime = time.Unix(int64(binary.BigEndian.Uint64(data[32:40])), 0)
iv.Atime = time.Unix(int64(binary.BigEndian.Uint64(data[40:48])), 0)
iv.FileName = string(data[48:])
return err
}
//文件结构体
type File struct {
DataFile *os.File
Info *FileInfo
offset uint64 //偏移量
}
//读取文件
func (f *File)Read(b []byte) (n int, err error) {
//计算文件开始读取位置和结束位置
start := f.Info.Offset + f.offset
end := f.Info.Offset + f.Info.Size
length := end - start
if len(b) > int(length) {
b = b[:length]
}
n, err = f.DataFile.ReadAt(b, int64(start)) //读取文件 从start位置开始 读取b个数据
f.offset += uint64(n)
if f.offset >= f.Info.Size {
err = io.EOF
}
return
}
//写文件
func (f *File)Write(b []byte) (n int, err error) {
start := f.Info.Offset + f.offset
end := f.Info.Offset + f.Info.Size
length := end - start
if len(b) > int(length) {
//b = b[:length]
return 0, errors.New("you should create a new File to write")
}else {
n, err = f.DataFile.WriteAt(b, int64(start))
f.offset += uint64(n)
return
}
}
//读取文件偏移量
//0意味着相对于文件的原始位置,1意味着相对于当前偏移量,2意味着相对于文件结尾
func (f *File)Seek(offset int64, whence int) (int64, error) {
switch whence {
case 0:
f.offset = uint64(offset)
case 1:
f.offset = uint64(int64(f.offset) + offset)
case 2:
f.offset = uint64(int64(f.Info.Size) + offset)
}
return int64(f.offset), nil
//if f.offset > f.Info.Size {
// f.offset = 0
// return int64(f.offset), errors.New("offset > file.size")
//}else {
// return int64(f.offset), nil
//}
}
file.go的更多相关文章
- 记一个mvn奇怪错误: Archive for required library: 'D:/mvn/repos/junit/junit/3.8.1/junit-3.8.1.jar' in project 'xxx' cannot be read or is not a valid ZIP file
我的maven 项目有一个红色感叹号, 而且Problems 存在 errors : Description Resource Path Location Type Archive for requi ...
- HTML中上传与读取图片或文件(input file)----在路上(25)
input file相关知识简例 在此介绍的input file相关知识为: 上传照片及文件,其中包括单次上传.批量上传.删除照片.增加照片.读取图片.对上传的图片或文件的判断,比如限制图片的张数.限 ...
- logstash file输入,无输出原因与解决办法
1.现象 很多同学在用logstash input 为file的时候,经常会出现如下问题:配置文件无误,logstash有时一直停留在等待输入的界面 2.解释 logstash作为日志分析的管道,在实 ...
- input[tyle="file"]样式修改及上传文件名显示
默认的上传样式我们总觉得不太好看,根据需求总想改成和上下结构统一的风格…… 实现方法和思路: 1.在input元素外加a超链接标签 2.给a标签设置按钮样式 3.设置input[type='file' ...
- .NET平台开源项目速览(16)C#写PDF文件类库PDF File Writer介绍
1年前,我在文章:这些.NET开源项目你知道吗?.NET平台开源文档与报表处理组件集合(三)中(第9个项目),给大家推荐了一个开源免费的PDF读写组件 PDFSharp,PDFSharp我2年前就看过 ...
- [笔记]HAproxy reload config file with uninterrupt session
HAProxy is a high performance load balancer. It is very light-weight, and free, making it a great op ...
- VSCode调试go语言出现:exec: "gcc": executable file not found in %PATH%
1.问题描述 由于安装VS15 Preview 5,搞的系统由重新安装一次:在用vscdoe编译go语言时,出现以下问题: # odbcexec: "gcc": executabl ...
- input type='file'上传控件假样式
采用bootstrap框架样式 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> &l ...
- FILE文件流的中fopen、fread、fseek、fclose的使用
FILE文件流用于对文件的快速操作,主要的操作函数有fopen.fseek.fread.fclose,在对文件结构比较清楚时使用这几个函数会比较快捷的得到文件中具体位置的数据,提取对我们有用的信息,满 ...
- ILJMALL project过程中遇到Fragment嵌套问题:IllegalArgumentException: Binary XML file line #23: Duplicate id
出现场景:当点击"分类"再返回"首页"时,发生error退出 BUG描述:Caused by: java.lang.IllegalArgumentExcep ...
随机推荐
- maximun-depth-of-binary-tree
题目: Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the ...
- Qt与FFmpeg联合开发指南(三)——编码(1):代码流程演示
前两讲演示了基本的解码流程和简单功能封装,今天我们开始学习编码.编码就是封装音视频流的过程,在整个编码教程中,我会首先在一个函数中演示完成的编码流程,再解释其中存在的问题.下一讲我们会将编码功能进行封 ...
- 自动红眼移除算法 附c++完整代码
说起红眼算法,这个话题非常古老了. 百度百科上的描述: "红眼"一般是指在人物摄影时,当闪光灯照射到人眼的时候,瞳孔放大而产生的视网膜泛红现象. 由于红眼现象的程度是根据拍摄对象色 ...
- 动态规划:给出两个字符串s1和s2,返回其中最大的公共子串
求公共子字符串问题(连续的) 这个题目是当时远景能源公司现场笔试的一道题目,当时根本就不知道动态规划是什么鬼,直接上来就暴力求解,面试官很谄媚的问我,你这能求出来吗?当时很年轻的说,能啊!现在想,当时 ...
- nginx防盗链
盗链是指一个网站的资源(图片或附件)未经允许在其它网站提供浏览和下载.尤其热门资源的盗链,对网站带宽的消耗非常大,本文通过nginx的配置指令location来实现简单的图片和其它类型文件的防盗链. ...
- .gitignore文件不起作用的解决方法
http://keendawn.blog.163.com/blog/static/88880743201531554431124/ git rm -r --cached . git add . git ...
- Oracle基础快速入门
数据库体系结构 物理存储结构与Oracle启动时关系是 依次打开 参数(startup nomount).控制(startup mount).数据文件(open) 物理存储结构:指实际的文件存储形式 ...
- Hibernate二级缓存简述及基于Spring4,Hibernate5,Ehcache3的二级缓存配置
Hibernate L2缓存 缓存的分类 L2缓存工作原理 放入二级缓存的数据 Ehcache 依赖 ehcache.xml 常用的memoryStoreEvictionPolicy(缓存算法) eh ...
- GitHub学习笔记:分支管理
GitHub对于每个开发版本都需要有一个分支,默认的分支是master往往被大家保留下来作为主分支,分支类似于进程的一个指针,往往在master这个稳定的主干版本上分出一个或多个正在开发的分支版本,开 ...
- 洛谷 P1272 解题报告
P1272 重建道路 题目描述 一场可怕的地震后,人们用\(N\)个牲口棚\((1≤N≤150\),编号\(1..N\))重建了农夫\(John\)的牧场.由于人们没有时间建设多余的道路,所以现在从一 ...