Buffered Writer - Writing strings with "\n" inside - java

I was wondering if it's possible to send a single string with newline characters using BufferedWriter.
For context I need to send the following string over the network:
String message = "LOOKREPLY\nX...X\n.....\n.....\n.....\nX...X"
socketOutput = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
socketOutput.write(message + "\n");
But this sends 6 messages over the network because of the newline characters. I could re-build it on the client side but was wondering if there's a neater/simpler approach.

In your code
bw.write(message+"\n");
As it will put \n after all message has been written.
BufferedWriter will not send 6 Messages it will send only one but as you gave \n in your string it will write according to that.
As delv said you can put escape sequence to the \n so that it will write only one line.
String message = "LOOKREPLY\\nX...X\\n.....\\n.....\\n.....\\nX...X";
So that message will be written like this.
LOOKREPLY\nX...X\n.....\n.....\n.....\nX...X

Related

write the command to send a message to one or more receivers in a java client server chat application

I've tried to write a java client server application for chatting between clients privately. I am searching for a way to write the command to send a message to one or more receivers, I thought of handling it with a command like:
/send UserName UserName msg
but I pretty soon discovered that the character in between usernames and the message couldn't be repeated in the message because then it wouldn't know what is the message and what are the recipients, using a prearranged character also seemed to have some implications, like the inability to use that character in usernames or the message.
What would be a good way to handle such a thing?
You can determinate what is message and what are usersNames by splitting on last and first occurrence of delimiter in your case empty string. Lets say user input is inputStr
int firstOccurance = inputStr.indexOf(" ");
int lastOccueance = inputStr.lastIndexOf(" ");
And split it like this
String command = inputStr.substring(0,firstOccurance); // /send
String users = inputStr.substring(firstOccurance+1,lastOccurance); //UserName UserName
String msg = inputStr.substring(lastOccurance+1); //msg
Using space as delimiter will lead to a issue that message itself cannot include a space.
Instead you can use special delimiter to indicate a particular substring is a message.
Some very common delimiters are | ;

Apache Commons Net - System.getProperty("line.separator") - does not work in Android

I use the Apache Commons API to append a new line to a file using the FTPClient class. When I run the following code in Java, a new line is appended to the file on the FTP server. However, when I run the same code in Android, the String is appended to the file without a new line.
Why is the new line using - System.getProperty("line.separator") - not transferred via FTP under Android?
Also, the new line is correctly displayed in the LogCat but does not work in the txt file on the FTP server. Maybe there is a difference in character encoding between Java and Android?
Thank you very much.
String log = System.getProperty("line.separator") + "blablabla";
boolean done = ftpClient.appendFile("log.txt", new ByteArrayInputStream(log.getBytes("UTF-8")));
System.out.println("LOG: " + log);
As the file is on the server, I wouldn't think you'd want the client's value of System.getProperty("line.separator"); You want to know what the line separator on the server is, especially as you're working (apparently) in binary mode and so the FTP middle layer can't do line-ending conversions for you. (Which was once — possibly still is — quite a common thing for FTP clients and servers to do; it was called "ASCII" mode. [Ah, those halcyon days, when we thought we could assume text would be in ASCII, despite knowing, deep down, that that just wasn't sustainable... Like two-digit years...])
You could either query that information from the server, or choose to always use a particular line separator in your server-side log file. If the latter, \n would be a good choice if you're using a *nix-based server. If you're always on the Microsoft stack on the server, then \r\n would probably be a better choice.
Windows uses \r\n as its line separator, unlike UNIX which uses just \n
So,try to use
String log = "\n" + "blablabla";
or
String log = "\r\n" + "blablabla";
instead of
String log = System.getProperty("line.separator") + "blablabla";

Java > PHP Socket - trash at start of message

I have a java server communicating with a PHP script called from apache. I am aiming to send a JSON from the java server to the php client when requested, however there is some stuff getting prefixed when its received on the client.
JAVA
in = new BufferedReader(new InputStreamReader (socket.getInputStream()));
out= new DataOutputStream(socket.getOutputStream());
//The server receives a JSON from the PHP script and replies. It recives and converts to a Gson JSON no problem.
String reply = "{\"status\":\"reg\",\"token\":\""+client.getToken()+"\"}\r\n";
//reply = "HELLO\r";
out.writeUTF(reply);
PHP
$rec = socket_read($socket, 2048,PHP_NORMAL_READ);
echo "Receiving... ";
echo $rec;
The issue is that the message received is pre-fixed with some crap.
Output From PHP
Receiving... 1{"status":"reg","token":"QOPIPCNDI4K97QP0NAQF"}
If I send "HELLO\r"
Receiving... >HELLO
You shouldn't use DataOutputStream.writeUTF() unless you are using DataOutputStream.readUTF() to read the message.
Here is a snippet of the javadoc of writeUTF():
Writes a string to the underlying output stream using modified UTF-8
encoding in a machine-independent manner.
First, two bytes are written to the output stream as if by the
writeShort method giving the number of bytes to follow. This value is
the number of bytes actually written out, not the length of the
string. Following the length, each character of the string is output,
in sequence, using the modified UTF-8 encoding for the character. If
no exception is thrown, the counter written is incremented by the
total number of bytes written to the output stream. This will be at
least two plus the length of str, and at most two plus thrice the
length of str.
The bolded part above may tell you why you are getting weird characters at the beginning of your message.
Here is a workaround I believe will work in your case
BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());
out.write(os.getBytes("UTF-8"));
Reference: Why does DataOutputStream.writeUTF() add additional 2 bytes at the beginning?

