将 mp3 文件中的字节表示为十六进制字符串

Representing Bytes From an mp3 File as Hexadecimal Strings

我正在尝试从 mp3 文件中读取数据,以便以后可以将它们作为十六进制进行处理。假设如果我在文本编辑器中打开一个 mp3 文件并且我看到字符 ÿû²d。翻译应该是十六进制的 FF FB B2 64(表示 header)。但是,输出文本文件中出现的 Hex 是 6E 75 6C 6C,我不明白为什么。

来源:

Java code To convert byte to Hexadecimal

convert audio,mp3 file to string and vice versa

How to check the charset of string in Java?

我的代码:

package mp3ToHex;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.nio.charset.*;

public class mp3ToHex {
  public static void main(String[] args) {
    //directories
    String fileIn = "Some\Input\Directory.mp3", fileOut = "Some\Output\Directory.txt";
    outputData(fileOut, fileIn);
  }
  @SuppressWarnings("unused")
  public static String readFile(String filename) {
    // variable representing a line of data in the mp3 file
    String line = "";
    try {
      BufferedReader br = new BufferedReader(new FileReader(new File(filename)));

      while (br.readLine() != null) {
        line += br.readLine();

        try {
          if (br == null) {
            // close reader when all data is read
            br.close();
          }

        } catch (FileNotFoundException e) {
          e.getMessage();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    } catch (FileNotFoundException e) {
      e.getMessage();
    } catch (IOException e) {
      e.printStackTrace();
    }
    return line;
  }
  public static void outputData(String outputFile, String inputFile) {
    try {
      // Create file
      FileWriter fileStream = new FileWriter(outputFile);
      BufferedWriter writer = new BufferedWriter(fileStream);
      // Convert string to hexadecimal
      String output = toHex(readFile(inputFile));
      StringBuilder s = new StringBuilder();
      for (int i = 0; i < output.length(); i++) {
        // Format for easier reading
        if (i % 64 == 0) s.append('\n');
        else if (i % 2 == 0) s.append(' ');
        s.append(output.charAt(i));
      }
      // Write to file
      writer.write(s.toString());
      // Close writer
      writer.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  // Converts strings to hexadecimal
  public static String toHex(String arg) throws UnsupportedEncodingException {
    return String.format("%02X", new BigInteger(1, arg.getBytes(charset(arg, new String[] {
      "US-ASCII",
      "ISO-8859-1",
      "UTF-8",
      "UTF-16BE",
      "UTF-16LE",
      "UTF-16"
    }))));
  }
  // Converts strings to different encodings
  public static String convert(String value, String fromEncoding, String toEncoding) throws UnsupportedEncodingException {
    return new String(value.getBytes(fromEncoding), toEncoding);
  }
  // Detects which Charset a string is encoded in by decoding and re-encoding a string. The correct encoding is found if the transformation yields no changes.
  public static String charset(String value, String charsets[]) throws UnsupportedEncodingException {
    String probe = StandardCharsets.UTF_8.name();
    for (String c: charsets) {
      Charset charset = Charset.forName(c);
      if (charset != null) {
        if (value.equals(convert(convert(value, charset.name(), probe), probe, charset.name()))) {
          return c;
        }
      }
    }
    return StandardCharsets.UTF_8.name();
  }
}

在对该程序进行一些试验后,我发现 运行 编码配置改变了输出。通过导航至 Run>Run Configurations>[file name]>Common>Encoding,从下拉列表中选择 ISO-8859-1 解决了该问题。

来源:

更新代码:

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.*;
import java.nio.file.Files;
import java.nio.file.Paths;

public class mp3ToHex {

  public static void main(String[] args) throws IOException {
    //directories
    String fileIn = "Some\Input\Directory\input.mp3",
      fileOut = "Some\Output\Directory\out.txt",
      log = "Some\Log\Directory\log.txt",
      debug = "Some\Debug\Directory\debug.mp3";

    BufferedWriter br = new BufferedWriter(new FileWriter(fileOut)),
      brL = new BufferedWriter(new FileWriter(log)),
      brD = new BufferedWriter(new FileWriter(debug));
    String s = readFile(fileIn, Charset.forName(StandardCharsets.ISO_8859_1.name()));
    brD.write(s);
    byte[] bytes = s.getBytes();
    brL.write(bytesToHex(s.getBytes()));
    StringBuilder binary = new StringBuilder();
    for (byte b: bytes) {
      int val = b;
      for (int i = 0; i < 8; i++) {
        binary.append((val & 128) == 0 ? 0 : 1);
        val <<= 1;
      }
      binary.append(' ');

    }
    br.write(binary + "");
    br.close();
  }
  static String readFile(String path, Charset encoding)
  throws IOException {
    byte[] encoded = Files.readAllBytes(Paths.get(path));
    return new String(encoded, encoding);
  }
  private final static char[] hexArray = "0123456789ABCDEF".toCharArray();
  public static String bytesToHex(byte[] bytes) {
    char[] hexChars = new char[bytes.length * 2];
    for (int j = 0; j < bytes.length; j++) {
      int v = bytes[j] & 0xFF;
      hexChars[j * 2] = hexArray[v >>> 4];
      hexChars[j * 2 + 1] = hexArray[v & 0x0F];
    }
    return new String(hexChars);
  }

}