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

您可能还想指定字符集,否则字节可能会被错误地转换。根据数据的编码方式,您可能需要指定不同的字符集:

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

String如果您确定它们都是 ASCII(或者如果您知道编码),则可以将字节转换为 a 。然后你应该与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")) {

如果是String,!=还是==测试一下两个String是同一个实例,不是同一个值。您需要使用该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")

目前,您正在比较内存地址而不是实际值。

为了清楚起见,我这样写。对于空安全代码,您应该始终首先使用文字。

IE

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