PDF generation issue in java code

I am getting a PDF attachment in a Soap response message. I need to generate a PDF back out of it. However, the generated PDF is of the following form:
%PDF-1.4
%
2 0 obj
<</Type/XObject/ColorSpace/DeviceRGB/Subtype/Image/BitsPerComponent 8/Width
278/Length 7735/Height 62/Filter/DCTDecode>>stream
How can I solve this issue?
Here is the code showing how I am embedding a PDF as an attachment:
message = messageFactory.createMessage();
SOAPBody body = message.getSOAPBody();
header.detachNode();
AttachmentPart attachment1 = message.createAttachmentPart();
fr = new FileReader(new File(pathName));
br = new BufferedReader(fr);
String stringContent = "";
line = br.readLine();
while (line != null) {
stringContent = stringContent.concat(line);
stringContent = stringContent.concat("\n");
line = br.readLine();
}
fr.close();
br.close();
attachment1.setMimeHeader("Content-Type", "application/pdf");
attachment1.setContent(stringContent, "application/pdf");
The below code describes how I am getting PDF back from the SOAP message:
Object content = attachment1.getContent();
writePdf(content);
private void writePdf(Object content) throws IOException, PrintException,
DocumentException {
String str = content.toString();
//byte[] b = Base64.decode(str);
//byteArrayToFile(b);
OutputStream file = new FileOutputStream(new File
(AppConfig.getInstance().getConfigValue("webapp.root") +
File.separator + "temp" + File.separator + "hede.pdf"));
//String s2 = new String(bytes, "UTF-8");
//System.out.println("S2::::::::::"+s2);
Document document = new Document();
PdfWriter.getInstance(document, file);
document.open();
document.add(new Paragraph(str));
document.close();
file.close();
}
Can anyone help me out?
There are several faults in the supplied code:
In the code showing how you are embedding pdf as an attachment, you are using a Reader (a FileReader enveloped in a BufferedReader) to read the file to attach line by line, concat these lines with using \n as separator, and send the result of the concatenation as attachment content of type "application/pdf".
This is a procedure you may consider for text files (even though it isn't a good choice there either) but binary files read like this most like get broken beyond repair (and PDFs are binary files, in spite of a phase early in their history where handling them as text was quite harmless):
When reading a file, a Reader interprets the bytes in it according to some character encoding (as none is given explicitly here, most likely the platform default encoding is used) to transform them to Unicode characters collected in a String. Already here most likely the binary data is damaged.
When using readLine you read these Unicode characters until the Reader recognizes a line break. A line is considered to be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or a carriage return followed immediately by a linefeed. (Java API sources JavaDocs). When you continue to concatenate these lines uniformly using \n as separators, you essentially replace all single carriage return characters and all carriage return - line feed character pairs into single line feed characters, damaging the binary data even further.
When you make the attachment API you use encode this string as the content of some attachment part, you make it transform your Unicode characters back into bytes. If by chance the same character encoding is assumed as was by the Reader before, this might heal some of the damage done back then, but surely not all, and the line break interpretation of the step inbetween certainly isn't healed, either. If a different encoding is used, the data is damaged once again.
Thus, check what other arguments your AttachmentPart.setContent methods accept, choose something which does not damage binaries (e.g. InputStreams, ByteBuffers, byte[], ...) and use that, e.g. a FileInputStream.
The code which describes how you are getting PDF back from SOAP message is even weirder... You assume that toString of the attachment content returns some meaningful string representation (very unlikely here), and then continue to create a new PDF containing that string representation as text content of the first and only paragraph of the PDF. Thus while your attachment creation code discussed above at least 'merely' damaged the PDF, your attachment restrieval code completely ignores the nature of the attachment and destroys it beyond recognition.
You should instead check the actual type of the content object, retrieve the binary data it holds according to its type, and store that content using a FileOutputStream (not a Writer, and not using Strings inbetween, and not copying 'line' by 'line').
And whatever source gave you the impression that your code was appropriate for the task... well, either you completely misunderstood it or you should shun it from now on.

PrintWriter println(String s) method: \r\n not supported?

I'm creating a multithread chat client server application.
In the server connection I use PrintWriter println(String s) method to write the response to the client.
PrintWriter out;
String msg = in.readLine();
String response = "";
if (msg.startsWith("nick: ") {
response = protocol.authenticate(msg); //returns a String that says "welcome " + nick
//if there are messages pending for the author who logged in add them to the response String
response+="\r\n"+textmsg;
} else { ... }
out.println(response);
When I run the client, who uses the BufferedReader readLine() method to read from the server, I get the welcome message but not the pending message for the client, but If I use
response+=textmsg;
it works, so I assume it's because I'm using \r\n but I still need to print a new line between those two messages. What should I do?
Edit after accepting the answer: In the end I chose to use OutputStream and InputStream so I can send every kind of string I want, even with \r\n.
Either call println once for each line of output (so twice) or use only \n, without the \r. That's Java's standard newline char and \r\n is a Windows-specific end-of-line sequence. Of course, at the client end you now have to call readLine twice as well. There is no way to call readLine once and get two lines. If you need a custom delimiter, then you must use something else, not \n.
Use println with PrintWriter, for the \n.

Categories