分享
  1. 首页
  2. 文章

使用golang读取StarDict 词典idx文件并按行输出

piaoyaofenfanl · · 4706 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

StarDict 词典idx文件格式:


每一个条目在单词列表中包含陆续三个域:

word_str; // a utf-8 string terminated by '0円'.

// 一个 utf-8 编码字符串,以 '0円' 终止符结束。word_str 的长度将是小于 256 的

word_data_offset; // word data's offset in .dict file

// 单词数据在 .dict 文件中的偏移,

//If the version is "3.0.0" and "idxoffsetbits=64",

//word_data_offset will be 64-bits unsigned number in network byte order.


word_data_size; // word data's total size in .dict file

// 单词数据在 .dict 文件中的总大小,word_data_size should be 32-bits unsigned number

// in network byte order.


package main
import (
// "bufio"
 "io"
 "os"
 "fmt"
 "strconv"
)
func main() {
 fi, err := os.Open("gaojihanyudacidian_fix.idx")/*现代汉语词典\\*/
 if err != nil { panic(err) }
 defer fi.Close()
 fo, err := os.Create("output.txt")
 if err != nil { panic(err) }
 defer fo.Close()
	/*每次只读4个字节*/
 read_buf := make([]byte,4)
 jiange := make([]byte,1)
 huanghuang := make([]byte,1)
 jiange[0]=9
 huanghuang[0]=10 
 var pos,nextPos uint64 = 0,0
 /*标记当下需要读取的是哪个域的数据
 为1是word_str 
 为2是word_data_offset 
 为3是word_data_size*/ 
 var setp int = 1 
 /*记录已经存储在word_str中的字符个数(不包括字符串最后的0円),也就是说下次从word_str[lenth_of_word_str]处开始存*/
 var lenth_of_word_str,charNum int = 0,0
 word_str := make([]byte,257)
 var tmpChar byte =0
 var word_data_offset uint64 = 0 
 var word_data_size uint64 = 0 
 count :=1
 for{
 	pos=nextPos
	count++
 n,err := fi.ReadAt(read_buf,(int64)(pos))
 if err != nil && err != io.EOF{
 panic(err)
 }
 /*文件格式要求:读取数据小于4个字节时说明文件结束*/
 if n < 4{
 fmt.Printf("\nfinish read\n")
 break
 }
	switch setp {
	case 1:
//		fmt.Println("1:")
		tmpChar=read_buf[0]
		/*如果第一个字符是‘0円’说明该步骤已经结束*/
		if tmpChar != 0{
		
			/*因为可能有逗号,所以可能只有1个或者俩个字节组成一个字符*/
			if tmpChar < 128{
				charNum=1/*charNum记录utf8编码的字符数*/
			}else if tmpChar < 194{
				panic(err)
			}else if tmpChar < 224{
				charNum=2
			}else if tmpChar < 240{
				charNum=3
			}else{
				panic(err)
			}
			
			
			read_buf[charNum]=0
			str1 := (string)(read_buf[0:charNum+1])
			copy(word_str[lenth_of_word_str:lenth_of_word_str+charNum], read_buf[:charNum])
			lenth_of_word_str=lenth_of_word_str+charNum
			nextPos=nextPos+(uint64)(charNum)
			continue
		}else{
			word_str[lenth_of_word_str]=9
			nextPos=nextPos+1
			
		}		
		
 	
	case 2:
		word_data_offset =0
		word_data_offset = word_data_offset+((uint64)(read_buf[0]))*16*16*16*16*16*16
		word_data_offset = word_data_offset+((uint64)(read_buf[1]))*16*16*16*16
		word_data_offset = word_data_offset+((uint64)(read_buf[2]))*16*16
		word_data_offset = word_data_offset+(uint64)(read_buf[3])
		nextPos=nextPos+4
		
// 	fmt.Printf("word_data_offset =%d \n",word_data_offset/*(uint64)(read_buf[3])*/)
	case 3:
		word_data_size =0
		word_data_size = word_data_size+(uint64)(read_buf[0])*16*16*16*16*16*16
		word_data_size = word_data_size+(uint64)(read_buf[1])*16*16*16*16
		word_data_size = word_data_size+(uint64)(read_buf[2])*16*16
		word_data_size = word_data_size+(uint64)(read_buf[3])
		nextPos=nextPos+4
	default:
 }
 /*现在可以写入了*/
	if setp == 3{
	
		if _,err := fo.Write( word_str[:lenth_of_word_str+1]); err != nil{
		 panic(err)
		}
		
	 word_data_offset_str := strconv.FormatUint(word_data_offset,10) 
	 word_data_size_str := strconv.FormatUint(word_data_size,10) 		
		if _,err := fo.WriteString( word_data_offset_str); err != nil{
		 panic(err)
		}
 		
		if _,err := fo.Write( jiange[0:1]); err != nil{
		 panic(err)
		}		
		if _,err := fo.WriteString( word_data_size_str); err != nil{
		 panic(err)
		}		
		if _,err := fo.Write( huanghuang[0:1]); err != nil{
		 panic(err)
		}
		lenth_of_word_str=0
	}
 setp=setp+1
 if setp > 4{
		setp = 1 
	}
 }
}



有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:piaoyaofenfanl

查看原文:使用golang读取StarDict 词典idx文件并按行输出

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
4706 次点击
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