Java:读取文件,第一行丢失

时间:2013-12-31 02:11:20

标签: java android hashmap

我有一个HashMap<String, String>,它保存图像的文件名和显示名称。我逐行读取文件,并将键和值添加到HashMap。

BufferedReader reader;
String line;
String[] lineSplit;

HashMap<String, String> imenaZnaki = new HashMap<String, String>();

try {
    reader = new BufferedReader(new InputStreamReader(am.open("znaki_imena.txt"), "UTF-8"));
    line = reader.readLine();
    while (line != null) {
        lineSplit = line.split("->");
        imenaZnaki.put(lineSplit[0], lineSplit[1]);
        line = reader.readLine();
    }
    reader.close();
} catch (IOException e) {
    e.printStackTrace();
}

除了第一个添加的条目外,一切都按预期工作,.get(key)返回null,.containsKey(key)返回false。所有其他键/值都可以正常存储在HashMap中。

修改

这根本没有意义......在我将内容添加到HashMap之后,我运行了MagicMan提供的代码来检查所有的部分是否都在HashMap中

for(String key: imenaZnaki.keySet()) {
    System.out.println("KEY: " + key + "  VALUE: " + imenaZnaki.get(key));
}

如果我 CTRL + F 代表“nevar_andrej”,它会显示4个输出,这是正确的。但是如果我搜索“nevar_andrej”(带有空格),它只会显示其中的3个,这是错误的,因为第一个会丢失。所以我的猜测是,文件的第一行中有一些东西会引起混淆。所以我添加了一个假/假第一行(bla_bla-&gt; Bla bla)并且它可以工作,但这是一个讨厌的解决方法。

这是我的全文文件,使用UTF-8 http://pastebin.com/6A4r4jm6

进行编码

3 个答案:

答案 0 :(得分:5)

尝试运行以下代码,看看是否所有条目都存在:

for(String key: imenaZnaki.keySet()) {
        System.out.println("KEY: " + key + "  VALUE: " + imenaZnaki.get(key));
}

我能够运行你的代码和你的样本,并在那里弹出所有7个条目。如果不能正常使用,请参阅antiduh的评论;你可能遇到了你在get()调用中使用的字符串的编码问题。

这是从OS X运行,

控制台输出指定UTF-8格式:

KEY: nevar_andrejev_kriz_zelezniska_proga_je_dvo_ali_vectirna  VALUE: Andrejev kri? (?elezni?ka proga je dvo ali ve?tirna)
KEY: nevar_andrejev_kriz_zelezniska_proga_je_dvo_ali_vectirna_2  VALUE: Andrejev kri? (?elezni?ka proga je dvo ali ve?tirna)
KEY: nevar_andrejev_kriz_zelezniska_proga_je_enotirna  VALUE: Andrejev kri? (?elezni?ka proga je enotirna)
KEY: nevar_andrejev_kriz_zelezniska_proga_je_enotirna_2  VALUE: Andrejev kri? (?elezni?ka proga je enotirna)
KEY: nevar_blizina_letaliske_steze  VALUE: Bli?ina letali?ke steze
KEY: nevar_blizina_obale  VALUE: Bli?ina obale
KEY: nevar_blizina_svetlobnih_prometnih_znakov  VALUE: Bli?ina svetlobnih prometnih znakov

更新

因此,这似乎是正在阅读的BOM(http://en.wikipedia.org/wiki/Byte_order_mark)的问题。我最初将文件重新保存为UTF-8,并生成上面的输出。然后我使用编码“UTF-8 with BOM”重新保存文件,它产生了这个:

KEY: ???nevar_andrejev_kriz_zelezniska_proga_je_dvo_ali_vectirna  VALUE: Andrejev kri?? (??elezni??ka proga je dvo ali ve??tirna)
KEY: nevar_andrejev_kriz_zelezniska_proga_je_dvo_ali_vectirna_2  VALUE: Andrejev kri?? (??elezni??ka proga je dvo ali ve??tirna)
KEY: nevar_andrejev_kriz_zelezniska_proga_je_enotirna  VALUE: Andrejev kri?? (??elezni??ka proga je enotirna)
KEY: nevar_andrejev_kriz_zelezniska_proga_je_enotirna_2  VALUE: Andrejev kri?? (??elezni??ka proga je enotirna)
KEY: nevar_blizina_letaliske_steze  VALUE: Bli??ina letali??ke steze
KEY: nevar_blizina_obale  VALUE: Bli??ina obale
KEY: nevar_blizina_svetlobnih_prometnih_znakov  VALUE: Bli??ina svetlobnih prometnih znakov

注意三个?第一行前面的字符。那些BOM字符在十六进制中看起来像这样:EF BB BF。这可能是导致第一行问题的原因。尝试使用Notepad ++或SublimeText

等文本编辑器重新保存没有BOM的文件

答案 1 :(得分:3)

我打电话给Shennanegans ......

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.HashMap;
import java.util.Map.Entry;

public class main {

public static void main(String[] args) {
    BufferedReader reader;
    String line;
    String[] lineSplit;

    HashMap<String, String> imenaZnaki = new HashMap<String, String>();

    try {
        reader = new BufferedReader(new FileReader(new File("test.txt")));
        String firstKey, firstValue;
        firstKey = null;
        firstValue = null;
        line = reader.readLine();
        while (line != null) {
            lineSplit = line.split("->");
            if (firstKey == null) {
                firstKey = lineSplit[0];
                firstValue = lineSplit[1];
            }
            imenaZnaki.put(lineSplit[0], lineSplit[1]);
            line = reader.readLine();
        }
        reader.close();

        System.out.println("contains first split line key: " +  imenaZnaki.containsKey(firstKey));
        System.out.println("contains first split key text dupe: " + imenaZnaki.containsKey("nevar_andrejev_kriz_zelezniska_proga_je_dvo_ali_vectirna"));
        for (Entry<String, String> entry : imenaZnaki.entrySet()) {
            System.out.println("key: " + entry.getKey() + " " + "value: " + entry.getValue());
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

}

}

控制台输出:

contains first split line key: true
contains first split key text dupe: true
key: nevar_blizina_letaliske_steze value: Bližina letališke steze
key: nevar_andrejev_kriz_zelezniska_proga_je_dvo_ali_vectirna_2 value: Andrejev križ (železniÅ¡ka proga je dvo ali veÄ?tirna)
key: nevar_andrejev_kriz_zelezniska_proga_je_enotirna value: Andrejev križ (železniška proga je enotirna)
key: nevar_blizina_obale value: Bližina obale
key: nevar_blizina_svetlobnih_prometnih_znakov value: Bližina svetlobnih prometnih znakov
key: nevar_andrejev_kriz_zelezniska_proga_je_dvo_ali_vectirna value: Andrejev križ (železniÅ¡ka proga je dvo ali veÄ?tirna)
key: nevar_andrejev_kriz_zelezniska_proga_je_enotirna_2 value: Andrejev križ (železniška proga je enotirna)

答案 2 :(得分:1)

我认为问题不在hashmap中 它在文件格式内,我将文件格式更改为GBK以及相关的阅读代码,我可以访问密钥