2013-03-23 71 views
1

我刚开始学习Java,对于我的第一个挑战,我试图从MP3中读取ID3v1标记。我将一个MP3的最后128个字节读入一个字节数组,然后从那里分割出来。为了检查我发现了一个有效的ID3标签,我将数组中的前3个字节转换为一个字符串,并将其与“TAG”进行比较。问题是由字节组成的字符串永远不会匹配“TAG”字符串,即使它看起来应该在我在eclipse调试器中运行它的时候。Java - 将字节转换为字符串并与另一个字符进行比较

我粘贴了我在下面使用的代码,任何人都可以请指出我在这里做错了什么?

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; 
} 
+1

[如何比较字符串我[Java](http://stackoverflow.com/search?q=java+string+compare) – Eran 2013-03-23 21:52:16

回答

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")); 
+1

甚至'tagHeader = new String(tagBytes)'。 – Vulcan 2013-03-23 21:55:21

+0

好的电话,谢谢你的建议。 – dimo414 2013-03-23 22:11:40

0

变化tagHeader != "TAG"!tagHeader.equals("TAG")

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

为了清楚起见,我是这样写的。对于空安全代码,你应该总是首先使用字面值。

"TAG".equals(tagHeader) 
1

您可以转换字节为String,如果你确信它们都是ASCII(或者,如果你知道的编码)。那么你应该比较equals而不是!=,因为稍后检查它是否不是相同的实例。在你的情况下,它总是一个不同的例子。

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

这会变成字节为String和正确:

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

您的解决方案也适用。这是你的比较,这是问题。你想:

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

在字符串的情况下,!===测试这两个字符串是相同的实例,而不是相同的值。您需要使用equals()方法按值进行比较。

变种: 要选择字节数组的只是一部分:

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

如果整个字节数组已转换为字符串,你想看看,如果它不与“TAG”启动:

if (!tagHeader.startsWith("TAG")) { 
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"); 
    } 
}