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

时间:2019-02-14 07:17:36

标签: java mp3

我正在尝试从mp3文件中读取数据,以便以后可以将它们作为十六进制进行操作。假设我在文本编辑器中打开了一个mp3文件,并且看到了字符ÿû²d。转换应以十六进制(表示标题)读取FF FB B2 64。但是,出现在输出文本文件中的十六进制为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();
  }
}

1 个答案:

答案 0 :(得分:0)

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

来源: https://stackoverflow.com/a/18434549/10589287

更新代码:

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

}