2013-03-11 36 views
0

我有一个文件,我需要搜索编码标签,并检索它们标识的数据。标签长度为4字节,标识可变长度的ASCII字符串或编码Little-Endian的双字节整数值。编码标签的搜索文件

这些标签似乎全部位于4个字节的边界上,并且全部位于文件开头的前2000个字节内。我尝试过搜索文件的各种方法。唯一已经工作的是使用十进制整数值逐字节比较。

在SO上找到了一个解决方案,但并不完全针对此问题提出:indexOfSubList()。 我试过这个测试,但结果是-1。

byte[] needle = {68,73,67,77}; 
byte[] hayStack = {00, 01, 68,73,67,77, 11, 45}; 
location = Collections.indexOfSubList(Arrays.asList(hayStack), Arrays.asList(needle)); 

我决不会忠于这段代码,并希望能有其他想法或解决方案。

+0

“但结果是-1”,你会期望它是什么? – hyde 2013-03-11 14:52:01

+0

如果'hayStack'数组实际包含'needle'数组,那么您的示例将会*更多*更多信息。在那种情况下,'-1'也被返回,这是更有趣的考虑。 – 2013-03-11 14:59:32

+0

我已更正针头 – Mike 2013-03-11 15:01:01

回答

2

你的问题是一种模糊的,你的意思是这样的:

// simplified way of identifying tag by first byte of it, 
// make it more complex as needed 
byte startOfTag = 65; 

// for loop assumes tags start at even 4 byte boundary, if not, modify loop 
for(int i = 0; i <= data.length-4 ; i += 4) { 
    if (data[i] == startOfTag) { 
     myTagHandlerMethod(data[i], data[i+1], data[i+2], data[i+3]); 
    } 
} 

你得-1从Collections.indexOfSubList,因为Arrays.asList如您所愿的byte[]不起作用:它返回List<byte[]>,不是List<Byte>。容器必须包含对象引用,未装箱的数值类型不允许...这应该工作:

Byte[] needle = {68,73,67,77}; 
Byte[] hayStack = {00, 01, 68,73,67,77, 11, 45}; 
location = Collections.indexOfSubList(Arrays.asList(hayStack), Arrays.asList(needle)); 

如果你想避免重新发明轮子而操纵原始类型数组,可以使用Google's Guava libs。例如,您可以在此处使用indexOf方法。

+0

谢谢。你的榜样和邓肯琼斯的作品。现在,我试图从文件中读入Byte []。有任何想法吗?再次感谢。 – Mike 2013-03-11 18:55:15

+0

@Mike只需将一个简单的for循环直接转换为ArrayList ,我不需要任何中间Byte []数组。 – hyde 2013-03-11 19:18:34

+0

@Mike要注意一点:Byte []或ArrayList 将占用基本数组byte []的10倍多的内存,所以如果您可以使用基本数组,则效率会更高。对于现代硬件上的几千字节可能无关紧要,但对于大量数据而言,这是一个杀手。 – hyde 2013-03-11 19:27:43

1

通过转换你的byte阵列Byte阵列,你会得到你想要的结果:

Byte[] needle = { 68, 73, 67, 77 }; 
Byte[] hayStack = { 00, 01, 68, 73, 67, 77, 11, 45 }; 
location = Collections.indexOfSubList(Arrays.asList(hayStack), 
    Arrays.asList(needle)); 

// location now equals 2 

这是因为Arrays.asList不作为你的byte[]对象想象。它返回List<byte[]>而不是List<Byte>