从数组读取字节到Java类数组

时间:2016-07-04 20:50:36

标签: java arrays

我有一个我正在更新的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;
}

}

如果有更好的方法来完成任务,我愿意接受建议。

3 个答案:

答案 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;
   }

}

相关问题