日期:2014-05-18  浏览次数:20950 次

读取MARC文件的问题!高人指点!
最近做个程序,需要从MARC文件中读出图书信息的数据,是ISO文件,格式如下:

00906nam 2200265 450 001001700000010005600017010002800073016002100101100004100122101001300163102001500176105001800191106000600209200006700215210004000282215002500322312002100347320002100368330013400389510002500523606002400548690001400572701002800586801002600614CAL 010090028423 a978-7-5062-9043-2dCNY16.80 (含光盘)z7-5062-9043-X a978-7-88765-122-8b光盘 aCN-M46-07-0131-0 a20080307d2007 em y0chiy50 ea0 achiaeng aCNb610000 ay a 000yy ar1 a奥运英语大家说Aao yun ying yu da jia shuoi提高篇f主编李林波 a西安c世界图书出版西安公司d2007.09 a284页d21cme光盘1片 a英文题名取自封面 a有书目 (第284页) a本书中英文对照, 共分为6个单元, 每个单元都分为文章和对话两部分, 相关的重难点词汇及释义可帮助读者快速、有效地掌握文章和对话的内容。1 aOlympic Englishzeng0 a英语Aying yux口语 aH319.9v4 0a李林波Ali lin bo4主编 0aCNbRENTIANc20080307


没什么头绪,哪位做过类似的程序,指导一下,谢谢。

------解决方案--------------------
C# code

00906nam  2200265  450   
001 0017 00000  CAL 010090028423 
010 0056 00017   $a978-7-5062-9043-2$dCNY16.80 (含光盘)$z7-5062-9043-X
010 0028 00073    $a978-7-88765-122-8$b光盘
016 0021 00101   $aCN-M46-07-0131-0
100 0041 00122   $a20080307d2007    em y0chiy50      ea0 
101 0013 00163  $achi$aeng 
102 0015 00176    $aCN$b610000
105 0018 00191   $ay  a  000yy  
106 0006 00209   $ar
200 0067 00215  1 $a奥运英语大家说Aao yun ying yu da jia shuoi提高篇f主编李林波 
210 0040 00282   $a西安$c世界图书出版西安公司$d2007.09
215 0025 00322   $a284页$d21cm$e光盘1片
312 0021 00347   $a英文题名取自封面
320 0021 00368    $a有书目 (第284页)  
330 0134 00389  $a本书中英文对照, 共分为6个单元, 每个单元都分为文章和对话两部分, 相关的重难点词汇及释义可帮助读者快速、有效地掌握文章和对话的内容。
510 0025 00523  1 $aOlympic English$zeng
606 0024 00548  0 $a英语$Aying yu$x口语
690 0014 00572   $aH319.9$v4
701 0028 00586  0$a李林波$Ali lin bo$4主编
801 0026 00614  0$aCN$bRENTIAN$c20080307

------解决方案--------------------
读取MARC记录的时候,应当以字节方式读取。
前面我说了,以GBK/GB2312编码分解,即你可以把读出来的字节转换为字符串,但是.NET中的字符串是Unicode编码的,汉字的长度是1,而GBK编码的长度是2,因此会导致目次区与实际数据不符。
另外一方面,绝大多数的MARC数据文件中,每条记录后面会有一个回车换行符号,需要把它们去掉。

所以,读取一个整个的MARC文件的方法是:
以流的方式打开文件
读取前面5个字节,并转换字符串,然后变为int变量,如marcLen
继续读取marcLen-5个字节
将数据基地址部分取出,转换为int变量,如dataStart
将目次区(不叫目录区)分解到一个n*3的数组中,如aEntrys[n,3]
从dataStart位置开始,将数据部分单独取出
遍历aEntrys[],依次取出各个字段内容,转变为字符串,放到另一个数组中aFields[n,2],其中[n,1]放字段名,[n,2]放字段数据。
MARC分解的主要工作完成,然后根据需要,提取需要的具体信息(参见前面的帖子)
->准备读取下一条数据
读取数据,如果是回车、换行符号,则忽略,直到遇到连续5个数字(因为MARC的前5个字节一定是是数字)
回到第一步,读取下一条MARC。

此外,有一个问题,就是并非所有人提供的MARC都是符合标准的,有的软件尽管声称支持MARC,但实际上它输出的MARC数据是不合格的,常见的是目次区错误,总长度值错误,将记录结束符记入最后一个字段内等等
此时要根据具体情况进行分析,加入容错部分,比如总长度错误可以通过多读取一部分数据来解决(一般就是差1个字节),目次区错误可以通过字段结束符判定每个字段的位置等。

这是一个基本的MARC数据读取程序,还有很多可优化的地方