我有一个我正在更新的DOS程序的配置文件。 。
配置文件为17512字节。前128个字节是标题信息,剩余字节被分成256个记录,每个记录64字节。每条记录包含设备的特定信息,如名称(8个字节),描述(18个字节),单元号(1个字节)等。我正在将文件读入一个大字节数组,然后想要提取单个设备信息,以便在新的GUI界面中进行编辑。
我创建了一个类设备,其中包含设备名称的字段。我想创建一个包含所有256个设备的类的数组,但是当我尝试读取各个设备名称时,所有256个设备最终都会读取最后一个设备。我不确定我哪里出错了。
以下是Main.java的代码
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();
}
}
以下是类Device的代码。到目前为止我只有第一个字段。当我能够正常工作时,我会添加其余部分。
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;
}
}
如果有更好的方法来完成任务,我愿意接受建议。
答案 0 :(得分:0)
在类上公开Array值是不正确的。 使用您的代码,每个人都可以更改数组的值。
public static byte[] code;
将公开数组的值。这很危险
1°)你需要很好地封装你的数组
private static byte[] code = new byte[8];
//初始化数组
创建一个getter来返回数组的副本
2°)如果你的应用程序需要共享数组,那么对于静态关键字是好的,但你只需要使用数组的副本。
所以返回需要为Arrays.copyOf(code, code.length);
3°)如果数组需要是不可变的,请使用private static final来确保它永远不会改变。因此,在声明中初始化数组。不需要在构造函数上初始化
答案 1 :(得分:0)
好的,对不起,也许我的解释太糟糕了。
“无法从静态上下文引用非静态”意味着您不能使用非静态方法调用静态字段。如果您使用非静态方法,则可以通过以下方式调用静态字段:
`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();
}
}
=&GT;不要将您的入门级别称为“主要”(不适合编码规则集和可维护性)
package test;
import java.util.Arrays;
/**
*
*
*
*/
public class Device {
/** */
private 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
/**
*
* @param devNumber
*/
public void setCode(final int devNumber) {
byte codeTmp[] = new byte[8] ;
int devCodeByteStart = (128 + (64 * devNumber)); // Skip first 128 bytes
// to get to first
// device.
int devCodeByteStop = (devCodeByteStart + 8); // Get 8 bytes for device
// code.
for (int byteCount = devCodeByteStart; byteCount < devCodeByteStop; byteCount++) {
codeTmp[byteCount - devCodeByteStart] = configFileBytes[byteCount]; // WORK WITH A TMP ARRAY
}
this. code = Arrays.copyOf(codeTmp, codeTmp.length) ; ASSIGN A COPY A THE TMP ARRAY
}
/**
*
* @return
*/
public byte[] getCode() {
return Arrays.copyOf(code, code.length); // RETURN A COPY
}
}
数组现在已经封装好了...你可以通过setter(Device[i].setCode()
)设置值,并通过getter(Device[i].getCode()
)获取值,后者返回数组的副本
因此,每个设备都有“自己的”代码数组
答案 2 :(得分:0)
是的!实际上,新的Device [X]只会初始化大小为256个元素的数组(它在内存中分配256个设备),但它不会初始化256个设备,也不会在数组中放置256个设备。为了创建您的设备,我可以建议您这样做。不要使用设备数组(如果你可以采取其他方式)。
1°)你能改变你的importConfig来构造ByteBuffer来代替byte []吗?为什么? 因为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 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();
}
}
和UtilClass
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;
}
}