您的位置:首页 > 编程语言 > Java开发

一个下午,找了一条小虫,JAVA读取fits文件出错异常

2013-06-04 20:43 459 查看
准备用JAVA完成对光谱的读取,并寻找相似集。下午开始,就卡在光谱的读取中,郁闷了一个下午。以前用MATLAB写过读取光谱的代码(FIT文件格式解析及MATLAB读取程序),也用C++写过,但是觉得C++以前一个字节一个自己的读取过于麻烦,所以对于JAVA的,先找找是不是有读取fits文件的包。没想到还找到了:Java
Library for access to FITS files 。但是,后来问题来了:

开始我用v2..3版本的fits数据,读取文件都没问题,对于关键字的读取很顺利。后来想着现在的pipeline都是2.6版本的了,所以还是重新下载了新版本的数据,但是问题来了,一直显示不是fits文件。但是我用fv打开一切都正常。后来下了dr8的数据,也没发现问题,说明这个包的兼容性还是可以的,但是不知道为什么出现问题。

首先,我想到是不是因为数据的事,后来重新下载了2.6版本的其他数据,测试,还是一样的问题。而且用fv能正常打开,所以数据的问题应该可以排除。

没办法,只能从包里找问题了,因为pipeline跑出来的数据是没法重新修改的,否则这么大的数据,是整个工程的事。幸好这个Library给出了source文件,把source文件加载了,然后一步一步的调试,F11,F5,F6,F8,System.out.println, 找了很久,跟踪了很久,终于发现问题了。



肯定是这个keyword出了问题,但是没有明显的差别啊。后来跟踪到源代码的异常处理后发现问题的关键所在:

public FitsKeyword(byte[] card) throws FitsException {
int idx = 0;                         // index in FITS card
int idx_last = 0;                    // last index of value field
int idx_comm_first = 0;              // first index of comment field

// if card is null or too short - add spaces
if (card == null || card.length < Fits.CARD) {
byte[] pc = new byte[Fits.CARD];
int n = 0;
while (n < card.length) {
pc
= card
;
n++;
}
while (n < Fits.CARD) pc[n++] = SPACE;
card = pc;
}

if ((card[0] != SPACE) && (card[0] != MINUS) && (card[0] != UNDERSCORE)
&& ((card[0] < A) || (Z < card[0])) ) {
throw new FitsException("Illegal character",
FitsException.KEYWORD);
}


原来,在检查fitskeyword的时候,他会检查card的第一个字符,而出问题的关键字的新版本是1D_CLASS,以1开头,所以抛出了Illegal character的异常导致程序不能运行,进而抛出文件的异常is not a FITS file.

终于找到Bug了,很开心,呵呵,虽然问题很小很小,但是过程是美好的,也进一步对JAVA的调试,包的导入有了更好的理解。另外,在Source中发现这样一段代码:

try {
int n = 0;
while (true) {
//System.out.println(kw.getString());
for (int k=0; k<Fits.CARD; k++) {
line[k] = record[n++];
}
kw = new FitsKeyword(line);

keywords.add(kw);
if (Fits.RECORD <= n) {
file.readFully(record, 0, Fits.RECORD);
n = 0;
}
}
} catch (IOException e) {
throw new FitsException("Cannot read header",
FitsException.HEADER);

} catch (FitsException e) {
if (e.getType() != FitsException.ENDCARD) {
throw new FitsException("Bad FITS keyword",
FitsException.HEADER);

}
}


开始纳闷的是while循环的判断是true,那什么时候运行是个头呢。呵呵,经过跟踪发现,原来是当readFully后也会抛出一个end的异常,进而对异常处理,这样就退出来了while循环。

总结:遇到问题,一定要理性的去分析,排除原因,一步一步调试,和C++一样,要熟练是使用调试。另外有时间多看看别人写的源码,真的能有很多启发。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: