It appears to me like JMS TextMessage containing Java.lang.String isn't recognizing \r\n as line-break but instead treating the CR LF as part of input on a Windows machine.
#Override
public void onMessage(Message message) {
try {
String text = ((TextMessage)message).getText();
String line=null;
BufferedReader br = new BufferedReader(new StringReader(text));
for(line = br.readLine(); line != null; line = br.readLine()) {
System.out.println(line);
}
catch (JMSException e) {
System.err.println( "Error processing message: " + e.getMessage() );
e.printStackTrace();
}
Can anyone provide any input and /or recommednations around the same.
It's not completely clear from your question, but it sounds like the string is read correctly on input, but it is not being formatted correctly by the println output.
Control characters like line-feeds and and carriage returns are just like any other character in a string. What makes them different is how they are interpreted by the output device, lie a terminal program (e.g. linux terminal, putty, etc.) or the windows command prompt.
If you are printing this string to a destination that does not interpret these characters correctly, you may not see proper formatting even if the string data is correct. For example some IDE's output windows do not correctly format certain control characters, so you'll see different formatting in your IDE than you would see in an actual terminal.
One possible reason could be that it is not sent properly from the source system. I would look there to see what can be done next. Most languages offer cross-platform EOL constant's which might come in handy. For instance, Ruby has four:
irb(main):002:0> require 'English'; test = "One"+ $INPUT_RECORD_SEPARATOR
=> "One\n"
irb(main):003:0> test1 = "One" + $/
=> "One\n"
irb(main):004:0> test2 = "One"+$-0
=> "One\n"
irb(main):005:0> require 'English';test3="One"+$RS
=> "One\n"
irb(main):006:0>
You can try this:
String text = ((TextMessage)message).getText();
if(text!=null)
text=text.replaceAll("\r\n","");
Related
I have a requirement to send the sms and email on the trigger of some event.
It's working fine when I am testing with english. But when I change the text to Japanese, it's producing some sort of junk message. I am using java as my programming language.
I have tried some solutions like changing the charset preference and adding -Dfile.encoding=UTF8 in run configurations, but doesn't seem to work.
It's not working in a particular case.
When I hard-code the string in my java class as Japanese string then it's working fine. But when I try to read from property file it's producing some junk characters.
Finally I have solved this. As I have stated in my question itself, that the problem is mainly with reading from .property file. When I tried to hardcode the string it's working perfectly.
As #Henry suggested in his comments, all the .property files contain only ISO8859-1 characters. So, I followed the process to convert string from ISO8859-1 format to UTF.
It can be achieved by simply using this one line of code.
String utf8String = new String(Charsets.ISO_8859_1.encode("your string").array()).
Although, It solved my purpose, But I thought it's not a clean way to solve this.
For my scenario I had to add a new configuration, so instead of going through above way. I kept the string in separate text file and read from the file.
String filePath = "filename.txt"
try {
BufferedReader br = new BufferedReader(new FileReader(filePath));
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
sb.append("\n");
line = br.readLine();
}
return sb.toString();
} catch (FileNotFoundException e) {
log.error("file not found ", e);
} catch (IOException e) {
log.error("Error occurred ", e);
}
It solved the issue without using any hack to convert from one CharSet to another.
I have a command in array format that I can pass to execve(). For example, the command is:
echo "It's Nice"
and the array I have is ["echo","It's Nice"]. I'm trying to convert this array into a string that I can write in bash and execute properly. I obviously cannot join on this array with space delimiter because I will get: echo It's Nice which cannot be run since it has an unterminated single quote.
Is there a BKM to convert this to a runnable string? maybe a library that does that already in Java? It can get tricky when the command has many special characters that should be escaped\quoted in order to run properly.
EDIT:
I would like to make my question clearer. The user gives me his command as a string array, I execute it and everything works fine. Now I need to report to the user what I have ran. I do not want to show the command as an array, instead I would like to show it as a string that the user can simply copy and paste to his bash shell and execute it if he wants to. So my input is [echo, It's Nice] and my output should be echo "It's Nice". It seems like a simple function to write, but i'm not sure i'm thinking of all the end-cases here (like if the string has a quote or some other special character the shell manipulates). I was wondering maybe there's some code that already does that and covers the end cases i'm yet to think about.
You don't need to convert array to string, you can directly execute a command using ProcessBuilder:
String runShell(final String[] commandArgs) {
try {
final ProcessBuilder processBuilder = new ProcessBuilder(commandArgs);
processBuilder.redirectErrorStream(true); // merge stderr with stdout
Process process = processBuilder.start();
ret = process.waitFor();
BufferedReader br = new BufferedReader(new InputStreamReader(
process.getInputStream() ));
br.lines().forEach(System.out::println); // print stdout + stderr
process.destroy();
br.close();
}
catch (IOException|InterruptedException e) {
e.printStackTrace();
}
return commandArgs[0] + Arrays.asList(commandArgs).stream()
.skip(1)
.collect(Collectors.joining("\" \"", " \"", "\""));
}
and call it as:
runShell(new String[] {"pwd"}); // print current working directory
runShell(new String[] {"ls", "-l"}); // list all the files and directories
runShell(new String[] {"echo", "It's Nice"}); // echo something
That's easy to do in Java 8:
String joined = String.join(" ", iteratable);
The code below reads from a file 'helpFile.txt' and checks for an index represented by '#'.
The variable read from the file is stored in the integer c and compared with '#' if the read character is '#' without casting the integer into character. I want to know if the comparison is valid as the compiler is not showing any error.
Also, suppose '#' is found by the program in the file and a string called 'topic' immediately follows '#' and it is read using readLine(). Will the 'String info = br.readLine()' be just 'topic' or '#'+'topic'?
Sorry for such a lengthy question. Help much appreciated.
boolean helpOn(String what){
private BufferedReader br;
private String info, topic;
private static PrintWriter pw = new PrintWriter(System.out, true);
int c;
br = new BufferedReader(new FileReader("helpFile.txt"));
try{
do{
//read characters until '#' is found
c = br.read();
if(***c=='#'***){ //check if the character is '#'
pw.println(c);
if((**topic=br.readLine()**).equalsIgnoreCase(what)){ //check if 'what' string is equal to 's' which is the string after '#'
while((info=br.readLine())!=null){ //print info until the end of info
if(info!=null)
pw.println(info);
}
return true;
}
}
}
while(c!=-1);
}
catch(IOException ex){
pw.println("File error.");
ex.printStackTrace();
try{
br.close();
}
catch(IOException e){
pw.println("Error closing file.");
e.printStackTrace();
}
return false;
}
try{
br.close();
}
catch(IOException ex){
pw.println("Error closing file.");
ex.printStackTrace();
}
return false; //topic not found
}
I tried your code, it is woking fine with me, i think u need to check your "helpFile.txt". i used this in it.
adad#hello
howareyou
and this is the outout i am getting.
c: 35
topic: hello
info: howareyou
i printed all the three vars u used. c, topic, info.
Now since you are using readline() after reading a character, u must give your "info" from next line in "helpFile.txt"
info will contain anything after topic, as you are using readline() function, it will go to the next line. try with my example.
As soon as "#" is encountered, your var
C will have "#" (35).
then
topic will have anything after the "#" till the end of line, because of readline();
then
info will have the next line after topic.
If you format your helpFile.txt properly, this will work fine
EDIT
i have to specify the full file name everytime
You are using eclipse, and you are saving the file in the "SRC" folder i guess. Save them in your Project folder. just one above the SRC folder and then do this.
br = new BufferedReader(new FileReader("helpFile.txt"));
it should work.
EDIT2
you don't need to check info for null twice
while((info=br.readLine())!=null){
//print info until the end of
// if(info!=null) noT needed, u alreay did that above
pw.println("info"+info);
}
If it is NULL, it will automatically come out of loop.
EDIT3
i don't want to print all the texts
As you used # to mark the begining of the block, you could use anything to mark the end of it. eg
helpFile.txt
adad#hello
howareyou
$
Other text here
blah blah blah...
...
Now, you can modify your while as:
while(!(info=br.readLine()).equals("$")){
pw.println("info"+info);
}
The loop will exit as soon as it gets "$", and it won't print anything after that.
You may wanna read the javadoc for the class you are using (BufferedReader), it can be found here, but i think it's ok to compare the characters with == because a char is really a numeric type. But i suggest you read more about enconding, because i think FileReader will use the default plataform encoding to read your file and that may not be your file encoding. It's always good practice to inform the encoding of the file.
About the second question, acoording to javadoc (again), it will read the entire line (not from the point you read the char). Hope that helps, i'm goona try to run this later to see the results
I am trying to decode an outlook .MSG file to a text file, using Apache POI classes.
Everything works fine, except for the println method of PrintWriter: it doesn´t create a new line.
It just concatenates every sentence directly one after another. The result of the code snippet below is
"De: textPara: " iso
"De: "
"Para: "
I tried the code on several machines: it works on my local tomcat instalation (Windows machine), but fails on a tomcat or Weblogic instalation on a Solaris platform. I thought it had something to do with the encoding algorithm, so I used PrintStream in stead of Printwriter, indicating the encoding ISO-8859-1, but no luck neither.
Any idea?
try {
byte [] msgByte = Base64.decodeBase64(msgBase64);
InputStream inputMsg = new ByteArrayInputStream(msgByte);
msg = new MAPIMessage(inputMsg);
/* 1. Transform MSG to TXT. */
try {
txtOut = new PrintWriter(outputMsg);
try {
String displayFrom = msg.getDisplayFrom();
txtOut.println("De: "+displayFrom);
} catch (ChunkNotFoundException e) {
_logger.info("Error extrayendo displayFrom: "+e);
}
try {
String displayTo = msg.getDisplayTo();
txtOut.println("Para: "+displayTo);
} catch (ChunkNotFoundException e) {
_logger.info("Error extrayendo displayTo: "+e);
}
} finally {
if(txtOut != null) {
txtOut.close();}
else {
_logger.error("No se ha podido parsear el mensaje.");
}
}
Change the following:
txtOut.print("De: "+displayFrom + "\r\n");
txtOut.print("Para: "+displayTo + "\r\n");
This is related to how PrintWriter.println() generates the Line break depending of the Operating System. For unix systems is LF (\n), for Windows is CR+LF (\r\n).
Notice how I added the "\r\n" which means CR+LF and used print() instead of println(). This way the line break generated is not platform dependent.
You can also add the following method to your class to avoid duplicity and just call this custom println() instead of directly calling txtOut.print().
private static final String LINE_SEPARATOR = "\r\n";
public void println(String str) {
txtOut.print(str + LINE_SEPARATOR);
}
This way you just call println() method.
If I run this simple program on Windows 7 and then on AIX (Unix system) and compare the two generated files using a tool such as Winmerge or Compare It, it tells me that the Carriage Return and Line Feed are different but the content identical.
Why is that? Isn't supposed to be the same if both use the same encoding "UTF-8" in this case?
How can I make both files totally equal?
public class WriteFile {
public static void main(String[] args) throws IOException {
write();
}
public static void write() throws IOException {
File file = new File("/tmp/test.txt");
file.delete();
file.createNewFile();
String str = "hello";
FileOutputStream fileOs = new FileOutputStream(file);
PrintWriter writer = new PrintWriter(new OutputStreamWriter(fileOs, "UTF-8"), true);
writer.println(str);
writer.close();
}
}
Different operating systems use different newline conventions:
On Windows, newlines are CR+LF;
On Unix, newlines are LF.
(If you're curious, there's more.).
If you need the output files to be identical, don't use println(), but write \n or \r\n instead:
writer.printf("%s\n", str); // LF
writer.printf("%s\r\n", str); // CR+LF
Use
writer.print(str + "\n");
instead of
writer.println(str);
Like it's been said, you should switch from using println(String) to print(String) or printf(String, ...)
Check out the documentation for println(String) (emphasis mine):
Prints a String and then terminates the line. This method behaves as
though it invokes print(String) and then println().
And the docs for println():
Terminates the current line by writing the line separator string. The
line separator string is defined by the system property
line.separator, and is not necessarily a single newline character
('\n').
You can read about the line.separator system property here.
I would go with aix's suggestion of using
writer.printf("%s\n", str);