【问题标题】:reading a long type from a text file in Java从 Java 中的文本文件中读取长类型
【发布时间】:2012-03-10 15:52:33
【问题描述】:

我正在尝试使用BufferedReader 类的readLine() 方法从文本文件中读取长类型,然后我使用StringTokenizer 解析第一个令牌(长类型编号),但我面临异常错误为java.lang.NumberFormatException

这是我的文本文件的示例;

2764841629  Quaroten Ilen
1398844030  Orden Nenama
1185252727  Inja Nenaptin
2370429126  Quaren Inaja
1502141743  Otin Una
1993687334  Quarwennaja Nenoten
1015934104  Polen Meritna
2363674760  Otja Ie
1904629749  Neninin Ordja
3047965620  Algnaja Nenja

这是我从文本文件中读取的代码并将长值赋给我的长变量

private void registerData() throws FileNotFoundException{
    try {

        String regPatName;
        String regPatSurname;
        long regPatID;


        FileInputStream fis = new FileInputStream("src\\assignment_3\\injuredPersonList.txt");
        BufferedReader reader = new BufferedReader(new InputStreamReader(fis));

        String line;

        while( ( line = reader.readLine() ) != null) {

            StringTokenizer st = new StringTokenizer(line, " ");

            while(st.hasMoreTokens()){

                regPatID = Long.parseLong(st.nextToken());
                regPatName = st.nextToken();
                regPatSurname = st.nextToken();

                Patient regPatient = new Patient(regPatName, regPatSurname, regPatID);
                hashMethod(regPatient);
            }

        }
    } catch (IOException ex) {
        Logger.getLogger(personTest.class.getName()).log(Level.SEVERE, null, ex);
    }


}

private void hashMethod(Patient regPatient){

    Long idPat = new Long(regPatient.getPatientID());
    int keyID;

    keyID = (int) Math.sqrt(Integer.parseInt(idPat.toString().substring(0, 5) + idPat.toString().substring(5, 10))) % (50000);

    System.out.println(keyID);

}

最后这是我面临的错误;

Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: "2481765933   Otna"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
    at java.lang.Long.parseLong(Long.java:419)
    at java.lang.Long.parseLong(Long.java:468)
    at assignment_3.personTest.registerData(personTest.java:58)
    at assignment_3.personTest.<init>(personTest.java:33)
    at assignment_3.personTest$1.run(personTest.java:161)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:641)
    at java.awt.EventQueue.access$000(EventQueue.java:84)
    at java.awt.EventQueue$1.run(EventQueue.java:602)
    at java.awt.EventQueue$1.run(EventQueue.java:600)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:611)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

如果您能帮助我,我将不胜感激,也谢谢您。

【问题讨论】:

  • 请发布您获得的整个堆栈跟踪。此外,提供示例文本文件可能是个好主意。
  • 好的,我会立即编辑我的帖子
  • 您的输入文件选项卡不是被任何机会分开了吗?制表符 != 空格字符。尝试在不指定分隔符的情况下初始化您的字符串标记器。 (默认为所有空格。)
  • 确保将正确的字段传递给 Long.parseLong()。 System.out.println(st.nextToken())
  • @biziclop 感谢您的建议,但现在它给出了 java.lang.NumberFormatException: For input string: "2481765933"

标签: java long-integer stringtokenizer numberformatexception


【解决方案1】:

您可能有一个制表符而不是空格来分隔您的字段。将制表符添加到您的分隔符集 (" \t")。

此外,请始终在 finally 块中关闭您的流和阅读器(只有最外面的必须关闭:关闭 BufferedReader 将关闭 InputStreamReader,这将关闭 FileInputStream)。

【讨论】:

  • 感谢您的建议,但除了抛出 java.lang.NumberFormatException:对于输入字符串:“2481765933”外,没有任何改变。输入字符串不再包含其他标记
  • 这个字符串是一个有效的长表示,我解析它没有任何问题。你确定它不包含一个看起来像 ASCII 数字但不是一个奇怪的字符吗?
  • 它在读取第一行时会给出错误。我检查前一千行是否包含奇怪的字符,但不是。
  • 将此 sn-p 添加到您的代码中:String s = st.nextToken(); for (char c : s.toCharArray()) {System.out.print(" " + (int) c);} System.out.println(); regPatID = Long.parseLong(s); 并告诉我们在抛出异常之前打印的内容。
  • 它给出“50 52 56 49 55 54 53 57 51 51”和exception is Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: "Otna"
【解决方案2】:

很明显,您正在尝试解析非数字字符串,堆栈跟踪显示它:2481765933 Otna。您应该拆分输入并解析数字部分,如下所示:

String[] data = line.split("\\s+");
regPatID = Long.parseLong(data[0]);
regPatName = data[1];
regPatSurname = data.length == 3 ? data[2] : "";

上面比使用StringTokenizer简单得多。事实上,StringTokenizer 的用法是 discouraged,实际上已被弃用 - 现在,解析字符串的首选方法是对简单情况使用 split() 方法或对复杂情况使用 Scanner 类。

【讨论】:

  • 但是当我读入整数值时,我多次使用这种解析方法,比如当我有行“21321 otna”时。我想唯一的问题是关于长类型
【解决方案3】:

您使用了错误的分隔符 (" "),因为您的文本文件在标记之间可能包含多个空格字符。 StringTokenizer 是一个遗留类,除非你有充分的理由,否则不要使用它。 String.split() 应该足够了:

String[] result = line.split("\\s+");
regPatID = Long.parseLong(result[0]);
regPatName = result[1];
regPatSurname = result[2];

但我认为Scanner 最适合您的问题:

// Java 7 try-with-resources synthax.
// If you are using Java <=6, declare a finally block after the catch 
// to close resources.
try (InputStream myFile = ClassLoader.getSystemResourceAsStream("MyTextFile.txt");
        Scanner sc = new Scanner(myFile)) {

    while (sc.hasNext()) {
        regPatID = sc.nextLong();
        regPatName = sc.next();
        regPatSurname = sc.next();

        System.out.printf("%d - %s %s\n", regPatID, regPatName, regPatSurname);
    }

} catch (Exception e) {
    // Do something about exceptions
}

两个版本都能正确解析您的示例输入。

这是第三个fully working Java 6 Version。

【讨论】:

  • 好吧,当我打印出“result[0]”和“regPatID”时,它会打印出真实值,但我再次面临同样的愚蠢错误。我的意思是它确实分配了,但我不知道为什么我又犯了同样的错误。
  • 伙计,我在 5 分钟前解决了这个问题,这是关于我在 hashMethod() 中使用 Integer.parseInt(),正如您在我的问题中看到的那样。是的,这也可以正常工作,感谢您的帮助
  • 嗨quartaela,我很高兴为您服务,既然您已经弄清楚了,您应该接受@JB Nizet 或Óscar López 的回答,通过帮助您解决原始问题来奖励他们;)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多