1

Java の学習を始めたばかりで、最初の課題として、MP3 から ID3v1 タグを読み取ろうとしています。MP3 の最後の 128 バイトをバイト配列に読み込み、そこから分割しました。有効な ID3 タグが見つかったことを確認するには、配列の最初の 3 バイトを文字列に変換し、それを「TAG」と比較します。問題は、バイトから構成された文字列が「TAG」文字列と一致しないことです。Eclipse デバッガーで実行すると一致するように見えますが。

以下に使用しているコードを貼り付けました。ここで間違っていることを誰か指摘してもらえますか?

byte tagBytes[] = {84, 65, 71}; //Normally filed from a file, just here as an example.
String tagHeader = null; //String to hold tag header
tagHeader = Character.toString((char)tagBytes[0]) + 
            Character.toString((char)tagBytes[1]) + 
            Character.toString((char)tagBytes[2]);
if (tagHeader != "TAG"){
    System.out.println("No ID3v1 tag found");
    return null;
}
4

5 に答える 5

2

==メモリ内のリテラル参照が同じかどうかをチェックするため、文字列を比較することはできません。代わりに、大文字と小文字を区別しない比較を実行"TAG".equals(tagHeader)または実行します。"TAG".equalsIgnoreCase(tagHeader)

次のように、文字列の構築を単純化することもできます。

StringBuilder sb = new StringBuilder();
for(int i = 0; i < 3; i++) {
    sb.append((char)tagBytes[i]);
}
tagHeader = sb.toString();

または、@Vulcanが示唆するように、単純に:

tagHeader = new String(tagBytes,0,3);

charset も指定する必要があるでしょう。そうしないと、バイトが正しく変換されない可能性があります。データのエンコード方法によっては、別の文字セットを指定する必要がある場合があります。

tagHeader = new String(tagBytes,0,3,Charset.forName("UTF-8"));
于 2013-03-23T21:54:22.050 に答える
1

Stringバイトがすべて ASCII であることが確実な場合 (またはエンコーディングがわかっている場合) は、バイトを に変換できます。次に、後で同じインスタンスではないかどうかをチェックするため、equalsnotと比較する必要があります。!=あなたの場合、それは常に別のインスタンスです。

    byte tagBytes[] = {84, 65, 71};
    String tagHeader = new String(tagBytes, Charset.forName("US-ASCII"));
    if (!"TAG".equals(tagHeader)){
        System.out.println("No ID3v1 tag found");
        return null;
    }

Stringまたは、これを行うだけで、冗長なオブジェクトの作成を完全に回避できます。

    byte tagBytes[] = {84, 65, 71};
    if (!('T' == tagBytes[0] && 'A' == tagBytes[1] && 'G' == tagBytes[2])){
        System.out.println("No ID3v1 tag found");
        return null;
    }
于 2013-03-23T21:53:26.310 に答える
1

これにより、バイトが文字列に変換され、適切に次のようになります。

byte tagBytes[] = {84, 65, 71}; 
String s = new String(tagBytes, Charset.forName("US-ASCII"));

あなたのソリューションも機能します。問題はあなたの比較です。あなたがしたい:

if (!tagHeader.equals("TAG")) {

文字列の場合、!=または==2 つの文字列が同じ値ではなく同じインスタンスであることをテストします。メソッドを使用equals()して値で比較する必要があります。

バリアント: バイト配列の一部だけを選択するには:

String s = new String(tagBytes, 0, 3, Charset.forName("US-ASCII"));

バイト配列全体が文字列に変換されており、「TAG」で始まっていないかどうかを確認したい場合:

if (!tagHeader.startsWith("TAG")) {
于 2013-03-23T21:58:11.997 に答える
1

簡単な方法では、次のようにできます。

public static void main(String[] args) {
    byte tagBytes[] = {84, 65, 71}; //Normally filed from a file, just here fro example.
    String tagHeader = null; //String to hold tag header
    tagHeader = new String(tagBytes);
    if (!tagHeader.equals("TAG")){
        System.out.println("No ID3v1 tag found");
    }
 }
于 2013-03-23T21:58:23.577 に答える
0

tagHeader != "TAG"に変更!tagHeader.equals("TAG")

現在、実際の値ではなくメモリ アドレスを比較しています。

わかりやすくするために、このように書きました。null セーフ コードの場合は、常にリテラルを最初に使用する必要があります。

すなわち

"TAG".equals(tagHeader)
于 2013-03-23T21:51:46.753 に答える