在java中将十六进制字符解码为ascii时的奇怪行为

xkftehaa  于 2021-07-08  发布在  Java
关注(0)|答案(1)|浏览(579)

我编写了一个java程序来获取文件的行,并整理出一个特定的id,然后将其从十六进制转换为ascii字符。在找到“0d”十六进制字符之前,它对几个文件都很有用,似乎是回车符(不知道这是怎么回事)。
当它遇到这种情况时,它将结束行输出(它不应该这样做)。我搞不清楚发生了什么事。
这是代码,编译时没有错误。我附上了一张结果照片。

文件1包含在id之前的字符=:lenght=8 在那之后需要转换8个十六进制字符。之后,程序转换并在同一行中添加文本。我需要他们站在同一条线上找出规律。

  1. import java.io.*;
  2. import java.util.Scanner;
  3. import java.io.FileWriter;
  4. import java.io.IOException;
  5. public class FrameDecoder {
  6. public static void main(String[] args) throws IOException {
  7. try {
  8. // Sortam frameurile cu id-ul tinta
  9. File fisierSursa = new File("file1.txt"); //Fisierul original
  10. FileWriter fisierData = new FileWriter("file2.txt"); //Fisierul cu frameurile care au id-ul cautat
  11. FileWriter fisierTranzit = new FileWriter("file3.txt"); //Fisier cu caractere HEX, care va fi sters.
  12. Scanner citireSursa = new Scanner(fisierSursa);
  13. while (citireSursa.hasNextLine()){
  14. String data = citireSursa.nextLine();
  15. //System.out.println("data = " + data);
  16. int intIndex = data.indexOf("ID=289"); // idul pe care il cauti
  17. int intIndex2 = data.indexOf("ID=1313"); //al doilea id pe care il cauti
  18. if (intIndex != -1 || intIndex2 != -1){
  19. char[] text = data.toCharArray();
  20. int counter = 0;
  21. for (int i=0; i<text.length; i++){
  22. if (text[i] == ':' && counter < 5){
  23. counter++;
  24. }
  25. if (text[i] == ':' && counter == 5){
  26. fisierTranzit.write(text[i+1]);
  27. fisierTranzit.write(text[i+2]);
  28. }
  29. }
  30. fisierTranzit.write("\r\n");
  31. fisierData.write(data + "\r\n");
  32. }
  33. }
  34. citireSursa.close();
  35. fisierTranzit.close();
  36. fisierData.close();
  37. // Convertire HEX to ASCII
  38. FileWriter fisierAscii = new FileWriter("file4.txt"); //Fisier care va contine caraterele ASCII decodate
  39. File fisierTranzitRedeschis = new File("file3.txt"); //Reinitializam fisierul tranzit pentru a putea citi din el
  40. Scanner citireTranzit = new Scanner(fisierTranzitRedeschis);
  41. while (citireTranzit.hasNextLine()){
  42. String data2 = citireTranzit.nextLine();
  43. System.out.println("data2 = " + data2);
  44. if (data2.length() % 2 != 0){
  45. System.err.println("Invalid hex string!");
  46. return;
  47. }
  48. StringBuilder builder = new StringBuilder();
  49. for (int i=0; i<data2.length(); i=i+2){
  50. //Impartim sirul in grupe de cate doua caractere
  51. String s = data2.substring(i, i+2);
  52. //Convertim fiecare grup in integer folosinf valueOfTheMetod
  53. int n = Integer.valueOf(s, 16);
  54. //Convertim valoare integer in char
  55. builder.append((char)n);
  56. }
  57. fisierAscii.write(builder.toString() + "\r\n");
  58. //System.out.println(builder.toString());
  59. }
  60. citireTranzit.close();
  61. fisierAscii.close();
  62. //Stergem fisierul 3
  63. File stergereFisier3 = new File("file3.txt");
  64. if(stergereFisier3.delete()){
  65. System.out.println("File 3 deleted successfully");
  66. }else{
  67. System.out.println("Failed to delete file 3");
  68. }
  69. // Combinam fisierele
  70. PrintWriter fisierFinal = new PrintWriter("file5.txt");
  71. BufferedReader br1 = new BufferedReader(new FileReader("file2.txt"));
  72. BufferedReader br2 = new BufferedReader(new FileReader("file4.txt"));
  73. String line1 = br1.readLine();
  74. String line2 = br2.readLine();
  75. //loop to copy lines
  76. //of file1.txt and file2.txt
  77. //to file3.txt alternatively
  78. while (line1 != null || line2 !=null){
  79. if(line1 != null){
  80. fisierFinal.print(line1 + " ");
  81. line1 = br1.readLine();
  82. }
  83. if (line2 != null){
  84. fisierFinal.println(line2 );
  85. line2 = br2.readLine();
  86. }
  87. }
  88. fisierFinal.flush();
  89. //closing resources
  90. br1.close();
  91. br2.close();
  92. fisierFinal.close();
  93. System.out.println("Merged files succesfully");
  94. //Stergem fisierul 2 si 4
  95. File stergereFisier2 = new File("file2.txt");
  96. File stergereFisier4 = new File("file4.txt");
  97. if(stergereFisier2.delete() && stergereFisier4.delete()){
  98. System.out.println("Files 2 and 4 deleted successfully");
  99. }else{
  100. System.out.println("Failed to delete files 2 and 4");
  101. }
  102. }catch (FileNotFoundException e){
  103. System.out.println("An error occurred.");
  104. e.printStackTrace();
  105. }catch (IOException e){
  106. System.out.println("No data to print");
  107. e.printStackTrace();
  108. }
  109. }
  110. }

编辑:我作弊了一点,在打印十六进制字符时设置了一个条件,如果遇到0d,就用00替换。成功了。我也会试试你的方法,那一种似乎比我的好。

  1. for (int i=0; i<text.length; i++){
  2. if (text[i] == ':' && counter < 5){
  3. counter++;
  4. }
  5. if (text[i] == ':' && counter == 5){
  6. if(text[i+1] == '0' && text[i+2] == 'D'){
  7. fisierTranzit.write('0');
  8. fisierTranzit.write('0');
  9. }
  10. else{
  11. fisierTranzit.write(text[i+1]);
  12. fisierTranzit.write(text[i+2]);
  13. }
  14. }
  15. }
t2a7ltrp

t2a7ltrp1#

回车符 \r (十六进制) 0D )是标准行分隔符字符之一,并且 Scanner.hasNextLine() 以及 nextLine() 方法假定它必须终止当前行。
要获得更多控制,请设置 delimiter 扫描仪只需换行字符 \n 并使用hasnext/next方法而不是hasnextline/nextline方法。例如:

  1. Scanner citireTranzit = new Scanner(fisierTranzitRedeschis);
  2. citireTranzit.useDelimiter("\n");
  3. while (citireTranzit.hasNext()){
  4. String data2 = citireTranzit.next();
  5. ...
  6. }

相关问题