go基础库之在文件中寻找位置

栏目: Go · 发布时间: 5年前

内容简介:在某些情况下,需要从文件中的特定位置读取或写入,例如索引文件。本文将向你展示如何在平面文件操作上下文中使用位置搜索。

在某些情况下,需要从文件中的特定位置读取或写入,例如索引文件。本文将向你展示如何在平面文件操作上下文中使用位置搜索。

在文件中寻找位置

Golang 版本

1.12.1

前言

在某些情况下,需要从文件中的特定位置读取或写入,例如索引文件。本文将向你展示如何在平面文件操作上下文中使用位置搜索。

实现

创建文件 flatfile.txt ,内容如下:

123.Jun.......Wong......
12..Novak.....Jurgen....
10..Thomas....Sohlich...

创建文件 fileseek.go ,代码如下:

package main

import (
	"errors"
	"fmt"
	"os"
)

const lineLegth = 25

func main() {

	f, e := os.OpenFile("flatfile.txt", os.O_RDWR|os.O_CREATE,
		os.ModePerm)
	if e != nil {
		panic(e)
	}
	defer f.Close()

	fmt.Println(readRecords(2, "last", f))
	if err := writeRecord(2, "first", "Radomir", f); err != nil {
		panic(err)
	}
	fmt.Println(readRecords(2, "first", f))
	if err := writeRecord(10, "first", "Andrew", f); err != nil {
		panic(err)
	}
	fmt.Println(readRecords(10, "first", f))
	fmt.Println(readLine(2, f))
}

func readLine(line int, f *os.File) (string, error) {
	lineBuffer := make([]byte, 24)
	f.Seek(int64(line*lineLegth), 0)
	_, err := f.Read(lineBuffer)
	return string(lineBuffer), err
}

func writeRecord(line int, column, dataStr string, f *os.File)error {
definedLen := 10
position := int64(line * lineLegth)
switch column {
case "id":
definedLen = 4
case "first":
position += 4
case "last":
position += 14
default:
return errors.New("Column not defined")
}

if len([]byte(dataStr)) > definedLen {
return fmt.Errorf("Maximum length for '%s' is %d",
column, definedLen)
}

data := make([]byte, definedLen)
for i := range data {
data[i] = '.'
}
copy(data, []byte(dataStr))
_, err := f.WriteAt(data, position)
return err
}

func readRecords(line int, column string, f *os.File)(string, error) {
lineBuffer := make([]byte, 24)
f.ReadAt(lineBuffer, int64(line*lineLegth))
var retVal string
switch column {
case "id":
return string(lineBuffer[:3]), nil
case "first":
return string(lineBuffer[4:13]), nil
case "last":
return string(lineBuffer[14:23]), nil
}

return retVal, errors.New("Column not defined")
}
$ go run fileseek.go
Sohlich.. <nil>
Radomir.. <nil>
Andrew... <nil>
10..Radomir...Sohlich... <nil>

我们可以使用十六进制看一下 flatfile.txt ,使用 xxd flatfile.txt

$ xxd flatfile.txt                                       
00000000: 3132 332e 4a75 6e2e 2e2e 2e2e 2e2e 576f  123.Jun.......Wo
00000010: 6e67 2e2e 2e2e 2e2e 0a31 322e 2e4e 6f76  ng.......12..Nov
00000020: 616b 2e2e 2e2e 2e4a 7572 6765 6e2e 2e2e  ak.....Jurgen...
00000030: 2e0a 3130 2e2e 5261 646f 6d69 722e 2e2e  ..10..Radomir...
00000040: 536f 686c 6963 682e 2e2e 0000 0000 0000  Sohlich.........
00000050: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000060: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000070: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000080: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000090: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000f0: 0000 0000 0000 0000 0000 0000 0000 416e  ..............An
00000100: 6472 6577 2e2e 2e2e                      drew....

原理

前面的示例使用平面文件展示了如何在文件中进行位置查找、读取和写入。通常,要移动 File 当前指针的位置,可以使用 Seek 方法。它有两个参数,分别是位置和如何计算位置,0 -相对于文件原点,1 -相对于当前位置,2 -相对于文件结束。这样就可以在文件中移动光标。在前面代码中的 readLine 函数的实现中使用了 Seek 方法。

平面文件是存储数据的最基本形式。其记录格式一般具有固定的长度,并且每一条记录的格式也是相同的。示例中的平面文件的结构是:ID-4个字符,FirstName-10个字符,LastName-10个字符。 整个记录长24个字符,以第25个字符的换行符结束。

os.File 还包含 ReadAtWriteAt 方法。这些方法将字节数据写入/读取从何处开始的偏移量。这样可以将写和读简化到文件中的某个位置。

注意,本例假设每个rune只有一个字节,对于特殊字符,不必为true,以此类推。


以上所述就是小编给大家介绍的《go基础库之在文件中寻找位置》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

C++沉思录

C++沉思录

Andrew Koenig、Barbara Moo / 黄晓春、孟岩(审校) / 人民邮电出版社 / 2002-11-01 / 50.00元

《C++ 沉思录》集中反映了C++的关键思想和编程技术,不仅告诉你如何编程,还告诉你为什么要这样编程。本书曾出现在众多的C++专家推荐书目中。 这将是C++程序员的必读之作。因为: 它包含了丰富的C++思想和技术,从详细的代码实例总结出程序设计的原则和方法。 不仅教你如何遵循规则,还教你如何思考C++编程。 既包括面向对象编程也包括泛型编程。 探究STL这一近年来C++最重要的新成果的内在思想。一起来看看 《C++沉思录》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

MD5 加密
MD5 加密

MD5 加密工具