Java inputStreamReader Charset
Asked Answered
M

6

5

I want to ping a target IP address and receive a response. To achieve this, I'm using windows command line in Java with runtime.exec method and process class. I'm getting the response using inputStreamReader.

My default charset is windows-1254, it's Turkish. When I receive it, the response contains Turkish characters but Turkish characters are not displayed correctly in the console.

I want to get a numeric value from the response I get but the value that I am searching for contains some Turkish characters, so when I look it up, I can't find it.

The codes are below, what I need to know is how to get the Turkish characters visible here:

runtime = Runtime.getRuntime();
process = runtime.exec(pingCommand);

BufferedReader bReader = new BufferedReader(
        new InputStreamReader(process.getInputStream(), "UTF8"));

String inputLine;
while ((inputLine = bReader.readLine()) != null) {
    pingResult += inputLine;
}

bReader.close();
process.destroy();

System.out.println(pingResult);
Moidore answered 1/5, 2011 at 17:14 Comment(3)
why are you specifying "UTF-8" if you know your encoding is "windows-1254"?Wilhelmstrasse
Erm, You're specifying UTF8.Indecent
I tried windows-1254, unfortunately, the same result.Moidore
M
6

In order to fix this, checking the charset that your current operating system uses on its command line and getting the data compatible with this charset is necessary.

I figured out that charset for Turkish XP command line is CP857, and when you edit the code like below, the problem is solved.

BufferedReader bReader = new BufferedReader(
        new InputStreamReader(process.getInputStream(), "CP857"));

Thx for your help.

Note : You can learn your default command line charset by "chcp" command.

Moidore answered 4/5, 2011 at 18:53 Comment(0)
Z
2

If you just need to ping and get the response time, then reading the output from the console might be overkill. There's an easier way so long as you're using Java5 or newer:

Here is a complete program that you can use to do this. NOTE: On Unix/Linux/Mac OS, you have to run this program under "sudo" in order to get a response from anything other than "localhost".

import java.net.InetAddress;
import java.io.IOException;

class PingTest {

  public static void main(String[] args) {
    try {
      String hostnameOrIP = args[0];
      int timeout = Integer.parseInt(args[1]);
      int pingCount = Integer.parseInt(args[2]);

      System.out.println("Pinging '" + hostnameOrIP + "'");
      for (int i = 0; i < pingCount; i++) {
        System.out.println("Response time: " + getPingResponseTime(hostnameOrIP, timeout));
      }
    } catch (Exception e) {
      System.out.println("Usage: java PingTest <hostname/IP address> <timeout in milliseconds> <number of pings to send>\n");
    }
  }

  static long getPingResponseTime(String hostnameOrIP, int timeout) {
      long startTime = System.currentTimeMillis();

      boolean successfulPing = false;

      try {
        successfulPing = InetAddress.getByName(hostnameOrIP).isReachable(timeout);
      } catch (IOException ioe) {
        successfulPing = false;
      }

      long endTime = System.currentTimeMillis();

      long responseTime = endTime-startTime;

      if (successfulPing == false)
        responseTime = -1;

      return responseTime;
  }

}

Here are the results that I got back when I ran the following on Mac OS (results are in milliseconds):

$ sudo java PingTest google.com 5000 5
Pinging 'google.com'
Response time: 419
Response time: 15
Response time: 15
Response time: 16
Response time: 16

Reponse times may vary between runs, but I'm seeing < 20 millisecond response times to most major sites, especially if you run multiple pings

Zuzana answered 1/5, 2011 at 17:47 Comment(12)
isReachable produces a boolean, but i want to a numeric value, so I want to know how much times it responds the target device. Windows command line is convenient for me, because at the next time, i will do another work with command line (telnet etc.).Moidore
I've modified my answer to calculate the response time. So long as "isReachable" returns true, then you know it was successful, and it's trivial to calculate the start and end time. If "isReachable" is false, then either (1) the system is not online / doesn't respond to pings, or (2) didn't respond before the "timeout" expired.Zuzana
I just tried this, according to my ip, ping result is about 75ms in command line ping (cmd), but this program produced about 2000ms. Unfortunately, it doesn't work correctly.Moidore
I edited my answer/code sample to include a full program that does this. I'm getting great response times from my machine to major websites (such as google.com). If you simply run it from the command line using "java PingTest", it will output the usage, and will explain how to use it. Good luck!Zuzana
Maozturk - did you loop a few times, to let the JVM warmup?Salpingitis
I copied your codes, and ran. But according to I entered ip, your program's ping results are -1, -1, 1141, 1531, -1. But cmd result is lower than 1ms. Why? Your program's result is not same cmd's result.Moidore
Don't know - works great on my machine. I got a few slower pings, but nothing like what you're talking about. Did you try the exact example from above (ping to google.com 5 times, with a timeout of 5000 milliseconds)? Also, what OS are you running this code on - it shouldn't really make any difference, but it might provide some insight into what's happening.Zuzana
I tried exact example, only difference is i didn't use command line, i used parameters on the program as timeout = Integer.parseInt("5000"); My OS is Windows XP. It doesn't work correctly on my OS.Moidore
What version of the JVM are you using (e.g. Java6-update 22, etc.)? I have a Windows machine at work. I'll try it there and see if my mileage varies.Zuzana
My version is 6 Update 24. Thanks for your help.Moidore
Installed the same version on my laptop at work (6 Update 24), and I still get the same results. I'm running Win7 32-bit. I don't have a WinXP machine around here. Sorry Maozturk - not sure why it's different on your setup. :(Zuzana
You helped me figure out something that was pretty vital for me, thanks for your time normalocity. I suppose pinging by using command line is the most practical solution.Moidore
S
2

Are you saying the characters are being retrieved properly but System.out isn't printing them right? System.out is definitely an OLD class. Maybe try

PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out,"charactersethere"));
out.println(“encoded system”);
out.flush();
out.close();

That MIGHT work

Salpingitis answered 1/5, 2011 at 17:53 Comment(1)
I don't want print this result, i want to get numeric ping response value. I will find that numeric value from word which before of this value (time=55ms, searching time word)Moidore
P
1

System.out(...) - and the Java console - is quite limited in encoding. You can expect basic ASCII characters to work, and that's about all. If you want to use any other encoding, then you should be writing the output to a text file or to a GUI. If you write to the console you'll always have to cope with poor handling of various non-ASCII characters.

Protestation answered 1/5, 2011 at 18:55 Comment(1)
Actually, i will use ping result (milisecond) in a web page, but i must get that numeric ping result from that text which doesn't contains turkish character. What can i do?Moidore
S
0

You need to change your eclipse default encoding setting under preferences. It can be set to UTF8.

Sixfooter answered 2/7, 2011 at 12:14 Comment(2)
What makes you think the OP is using Eclipse?Recount
I don't use Eclipse, im using Netbeans and my IDE default encoding setting is UTF8 already. Furthermore, i solved this problem. Solution is in my answer. Thanks for your answer.Moidore
S
0

Try this command line command:

chcp

My command line answered 866 so I used CP866

Sled answered 5/6, 2013 at 10:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.