Ejemplo n.º 1
0
  private void readFieldDescriptors(LittleEndianInputStream is, int nFields) throws IOException {

    // read description of each field
    byte[] asciiFieldName = new byte[11];
    for (int i = 0; i < nFields; i++) {
      DBFField field = new DBFField();
      is.read(asciiFieldName);
      field.name = bytesToString(asciiFieldName, asciiFieldName.length, this.charsetName);
      field.type = is.readUnsignedByte();
      field.address = is.readInt();
      field.length = is.readUnsignedByte();
      field.decimalCount = is.readUnsignedByte();
      is.readShort(); // overread reserved value
      field.workAreaID = is.readUnsignedByte();
      field.multiUserDBase = is.readShort();
      field.setFields = is.readUnsignedByte();
      is.skipBytes(7); // overread 7 reserved bytes
      field.fieldInMDXIndex = is.readUnsignedByte();

      this.fields.add(field);

      this.printInfo("\n" + field.toString());
    }

    // overread the Header Record Terminator, which should be 0x0D
    byte terminator = is.readByte();
    if (terminator != 0x0D) {
      throw new IOException("DBF file is corrupt.");
    }
  }
Ejemplo n.º 2
0
  public Table read(String filePath) throws IOException {
    LittleEndianInputStream is = null;
    if (filePath == null) return null;

    try {
      // read all data into a data buffer.
      is = new LittleEndianInputStream(new BufferedInputStream(new FileInputStream(filePath)));

      int fileCode = unsignedByteToInt(is.readByte());
      int year = unsignedByteToInt(is.readByte());
      int month = unsignedByteToInt(is.readByte());
      int day = unsignedByteToInt(is.readByte());
      long nbrRecords = is.readInt(); // & 0xffffffffL;// unsigned int
      int headerSize = is.readShort();
      int recordSize = is.readShort();
      is.readShort(); // overread reserved value
      is.readByte(); // transaction byte
      int encrypted = is.readUnsignedByte(); // encription byte
      is.skipBytes(13);
      int codepage = is.readUnsignedByte();
      is.skipBytes(2);

      // map the codepage to a string. Based on:
      // http://www.clicketyclick.dk/databases/xbase/format/dbf.html#DBF_STRUCT
      switch (codepage) {
        case 0x01: // DOS USA	code page 437
          this.charsetName = "IBM437";
          break;
        case 0x02: // DOS Multilingual	code page 850
          this.charsetName = "IBM850";
          break;
        case 0x03: // Windows ANSI	code page 1252
          this.charsetName = "windows-1252";
          break;
        case 0x04: // Standard Macintosh
          this.charsetName = "MacRoman";
          break;
          // ESRI shape files use code 0x57 to indicate that
          // data is written in ANSI (whatever that means).
          // http://www.esricanada.com/english/support/faqs/arcview/avfaq21.asp
        case 0x57:
          this.charsetName = "windows-1252";
          break;
        case 0x64: // EE MS-DOS	code page 852
          this.charsetName = "IBM852";
          break;
        case 0x65: // Nordic MS-DOS	code page 865
          this.charsetName = "IBM865";
          break;
        case 0x66: // Russian MS-DOS	code page 866
          this.charsetName = "IBM866";
          break;
        case 0x67: // Icelandic MS-DOS
          this.charsetName = "IBM861";
          break;
          /*
          case 0x68:  // Kamenicky (Czech) MS-DOS
              // ?
              break;
          case 0x69:  // Mazovia (Polish) MS-DOS
              // ?
              break;
          */
        case 0x6A: // Greek MS-DOS (437G) [?]
          this.charsetName = "x-IBM737";
          break;
        case 0x6B: // Turkish MS-DOS
          this.charsetName = "IBM857";
          break;
        case 0x96: // Russian Macintosh
          this.charsetName = "x-MacCyrillic";
          break;
        case 0x97: // Eastern European Macintosh
          this.charsetName = "x-MacCentralEurope";
          break;
        case 0x98: // Greek Macintosh
          this.charsetName = "x-MacGreek";
          break;
        case 0xC8: // Windows EE (=Eastern Europe?) code page 1250
          this.charsetName = "windows-1250";
          break;
        case 0xC9: // Russian Windows
          this.charsetName = "windows-1251";
          break;
        case 0xCA: // Turkish Windows
          this.charsetName = "windows-1254";
          break;
        case 0xCB: // Greek Windows
          this.charsetName = "windows-1253";
          break;
        default:
          this.charsetName = "IBM437";
      }

      this.printInfo("File Code: " + fileCode);
      this.printInfo("Year: " + year);
      this.printInfo("Month: " + month);
      this.printInfo("Day: " + day);
      this.printInfo("Nbr Records: " + nbrRecords);
      this.printInfo("Header Size: " + headerSize);
      this.printInfo("Record Size: " + recordSize);
      this.printInfo("Ecrypted: " + encrypted);
      this.printInfo("Codepage: " + codepage);

      if (encrypted != 0) throw new IOException("Encrypted DBF not supported.");

      int nFields = (headerSize - 32) / 32;
      this.readFieldDescriptors(is, nFields);

      // create an new table
      Table table = this.initTable("ShapeAttributes");

      // read the records and fill the table
      for (int i = 0; i < nbrRecords; i++) {
        this.printInfo("Reading Record " + i);
        this.readRecord(is, recordSize, table);
      }

      return table;
    } finally {
      if (is != null) is.close();
    }
  }