一个下午,找了一条小虫,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出了问题,但是没有明显的差别啊。后来跟踪到源代码的异常处理后发现问题的关键所在:
原来,在检查fitskeyword的时候,他会检查card的第一个字符,而出问题的关键字的新版本是1D_CLASS,以1开头,所以抛出了Illegal character的异常导致程序不能运行,进而抛出文件的异常is not a FITS file.
终于找到Bug了,很开心,呵呵,虽然问题很小很小,但是过程是美好的,也进一步对JAVA的调试,包的导入有了更好的理解。另外,在Source中发现这样一段代码:
开始纳闷的是while循环的判断是true,那什么时候运行是个头呢。呵呵,经过跟踪发现,原来是当readFully后也会抛出一个end的异常,进而对异常处理,这样就退出来了while循环。
总结:遇到问题,一定要理性的去分析,排除原因,一步一步调试,和C++一样,要熟练是使用调试。另外有时间多看看别人写的源码,真的能有很多启发。
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++一样,要熟练是使用调试。另外有时间多看看别人写的源码,真的能有很多启发。
相关文章推荐
- java读取一个路径下的所有文件
- 自定义字符输入流的包装类,通过这个包装类对底层字符输入流进行包装,让程序通过这个包装类读取某个文本文件(例如,一个java源文件)时,能够在读取的每行前面都加上有行号和冒号。
- java读取UTF-8的txt文件发现开头的一个字符问题
- Java 从一个文件中读取某一个特定的字符串
- 分享下java 读取目录及子目录下指定文件名的路径 并放到一个List数组里面返回遍历和写到文件里
- java基础IO流使用读取一个文件中的文字输出到控制台上
- 读取一个指定的*.Java文件,并打印在控制台上
- java.sql.SQLException: ${jdbc.driver} spring mybatis读取配置文件出错
- JAVA读取中文文件,判断string中含有中文字符,判断某一个字符是否为中文字符
- java关于读取数据后简单写入一个文件中的总结
- 读取一个.java文件,并打印在控制台上。
- 一个Java读取文件的例子
- 如何使用JavaExcel(jxl)读取一个文件并写入一个新文件
- java的JFileChooser上传一个Excel文件并读取该文件的内容
- [Java] Java序列化将一个对象的内容保存到文件和从文件读取对象
- 读取一个.java文件并打印在控制台上
- java多线程同时读取一个文件
- java 读取xml文件开头多了一个问号
- java读取输入流并保存成一个文件
- JAVA多线程读取同一个文件,加速对文件内容的获取