JavaStruct第三方库jar包下载地址(免费自取):
链接: https://pan.baidu.com/s/11AcJn8uk7yGlEEwEHa8_FA
提取码: esgf
JavaStruct使用环境:
当与嵌入式设备和其他使用C结构的应用程序一起使用时,结构体类可用于大大简化Java
应用程序的网络协议代码。JavaStruct允许程序员将Java类视为c结构,而不是手动编码和
解码消息。
JavaStruct使用Java5或Java5以上版本jdk,将类和字段标记为结构体JavaStruct并不是第一
次提供类似结构的功能,Jean-Marie Dautelle的Javolution库也具有出色的结构实现。但
是,POJO方法不是首选JavaStruct,而不是在Javolution中使用特殊的类。
JavaStruct应用实现:
JavaStruct类用于打包java对象为字节格式,解包字节数据为Java序列化对象。Struct字段
具有顺序值,因为Java JVM规范不提供有关类成员顺序的任何信息。它们按其在Sun的实
现中的外观进行排序,但在其他JVM上有所不同。因此,每个Struct字段都必须提供一个排
序值。
@StructClass
公共类Foo {
@StructField(order = 0)
public byte b;
@StructField(order = 1)
public int i;
}
try {//将类打包为字节缓冲区
Foo f = new Foo();
fb =(byte)1;
fi = 1;
byte [] b = JavaStruct.pack(f);
// Unpack it into an object
Foo f2 = new Foo();
JavaStruct.unpack(f2, b);
} catch(StructException e){}```
如果发生任何错误,Struct操作将抛出一个已检查的StructException。
Struct类也可以直接与Streams一起使用。请参考Photoshop ACB文件阅读器示例。
public void read(String acbFile){
try {
FileInputStream fis = new FileInputStream(new File(acbFile));
header = new ACBHeader();
//ByteOrder.BIG_ENDIAN为大端排序,数据高位放在字节低位
StructUnpacker up = JavaStruct.getUnpacker(fis, ByteOrder.BIG_ENDIAN);
up.readObject(header);
...
**原语**
使用原语。请注意,private和protected字段需要适当的getter和setter方法。Transient字段
将被自动排除。
@StructClass
public class PublicPrimitives implements Serializable {
@StructField(order = 0)
public byte b;
@StructField(order = 1)
public char c;
@StructField(order = 2)
public short s;
@StructField(order = 3)
public int i;
@StructField(order = 4)
public long lo;
@StructField(order = 5)
protected float f;
@StructField(order = 6)
private double d;
transient int blah;
transient double foo;
public float getF() {
return f;
}
public void setF(float f) {
this.f = f;
}
public double getD() {
return d;
}
public void setD(double d) {
this.d = d;
}
public boolean equals(Object o){
PublicPrimitives other = (PublicPrimitives)o;
return (this.b == other.b
&& this.c == other.c
&& this.s == other.s
&& this.i == other.i
&& this.lo == other.lo
&& this.f == other.f
&& this.d == other.d);
}
}
**数组**
数组有一些先决条件。打开包装时,应在阵列中保留足够的空间。只有其长度使
ArrayLengthMarker在另一个字段中定义的数组(请参见下文)可以为空,它们在
拆包时会自动分配。除此之外,它们不能为null和未初始化。
@StructClass
public class PublicPrimitiveArrays {
@StructField(order = 0)
public byte [] b = new byte [5];
@StructField(order = 1)
public char[] c = new byte[10];
@StructField(order = 2)
public short[] s;
@StructField(order = 3)
public int[] i;
}
**阵列长度标记**
数组长度标记对于其长度在anoher字段中定义的字段非常有用。考虑下面的例子。这是一
个特殊的String结构,其长度字段和其后的长度为16位字符。为了处理此问题,我们必须
将这些字符串表示为特殊的Struct类,比方说AStruct。长度字段应标注为
“ArrayLengthMarker”。这样,javastruct可以在打包和拆包操作期间在处理数组字段时自动
使用length字段中的值。
@StructClass public class AString {
@StructField (order = 0 )
@ArrayLengthMarker (fieldName = "chars")
public int length;
@StructField (order = 1)
public char[] chars;
public AString(String content){
this.length = content.length();
this.chars = content.toCharArray();
}
}
示例代码:
1.首先我们必须将这些字符串表示为特殊的Struct类AStruct。我们使用特殊的
ArrayLengthMarker批注。
@StructClass
public class AString {
@StructField(order = 0)
@ArrayLengthMarker(fieldName = "chars")
public int length;
@StructField(order = 1)
public char[] chars;
public AString(String content) {
this.length = content.length();
this.chars = content.toCharArray();
}
}
@StructClass
public class ACBHeader {
public static final short RGB = 0;
public static final short CMYK = 2;
public static final short LAB = 7;
// Signature is always ASCII characters "8BCB"
@StructField(order = 0)
public byte[] signature = { '8', 'B', 'C', 'B' };
// Photoshop 7 only opens files with a version of 1 (0x0001)
@StructField(order = 1)
public short fileVersion;
// Unique identifier..
@StructField(order = 2)
public short colorBookIdentifier;
@StructField(order = 3)
public AString title;
@StructField(order = 4)
public AString colorNamePrefix;
@StructField(order = 5)
public AString colorNamePostfix;
// Generally a copyright notice
@StructField(order = 6)
public AString description;
@StructField(order = 7)
public short colorCount;
// Photoshop displays colors page by page. This field specifies the
// maximum number of colors that can appear on a page.
@StructField(order = 8)
public short colorsPerPage;
@StructField(order = 9)
public short pageSelectorOffset;
// RGB, CMYK or Lab
@StructField(order = 10)
public short colorSpaceID;
}
2.根据格式,颜色数据及其格式取决于colorSpaceID字段。它可以是RGB,CMYK或Lab。
因此,我们为每个颜色空间编写一个类。确切有颜色数据的“ colorCount”个数。
@StructClass
public class RGBColor {
@StructField(order = 0)
public AString name;
@StructField(order = 1)
public byte[] code = new byte[6];
@StructField(order = 2)
public byte red;
@StructField(order = 3)
public byte green;
@StructField(order = 4)
public byte blue;
}
@StructClass
public class LabColor {
@StructField(order = 0)
public AString name;
@StructField(order = 1)
public byte[] code = new byte[6];
@StructField(order = 2)
public byte lightness;
@StructField(order = 3)
public byte aChrom;
@StructField(order = 4)
public byte bChrom;
}
3.要读取和写入acb文件,我们使用FileStreams初始化StructPacker和StructUnpacker类。
之后,读取标题和颜色数据就非常简单了。
public class AdobeColorBook {
ACBHeader header;
RGBColor[] rgbColors = null;
CMYKColor[] cmykColors = null;
LabColor[] labColors = null;
public void read(String acbFile) {
try {
FileInputStream fis = new FileInputStream(new File(acbFile));
header = new ACBHeader();
StructUnpacker up = JavaStruct.getUnpacker(fis, ByteOrder.BIG_ENDIAN);
up.readObject(header);
switch (header.ColorSpaceID) {
case ACBHeader.RGB:
rgbColors = new RGBColor[header.colorCount];
for (int i = 0; i < header.colorCount; i++) {
rgbColors[i] = new RGBColor();
up.readObject(rgbColors[i]);
}
break;
case ACBHeader.CMYK:
cmykColors = new CMYKColor[header.colorCount];
for (int i = 0; i < header.colorCount; i++) {
cmykColors[i] = new CMYKColor();
up.readObject(cmykColors[i]);
}
break;
case ACBHeader.LAB:
labColors = new LabColor[header.colorCount];
for (int i = 0; i < header.colorCount; i++) {
labColors[i] = new LabColor();
up.readObject(labColors[i]);
}
break;
default:
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (StructException e) {
e.printStackTrace();
}
}
public void write(String name) {
try {
FileOutputStream fo = new FileOutputStream(new File(name));
StructPacker packer = JavaStruct.getPacker(fo, ByteOrder.BIG_ENDIAN);
packer.writeObject(header);
switch (header.ColorSpaceID) {
case ACBHeader.RGB:
for (RGBColor color : rgbColors) {
packer.writeObject(color);
}
break;
case ACBHeader.CMYK:
for (CMYKColor color : cmykColors) {
packer.writeObject(color);
}
break;
case ACBHeader.LAB:
for (LabColor color : labColors) {
packer.writeObject(color);
}
break;
default:
}
fo.close();
} catch (StructException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public String toString() {
String str = "";
if (header != null) {
str += header;
}
switch (header.ColorSpaceID) {
case ACBHeader.RGB:
for (RGBColor color : rgbColors) {
str += color + "\n";
}
break;
case ACBHeader.CMYK:
for (CMYKColor color : cmykColors) {
str += color + "\n";
}
break;
case ACBHeader.LAB:
for (LabColor color : labColors) {
str += color + "\n";
}
break;
}
return str;
}
public static void main(String[] args) {
AdobeColorBook anpaBook = new AdobeColorBook();
anpaBook.read("ANPA Color.acb");
anpaBook.write("ANPA_my_Color.acb");
System.out.println(anpaBook);
}
}
也可参考博客:https://blog.youkuaiyun.com/jazzsoldier/article/details/75570462
javastruct源码链接:https://github.com/dubrousky/javastruct