1

我有以下代码,从方法中复制/粘贴:

String harmonicFile;
...
...
harmonicFile = String.format("%04d%s",this.number, this.suffix.toUpperCase()) + ".tch";

结果看起来不错,但我有一些时髦:

我将此字符串传递给另一个方法,其中包括:

if(filename.equals(file)){
   return file;
}

fileName 是传入的值,file 是资产文件系统的匹配项。假设文件是​​“0062.tch”。在 Intellij IDEA 调试器中检查文件名显示它等于“0062.tch”,但返回语句从未被命中。仔细检查,我可以看到文件名填充了 8 个空字符 (\u0000)。

我有两个问题:

  1. 为什么要填充字符串?

  2. 在 IDEA 中,中断 if 语句然后使用表达式评估器 (Alt-F8) 显示 filename.equals(file) 为真,但在运行时单步执行我的代码表明它不是。我认为这是 IDEA 评估表达式和 Dalvik VM 方式的一些低级差异?我假设虚拟机是正确的,因为文件名确实不等于文件。

感谢您的任何见解。

西蒙

[编辑] 我相信其余的代码是不相关的,但无论如何,为了节省空间,删除了注释。

public String filePathForHarmonicFile(){

    String harmonicFile;
    int number = this.number;

    if(this.number < 0){ return "";}

    if(number<10000 && this.suffix.length()<=1){
        harmonicFile = String.format("%04d%s",this.number, this.suffix.toUpperCase()) + ".tch";
    }else{
        harmonicFile = String.format("%s%s",this.number,this.suffix.toUpperCase()) + ".tch";
    }

    return SCFileManager.getAssetFilePath("",harmonicFile);
}

public static String getAssetFilePath(String rootOfSearch, String filename){

    try {

        // get a list of all file entries in the search root
        String[] files = ThisApplication.getContext().getAssets().list(rootOfSearch);

        for (String file:files){

            String newRoot;
            if (rootOfSearch.equals("")){
                newRoot = file;
            } else {
                newRoot = rootOfSearch + File.separator + file;
            }

            if (TidesPlannerApplication.getContext().getAssets().list(newRoot).length>0){

                String thisFile = getAssetFilePath(newRoot,filename);

                if (!thisFile.equals("")){
                    return thisFile;
                }
            } else {
                if(file.equals(filename)){
                    return file;
                }
            }
        }

    } catch (IOException e) {
        e.printStackTrace();  
    }

    return "";

}

我知道最后一种方法很难看,但如果有人知道更好的方法来处理资产子文件夹中的 7.5k 文件,我全都听好了——AssetManager 是 $%^&* 脑死!

4

3 回答 3

1

1)除非我遗漏了什么,否则您的字符串是填充的,因为格式语句"%04d%s"将用零填充以达到 4 位数字,因此是“0062.tch”。我错过了什么吗?

对于空字符的正确填充,请注意几点。首先,每个十六进制字符是半个字节,因此 (\u0000) 是两个字节,因此是一个字符。此外,IDE 会显示在 中分配的所有字节String,但是在打印、比较等时,它会在第一个空字符处停止。

于 2012-08-19T14:49:54.277 回答
1

在评论中你写了这个。

正确的。如果我检查后备字符数组,它看起来像这样:[0] [0] [6] [2] [.] [t] [c] [h] [\u0000] [\u0000] [\u0000] [\u0000] [\u0000] [\u0000] [\u0000] [\u0000]

这并不一定意味着 String 与 NUL 一起传递。

字符串的状态由从value[offset]到的字符组成value[offset + count - 1]。我推测这offset一定是零,但没有真正的证据表明它的价值count是......

这些 NUL 很可能超出了 String 状态的结尾,因此不是问题的原因。

于 2012-08-19T15:18:06.863 回答
0

呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜呜 怎么可能花超过 3 个小时来解决一个问题,为 SO 寻求帮助,然后在 5 分钟后发现愚蠢之处?感谢所有花时间回复的人,并为浪费空间和时间而道歉。

第二种方法是对资产文件夹的递归搜索。可以看到递归调用的结果存储在thisFile中。因此,if 语句应为:

if(thisFile.equals(filename)){}

也就是说,我仍然很好奇为什么 filename 用空值填充而 file 和 thisFile 没有。然而,深奥的兴趣只是因为代码现在可以工作......

于 2012-08-19T15:23:18.693 回答