将字节从数组读取到Java类的数组
我有一个正在更新的DOS程序的配置文件 配置文件为17512字节。前128个字节是报头信息,其余字节分为256条记录,每条记录64个字节。每个记录包含设备的特定信息,如名称(8字节)、说明(18字节)、单元号(1字节)等。我正在将文件读入一个大字节数组,然后想取出单个设备的信息,以便可以在新的GUI界面中对其进行编辑 我创建了一个类设备,其中包含设备名称字段。我想创建一个此类数组来包含所有256个设备,但当我尝试读取单个设备名称时,所有256个设备都以最后一个读取的设备结束。我不确定哪里出了错 下面是Main.java的代码将字节从数组读取到Java类的数组,java,arrays,Java,Arrays,我有一个正在更新的DOS程序的配置文件 配置文件为17512字节。前128个字节是报头信息,其余字节分为256条记录,每条记录64个字节。每个记录包含设备的特定信息,如名称(8字节)、说明(18字节)、单元号(1字节)等。我正在将文件读入一个大字节数组,然后想取出单个设备的信息,以便可以在新的GUI界面中对其进行编辑 我创建了一个类设备,其中包含设备名称字段。我想创建一个此类数组来包含所有256个设备,但当我尝试读取单个设备名称时,所有256个设备都以最后一个读取的设备结束。我不确定哪里出了错
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
ReadConfigFile.importConfigFile(); // Read config file into byte array.
Device[] device = new Device[256]; // Create array of 256 Devices.
device[0].code = Device.setCode(0);
System.out.println(new String(device[0].code)); // First device correct here.
device[255].code = Device.setCode(255);
System.out.println(new String(device[0].code)); // First device now same as last?
System.out.println(new String(device[255].code));
Group root = new Group();
Scene scene = new Scene(root, 200, 200);
primaryStage.setTitle("Config File Editor");
primaryStage.setScene(scene);
primaryStage.show();
}
}
下面是类设备的代码。到目前为止,我只有第一个字段。当我可以让它正常工作时,我将添加其余的
public class Device {
public static byte[] code; // 8 bytes. (1 - 8).
public Device() {
code = new byte[8]; // Constructor correct?
}
public static byte[] setCode(int devNumber) {
int devCodeByteStart = (128 + (64 * devNumber)); // Skip first 128 bytes to get to first device.
int devCodeByteStop = (devCodeByteStart + 8); // Get 8 bytes for device code.
byte[] code = new byte[8]; // Gives Null Pointer Exception if removed.
for(int byteCount = devCodeByteStart; byteCount < devCodeByteStop; byteCount++) {
code[byteCount - devCodeByteStart] = configFileBytes[byteCount];
}
return code;
}
}
公共类设备{
公共静态字节[]代码;//8字节。(1-8)。
公共设备(){
code=新字节[8];//构造函数是否正确?
}
公共静态字节[]设置码(int devNumber){
int devCodeByteStart=(128+(64*devNumber));//跳过前128个字节以到达第一个设备。
int devCodeByteStop=(devCodeByteStart+8);//获取设备代码的8字节。
字节[]代码=新字节[8];//如果删除,则给出空指针异常。
for(int byteCount=devCodeByteStart;byteCount
如果有更好的方法来完成任务,我愿意接受建议。在类上公开数组值是不正确的。 使用您的代码,每个人都可以更改数组的值
公共静态字节[]码代码>将公开数组的值。这很危险
1°)您需要很好地封装阵列
private static byte[]code=新字节[8]代码>//初始化数组
创建一个getter以返回数组的副本
2°)如果应用程序需要共享阵列,静态关键字可以,但只需要使用阵列的副本
因此,返回值必须是Arrays.copyOf(code,code.length)代码>
3°)如果数组需要是不可变的,请使用private static final,以确保它永远不会更改。因此,初始化声明中的数组。不需要初始化构造函数好的,对不起,也许我的解释太糟糕了
“不能从静态上下文引用非静态”表示不能使用非静态方法调用静态字段。如果您有一个非静态方法,您可以通过以下方式调用静态字段:
`Device.code`
但这是个坏主意
所以试试这个:
package test;
public class MainClass extends Application {
public static void main(final String[] args) {
launch(args);
}
@Override
public void start(final Stage primaryStage) throws Exception {
ReadConfigFile.importConfigFile(); // Read config file into byte array.
Device[] device = new Device[256]; // Create array of 256 Devices.
// Edit
device[0] = new Device() ; // you need a Device at index X. If not device[X] = null and null.myMethod() throw NPE
//
device[0].setCode(0);
System.out.println(new String(device[0].getCode())); // First device
// correct
// here.
device[255].setCode(255);
System.out.println(new String(device[0].getCode())); // First device now same
// as last?
System.out.println(new String(device[255].getCode()));
Group root = new Group();
Scene scene = new Scene(root, 200, 200);
primaryStage.setTitle("Config File Editor");
primaryStage.setScene(scene);
primaryStage.show();
}
}
=>不要将初学者类称为“Main”(不利于编码规则集和可维护性)
封装测试;
导入java.util.array;
/**
*
*
*
*/
公共类设备{
/** */
私有字节[]代码;//代码不需要是静态的。静态用于需要通过类/包(如常量或全局字段)共享的字段
/**
*
*@param devNumber
*/
公共无效设置码(最终整数编号){
字节代码tmp[]=新字节[8];
int devCodeByteStart=(128+(64*devNumber));//跳过前128个字节
//先到
//装置。
int devCodeByteStop=(devCodeByteStart+8);//为设备获取8字节
//代码。
for(int byteCount=devCodeByteStart;byteCount
阵列现在封装得很好。。。通过setter(Device[i].setCode()
)设置值,并通过getter(Device[i].getCode()
)获取值,getter返回数组的副本
因此,每个设备都有一个“自己的”代码数组是的!事实上,新设备[X]只初始化256个元素的数组(它在内存中分配256个设备的可能性),但它不会初始化256个设备,也不会在数组中放置256个设备。对于创建您的设备,我可以建议您这样做。不要使用设备阵列(如果可以采取其他方式)
1°)能否更改importConfig以构造ByteBuffer来代替字节[]?为什么?
因为ByteBuffer有一个在读取x字节后前进的“索引”
像这样
ByteBuffer bb = ByteBuffer.allocate(65535); // 65535 is for example, In your code ByteBuffer need to be return by ReadConfigFile.importConfigFile();
List<Device> devices = new ArrayList<Device>();
byte[] unused = new byte[128];
bb.get(unused); // this will return the 128 first bytes. ByteBuffer
// position is 129
while (bb.hasRemaining()) { // Make a check to Verify that bb have at least 8 bytes, if not, last code can be corrupted => if you need it
byte[] code = new byte[8]; // 8 byte for 1 code
bb.get(code); // now code in set with the 8 next bytes 129-136 ;
Device device = new Device(code); // set Directly the code with the constructor
devices.add(device);
}
你的主要
public class MainClass extends Application {
public static void main(final String[] args) {
launch(args);
}
@Override
public void start(final Stage primaryStage) throws Exception {
ByteBuffer bb = ByteBuffer.allocate(65535); // 65535 is for example, In your code ByteBuffer need to be return by ReadConfigFile.importConfigFile();
List<Device> devices = UtilClass.createDevices();
System.out.println(new String(device[0].getCode())); // First device
// correct
// here.
System.out.println(new String(device[0].getCode())); // First device now same
// as last?
System.out.println(new String(device[255].getCode()));
Group root = new Group();
Scene scene = new Scene(root, 200, 200);
primaryStage.setTitle("Config File Editor");
primaryStage.setScene(scene);
primaryStage.show();
}
}
public类MainClass扩展应用程序{
公共静态void main(最终字符串[]args){
发射(args);
}
@凌驾
public void start(final Stage primaryStage)引发异常{
ByteBuffer bb=ByteBuffer.allocate(65535);//例如,在代码中,ByteBuffer需要通过ReadConfigFile.importConfigFile()返回;
List devices=UtilClass.createDevices();
System.out.println(新字符串(设备[0].getCode());//第一个设备
//正确的
//在这里。
System.out.println(新字符串(设备[0].getCode());//第一个设备现在相同
//最后呢?
System.out.println(新字符串(设备[255].getCode());
组根=新组();
场景=新场景(根,200200);
setTitle(“配置文件编辑器”);
初级阶段。场景(场景);
初级牡鹿
/**
*
*
*
*/
public class Device {
/** */
private final byte[] code; // code don't need to be static. Static is for field who need to be shared over class/packages like constant or global field. If code
/**
*
* @param code
*/
public Device (final byte[] newCode) {
this.code = Arrays.copyOf(newCode, newCode.length) ; ASSIGN A COPY
}
/**
*
* @return
*/
public byte[] getCode() {
return Arrays.copyOf(code, code.length); // RETURN A COPY
}
}
public class MainClass extends Application {
public static void main(final String[] args) {
launch(args);
}
@Override
public void start(final Stage primaryStage) throws Exception {
ByteBuffer bb = ByteBuffer.allocate(65535); // 65535 is for example, In your code ByteBuffer need to be return by ReadConfigFile.importConfigFile();
List<Device> devices = UtilClass.createDevices();
System.out.println(new String(device[0].getCode())); // First device
// correct
// here.
System.out.println(new String(device[0].getCode())); // First device now same
// as last?
System.out.println(new String(device[255].getCode()));
Group root = new Group();
Scene scene = new Scene(root, 200, 200);
primaryStage.setTitle("Config File Editor");
primaryStage.setScene(scene);
primaryStage.show();
}
}
public class UtilClass {
public static List<Device> createDevices(){
List<Device> result = new ArrayList<Device>();
byte[] unused = new byte[128];
bb.get(unused); // this will return the 128 first bytes. ByteBuffer
// position is 129
while (bb.hasRemaining()) {
byte[] code = new byte[8]; // 8 byte for 1 code
bb.get(code); // now code in set with the 8 next bytes 129-136 ;
Device device = new Device(code); // set Directly the code with the constructor
devices.add(device);
}
return result;
}