/** * 从XML文件中读取话单格式 * * @param xmlFileName XML文件名 * @return */ private RecordInfo readFromXml(String xmlFileName) { SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setNamespaceAware(true); SAXParser saxParser; try { saxParser = factory.newSAXParser(); File file = new File(xmlFileName); RecordHandler handler = new RecordHandler(); saxParser.parse(file, handler); RecordInfo info = handler.getInfo(); setTitle(TITLE + " - " + info.getDescription()); return info; } catch (Exception e) { JOptionPane.showMessageDialog( this, "Failed to read xml " + xmlFileName + "\n" + e.getMessage()); return null; } }
/** 解析在文本框中输入的话单 */ private void parseRecord() { if (info == null) { info = readFromXml("record.xml"); if (info == null) { return; } } String record = textArea.getText().trim(); if (record.length() == 0) { return; } StringBuffer resultBuf = new StringBuffer(); String[] fields = record.split(info.getFieldSep()); for (int i = 0; i < fields.length; i++) { resultBuf.append(info.getFieldTitle(i)); resultBuf.append('\t'); resultBuf.append(info.getFieldValue(i, fields[i])); resultBuf.append('\n'); } resultArea.setText(resultBuf.toString()); }
/* * 响应客户端发送的请求,请求分两种: 1.获取文件名。responseClient返回null * 2.请求下载。responseClient返回客户端发送的record对象 */ private static Record responseClient(Socket socket) throws IOException, ClassNotFoundException { ObjectInputStream ois = null; ois = new ObjectInputStream(socket.getInputStream()); RecordInfo info = (RecordInfo) ois.readObject(); if ("download".equals(info.getRequestType())) { return info.getRecord(); } if ("filename".equals(info.getRequestType())) { FileInputStream fis = new FileInputStream(SRC_PATH + info.getRecord().getFileName()); int fileSize = fis.available(); info.setFileSize(fileSize); ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); oos.writeObject(info); } return null; }
/** * Check a particular field and set its size and offset in bytes based on the field type and the * bytes arrays. * * <p>For void, boolean, byte, short, int, long, float and double, there is no offset and the size * is fixed. For string, map, list, struct, the first four bytes are used to store the size. So * the offset is 4 and the size is computed by concating the first four bytes together. The first * four bytes are defined with respect to the offset in the bytes arrays. For timestamp, if the * first bit is 0, the record length is 4, otherwise a VInt begins at the 5th byte and its length * is added to 4. * * @param objectInspector object inspector of the field * @param bytes bytes arrays store the table row * @param offset offset of this field * @param recordInfo modify this byteinfo object and return it */ public static void checkObjectByteInfo( ObjectInspector objectInspector, byte[] bytes, int offset, RecordInfo recordInfo, VInt vInt) { Category category = objectInspector.getCategory(); switch (category) { case PRIMITIVE: PrimitiveCategory primitiveCategory = ((PrimitiveObjectInspector) objectInspector).getPrimitiveCategory(); switch (primitiveCategory) { case VOID: recordInfo.elementOffset = 0; recordInfo.elementSize = 0; break; case BOOLEAN: case BYTE: recordInfo.elementOffset = 0; recordInfo.elementSize = 1; break; case SHORT: recordInfo.elementOffset = 0; recordInfo.elementSize = 2; break; case FLOAT: recordInfo.elementOffset = 0; recordInfo.elementSize = 4; break; case DOUBLE: recordInfo.elementOffset = 0; recordInfo.elementSize = 8; break; case INT: recordInfo.elementOffset = 0; recordInfo.elementSize = WritableUtils.decodeVIntSize(bytes[offset]); break; case LONG: recordInfo.elementOffset = 0; recordInfo.elementSize = WritableUtils.decodeVIntSize(bytes[offset]); break; case STRING: // using vint instead of 4 bytes LazyBinaryUtils.readVInt(bytes, offset, vInt); recordInfo.elementOffset = vInt.length; recordInfo.elementSize = vInt.value; break; case CHAR: case VARCHAR: LazyBinaryUtils.readVInt(bytes, offset, vInt); recordInfo.elementOffset = vInt.length; recordInfo.elementSize = vInt.value; break; case BINARY: // using vint instead of 4 bytes LazyBinaryUtils.readVInt(bytes, offset, vInt); recordInfo.elementOffset = vInt.length; recordInfo.elementSize = vInt.value; break; case DATE: recordInfo.elementOffset = 0; recordInfo.elementSize = WritableUtils.decodeVIntSize(bytes[offset]); break; case TIMESTAMP: recordInfo.elementOffset = 0; recordInfo.elementSize = TimestampWritable.getTotalLength(bytes, offset); break; case DECIMAL: // using vint instead of 4 bytes LazyBinaryUtils.readVInt(bytes, offset, vInt); recordInfo.elementOffset = 0; recordInfo.elementSize = vInt.length; LazyBinaryUtils.readVInt(bytes, offset + vInt.length, vInt); recordInfo.elementSize += vInt.length + vInt.value; break; default: { throw new RuntimeException("Unrecognized primitive type: " + primitiveCategory); } } break; case LIST: case MAP: case STRUCT: case UNION: recordInfo.elementOffset = 4; recordInfo.elementSize = LazyBinaryUtils.byteArrayToInt(bytes, offset); break; default: { throw new RuntimeException("Unrecognized non-primitive type: " + category); } } }