2004年12月03日

DBF数据文件常见于VF和Sybase的一些应用,下面谈谈偶对Dbf文件的一些认识以及java中对dbf文件的操作经验.

用ultraEdit打开一个DBF文件,字符串的前两行,即前32位为dbf文件的表头说明信息部分,描述了文件包含多少行数据,文件表列结构数,每行数据占用的字符位数等等信息.第三行开始为dbf文件列信息说明部分,每两行字符串,即32位字符内描述了一个数据列信息,包括列名,列类型,列占用字符位数,列中小数点位数等信息,根据dbf文件列的数目,各文件的列信息说明部分长短不一.之后就是dbf文件的数据信息,每行数据前通常有ascII的20标志新的数据行开始,每行数据的长度由之前的表头说明部分就已经确定,最后的数据行后通常有ascII的A1标志文件数据行的结束.

在java中实现对dbf的操作,一般是通过对dbf文件stream的控制方式来实现操作.现行比较方便的方法是通过对开源项目com.svcon.jdbfjdbf的源代码进行适应性修改来实现自己需要的操作方式.jdbf的源代码大家可在网上找寻得到,呵呵,国外的高手们2000年的写的东东.这里谈谈偶对jdbf的类的认识:
1.JDBField.java用于建立Dbf表列对象,可返回name/type/length/decimalCount等信息,通过同名方法JDBField()构建对象,使用format(Object obj)方法将参数obj生成DBF表列数据,使用parse(String s)将读入的DBF表列数据生成obj;构建对象时主要时根据标准dbf文件的方法进行一些常规判断,并赋值私有属性,本类中似乎缺少了DBF的备注类型列的控制和判断,不知是不是偶的jdbf源代码的问题,有知道的xd请指教.
2.DBFReader.java用于建立DBF读取对象,可返回表列数组fields[]/数据行是否结束标志nextRecord[]等信息,通过同名方法DBFReader()构建对象,提供方法nextRecord()读取下一行数据.构建对象方法时先解析DBF文件表头信息,再获得表列信息,最后读取出第一行数据,大家可以根据自己需求进行修改.
3.DBFWriter.java用于建立DBF写入对象,与读取对象相似.
4.JDBFException.java用于JDBF中各类的异常处理,大家可以将类的异常处理修改成自己系统的异常机制,这里不多说了.

    Case “.asf”
     ContentType = “video/x-ms-asf”
    Case “.avi”
     ContentType = “video/avi”
    Case “.doc”
     ContentType = “application/msword”
    Case “.zip”
     ContentType = “application/zip”
    Case “.xls”
     ContentType = “application/vnd.ms-excel”
    Case “.gif”
     ContentType = “image/gif”
    Case “.jpg”, “jpeg”
     ContentType = “image/jpeg”
    Case “.wav”
     ContentType = “audio/wav”
    Case “.mp3″
     ContentType = “audio/mpeg3″
    Case “.mpg”, “mpeg”
     ContentType = “video/mpeg”
    Case “.rtf”
     ContentType = “application/rtf”
    Case “.htm”, “html”
     ContentType = “text/html”
    Case “.txt”
     ContentType = “text/plain”
    Case Else
     ContentType = “application/octet-stream”


前不久做了和商业税控机的文本接口,截取部分代码随便说说文件输入输出实现经验:
ps:以下代码有不少穿插语句,不可直接copy使用,仅供交流。

          //FormFile是struts中的一个类,通用的jsp页面方式直接传递file即可。
          FormFile file = form.getLocalFile();
          try {
            Debug.print(“file name is ” + file.getFileName());
            //读入文件,本例是用bufferReader的readLine的方式操作字符流
            //通常情况下更多实用性质的是inputstream的直接操作.
            BufferedReader br= new BufferedReader(new InputStreamReader(
                file.getInputStream()));
            //判断文件是否为空
            if (br.read() == -1) { //判断是否已读到文件的结尾
              throw new Exception(“传入文件中无内容”);
            }
            /*
            //判断文件是否为空可,用read()的方式会读入了一个字节,可能对文件字符流处理有影响.
            if(fis.available()== -1){
              throw new Exception(“传入文件无内容!”);
            }
            */
            //文件不为空时继续处理
            else {
              //一行一行读取数据
              //从文件读取第一行字符串
              List list = new ArrayList();
              String line = br.readLine();
            }

            //文件的写出实例:
            File f = new File(filePath,”in.txt”);
            //检查in.txt是否存在
            if(f.exists()){
              //删除已经存在的in.txt文件
              f.delete();
              Debug.print(filePath + “\\in.txt 存在,已删除。”);
            }
            //在当前目录下建立一个名为in.txt的文件
            f.createNewFile();
            //写入导出文本文档数据
            FileWriter fw = new FileWriter(f);
            BufferedWriter bw=new BufferedWriter(fw);
            //写入一行文本
            bw.write(“~~~”);
            //断行
            bw.newLine();;
            //将数据更新至文件
            bw.flush();
            //关闭文件流
            fw.close();
            
            //写出的文件在jsp页面上的response控制
            //读取数据到buff中
            byte[] buff = new byte[f.available()];
            f.read(buff);
            //用response带header返回导出的txt文件
            String fileName=”.//applications//BYERP//SALE//in.txt”;
            httpServletResponse.reset();
            //设置导出文件类型,本处提交的文件类型是文本文档,类型的处理以后补充.
            httpServletResponse.setContentType(“text/plain”);
            httpServletResponse.setHeader(“Content-disposition”,
                                      “attachment; filename=XXXXX.txt”);
            //httpServletResponse.addHeader(“Cache-Control”, “no-cache,must-revalidate”);
            //httpServletResponse.addHeader(“Pragma”, “no-cache”);
            //用PrintWrite的方式返回流数据
            //也可用:PrintWrite和ServletOutPutStream的区别就不多说了.
            //      ServletOutputStream myout = response.getOutputStream();
            //      myout.write(buff);
            //      PrintWriter mynewout = httpServletResponse.getWriter();
            //      mynewout.write( new String( buff ) );
            ServletOutputStream mynewout = httpServletResponse.getOutputStream();
            mynewout.write(buff);
            mynewout.flush();
            mynewout.close();

          }catch (FileNotFoundException fnfe) {
            Debug.log(fnfe);
            throw new GeneralException(ExceptionType.SYS_UPLOAD_FILE_NOT_EXIST,
                                       “SaleInvoiceAction.action=save”, fnfe);
          }
          catch (IOException ioe) {
            Debug.log(ioe);
            throw new GeneralException(ExceptionType.SYS_FILE_IO_EXCEPTION,
                                       “SaleInvoiceAction.action=save”, ioe);
          }

对以上代码有不同看法的XD们,请指出,大家讨论,谢谢.