Hello!

I need to read from a txt file ip:port (or in some lines ip:portDdateCinteger). But i can not do it because there is no nextChar method on Scanner class.

The txt file is like this:

332.234.
123.32.45.43.32.11:8976D12.01.2010C5
44.44.
222.333.
111.11.11.11.22.33:8080D01.01.2009C1

...

There are million line on txt file. I need to read one by one from my Java program by reading ip, port, if exist date and check number.

This program must work multi-platform. Thats why i get the end of line string with System.getProperty("line.separator") method.

Can someone help me please?

Thank you!

Dani AI

Generated

Brief follow-up that ties the thread together and gives a robust, cross-platform solution.

As showed, reading whole lines first is the right idea; as and noted, tokenizers/delimiters can help but they get fragile when some lines have the extra D...C... tail and some do not. A reliable, fast approach is: stream the file line-by-line (so no whole-file memory use), split each line deterministically (not by catching exceptions), and parse the expected pieces. BufferedReader.readLine() (or Files.lines) already handles CR/LF differences across platforms, so no manual line-separator logic is required.

Efficient parsing example (index-based, avoids regex overhead):

try (BufferedReader br = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
    String line;
    while ((line = br.readLine()) != null) {
        line = line.trim();
        if (line.isEmpty()) continue;
        int d = line.indexOf('D');
        String main = (d >= 0) ? line.substring(0, d) : line;    // ip:port
        String tail = (d >= 0) ? line.substring(d + 1) : null;   // dateCnumber

        int colon = main.lastIndexOf(':');
        if (colon < 0) continue; // malformed
        String ip = main.substring(0, colon);
        int port = Integer.parseInt(main.substring(colon + 1));

        String date = null;
        Integer check = null;
        if (tail != null) {
            int c = tail.indexOf('C');
            if (c >= 0) {
                date = tail.substring(0, c);               // "dd.MM.yyyy"
                check = Integer.parseInt(tail.substring(c + 1));
                // parse date with java.time if needed:
                // LocalDate ld = LocalDate.parse(date, DateTimeFormatter.ofPattern("dd.MM.yyyy"));
            }
        }
        // process ip, port, optional date/check
    }
}

If a single regexp is preferred (precompile the Pattern once for speed), use a pattern such as ([^:]+):(\\d+)(?:D([^C]+)C(\\d+))? and read groups. Tips: precompile Patterns, handle NumberFormatException/date parse errors, trim and skip blank lines, and beware IPv6 (contains ':' — use a different splitting rule for IPv6). For million-line files, avoid per-token Scanner and exception-based control flow — the index-based or precompiled-regex approaches are faster and clearer.

Recommended Answers

All 9 Replies

you can use StringTokenizer class inorder to differentiate ip and port

Have you tried the Scanner class's useDelimiter() method?
Try this:

Scanner input = new Scanner("332.234.32.11.11.222:8080");
            input.useDelimiter("\\.");
            while(input.hasNext()) {
              System.out.println("next="  + input.next());
            }

StringTokenizer and useDelimiter can not solve my problem :( because i am not sure if the line ends with end_of_line character or 'D' character. StringTokenizer and useDelimiter can split the string if we know which character splits the string. I told you some line has date and check number hut some of them does not.

i am not sure if the line ends with end_of_line character or 'D' character

If you don't know the delimiters for a line, that makes it very hard to read a "line".
By 'D' do you mean the character 'D' or 0xd ?
What is the format of the data on a line? How will you know when you are at the end of a line?

With that:
read.useDelimiter(" : | " + end_of_line+ "|D|C");
i can not understand if the line ends or not :(

If you don't know the delimiters for a line, that makes it very hard to read a "line".
By 'D' do you mean the character 'D' or 0xd ?
What is the format of the data on a line? How will you know when you are at the end of a line?

I mean the character 'D' .

The format of line is very simple

ip:port OR ip:portDdateCnumber
example for each
332.234. OR 123.32.45.43.32.11:8976D12.01.2010C5

It will be very simple if java scanner had a nextChar() method :( .

End of line character is System.getProperty("line.separator")

End of line character is System.getProperty("line.separator")

On my system that character has a value of 0x0d0a.
What is the value on your system?

String lineSep =  System.getProperty("line.separator");
      System.out.print("l.s="); 
      for(int i=0; i < lineSep.length(); i++)
          System.out.print(Integer.toHexString(lineSep.charAt(i)) + " ");  // l.s=d a

What does the Scanner class do when reading a file with lines separated by 0x0d0a characters? Have you tried that?

On my system that character has a value of 0x0d0a.
What is the value on your system?

String lineSep =  System.getProperty("line.separator");
      System.out.print("l.s="); 
      for(int i=0; i < lineSep.length(); i++)
          System.out.print(Integer.toHexString(lineSep.charAt(i)) + " ");  // l.s=d a

What does the Scanner class do when reading a file with lines separated by 0x0d0a characters? Have you tried that?

My line sperator is "d a" at the moment(i am on windows now). (My program must work multiplatform (linux-unix-win) ).

Why you asked my end seperator ?

Why you asked my end seperator ?

Your program needs to read each line. To do that it needs to know what defines the end of a line.
When a line has been read, then you need to parse the line to get the values from the line.
Are you able to read the file, line by line?
Write a small simple test program to read the first 10 lines from the file and print them out to be sure you can read a line.

I solve the problme. I don't need to understand if i am on end of line. Because i read first all the line and i put it on a string. After that i read the Scanner.next with useDelimiter(" : |D|C"). If it gives error (which i catch it with try-catch) when i read with Scanner.next that means this line includes just ip and port. if it will not give me an error that means it has also date and check numnber. I try it it works :)

Thanks for your helping me... :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.