内容简介:在某些情况下,需要从文件中的特定位置读取或写入,例如索引文件。本文将向你展示如何在平面文件操作上下文中使用位置搜索。
在某些情况下,需要从文件中的特定位置读取或写入,例如索引文件。本文将向你展示如何在平面文件操作上下文中使用位置搜索。
在文件中寻找位置
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
还包含 ReadAt
和 WriteAt
方法。这些方法将字节数据写入/读取从何处开始的偏移量。这样可以将写和读简化到文件中的某个位置。
注意,本例假设每个rune只有一个字节,对于特殊字符,不必为true,以此类推。
以上所述就是小编给大家介绍的《go基础库之在文件中寻找位置》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
C++沉思录
Andrew Koenig、Barbara Moo / 黄晓春、孟岩(审校) / 人民邮电出版社 / 2002-11-01 / 50.00元
《C++ 沉思录》集中反映了C++的关键思想和编程技术,不仅告诉你如何编程,还告诉你为什么要这样编程。本书曾出现在众多的C++专家推荐书目中。 这将是C++程序员的必读之作。因为: 它包含了丰富的C++思想和技术,从详细的代码实例总结出程序设计的原则和方法。 不仅教你如何遵循规则,还教你如何思考C++编程。 既包括面向对象编程也包括泛型编程。 探究STL这一近年来C++最重要的新成果的内在思想。一起来看看 《C++沉思录》 这本书的介绍吧!