2016-07-04 138 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