2016-07-04 140 views
-3

我有一个用于我正在更新的DOS程序的配置文件。 。 。从数组读取字节数组到Java数组

配置文件为17512字节。前128个字节是标题信息,其余字节被分成256个记录,每个记录64个字节。每个记录包含名称(8字节),描述(18字节),单元号(1字节)等设备的特定信息。我正在将文件读取到一个大字节数组中,然后想要提取单个设备信息,以便可以在新的GUI界面中对其进行编辑。

我创建了一个包含设备名称字段的Device类。我想创建一个包含所有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(); 
} 

} 

的代码下面是该类设备的代码。到目前为止,我只有第一个领域。当我能够正常工作时,我会添加其余的。

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

} 

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

+1

你知道什么是'static'意味着/呢? – Amit

+0

@Amit haha​​ ...这么简单... :) –

+2

Device的所有实例共享相同的代码数组,因为您声明为静态。 – JJF

回答

0

是的!实际上,新的Device [X]仅初始化您的阵列,其大小为256个元素(它在内存中分配了256个设备可能性),但它不会初始化256个设备,也不会将256个设备放入阵列中。为了创建你的设备,我可以建议你这样做。不要使用设备阵列(如果可以采用其他方式)。

1°)你可以改变你的importConfig来构造一个ByteBuffer来代替byte []吗?为什么? 因为字节缓冲区有 “索引” 读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; 
    } 

}

+0

我会试试看。感谢你的协助。 – CelestialCoyote

0

在类上暴露Array值是不正确的。 使用您的代码,每个人都可以更改数组的值。

public static byte[] code;将暴露数组的值。这是危险的

1°),您需要良好的微胶囊的阵列

private static byte[] code = new byte[8]; //初始化数组

创建一个getter来回报您的阵列

2°)确定为副本如果您的应用程序需要共享数组,则需要使用静态关键字,但只需使用数组的副本。

因此,返回必须Arrays.copyOf(code, code.length);

3°),如果阵列需要是不可改变的使用私有静态最后,以确保它永远不会改变。因此,在声明中初始化数组。不需要初始化构造函数

+0

我已经从setCode方法中删除静态,但现在我得到'非静态无法从静态上下文中引用'的错误。我不明白为什么我在调用setCode方法之前创建设备数组时遇到了错误。 – CelestialCoyote

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(); 
    } 

} 

=>不要叫你的入门级“主”

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())设置值并获取由获取者(Device[i].getCode())返回的数组的副本的值

因此,每个设备都有“自己”的代码数组

+0

我已经复制了您的示例代码,并且在到达“device [0] .setCode(0);”行时仍然收到空指针异常错误。非常令人沮丧。 – CelestialCoyote

+0

这是正常的...你不设置任何值索引0.创建一个设备,把它一个索引0,然后你可以用它来设置你的代码像:device [0] = new Device();此时是“如你所愿”!你可以最终通过“devNumber”作为参数来设置代码[] –

+0

好吧,我得到了它的工作。仍然有点困惑,为什么我创造了两次设备。我认为行Device [] device = new Device [256]会创建空设备,但是我必须创建单个设备并将它们放入数组中? – CelestialCoyote