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 ...
随机推荐
- asp.net core中写入自定义中间件
首先要明确什么是中间件?微软官方解释:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/middleware/?tabs=aspnet ...
- js常用 弹出确认 取消对话框
<!DOCTYPE html><html><head> <title></title> <meta charset='utf-8'&g ...
- spring的优缺点
它是一个开源的项目,而且目前非常活跃:它基于IoC(Inversion of Control,反向控制)和AOP的构架多层j2ee系统的框架,但它不强迫 你必须在每一层 中必须使用Spring,因为它 ...
- javap
本词条缺少概述.信息栏.名片图,补充相关内容使词条更完整,还能快速升级,赶紧来编辑吧! javap是jdk自带的一个工具,可以反编译,也可以查看java编译器生成的字节码,是分析代码的一个好工具. j ...
- EF Core使用SQL调用返回其他类型的查询
假设你想要 SQL 本身编写,而不使用 LINQ. 需要运行 SQL 查询中返回实体对象之外的内容. 在 EF Core 中,执行该操作的另一种方法是编写 ADO.NET 代码,并从 EF 获取数据库 ...
- Spring Boot开发MongoDB应用实践
本文继续上一篇定时任务中提到的邮件服务,简单讲解Spring Boot中如何使用MongoDB进行应用开发. 上文中提到的这个简易邮件系统大致设计思路如下: 1.发送邮件支持同步和异步发送两种 2.邮 ...
- 新盘进行LVM的划分
echo "- - -" > /sys/class/scsi_host/host2/scan LVM是 Logical Volume Manager(逻辑卷管理)的简写,它由 ...
- Android Studio 插件开发详解四:填坑
转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/78265540 本文出自[赵彦军的博客] 在前面我介绍了插件开发的基本流程 [And ...
- C# 操作PDF 图层(Layer)——添加、删除图层、设置图层可见性
前言 通过添加图层,我们可以将文本.图片.表格.图形等元素精确定位于页面指定位置,将这些元素进行叠放.组合形成页面的最终效果.此外,对于页面中已有的图层我们也可以进行设置图层可见性.删除图层等操作.因 ...
- 一个简单的小小记账本程序(java)
感觉基础知识学了不少,但是一直搞不清一个项目的实际开发流程,所以就借着这个小记账本的程序梳理一下.因为楼主也是出于学习阶段的菜鸟,所以程序可能会有各种玄学的bug,希望一起提升吧. 跟着站长学到了很多 ...