0

In going through some socket connection code of mine, I noticed this method:

public void write(String line) throws IOException, NullPointerException {
    log.fine(line);
    byte[] bytes = line.getBytes();
    outputStream.write(bytes);   // append 13 and 10 here before the write
    outputStream.write(13);
    outputStream.write(10);
    outputStream.flush();

}

and it occurs that I may be introducing some latency, perhaps, by writing the line and then appending CR and LF before flushing.

Would it be more efficient to append the CR and LF to the byte array, making for only a single call to outputStream.write() instead of three calls?

The context is a socket connection based MUD client. (No, SSH isn't an option, MUD games use telnet.)

Because it's not an ArrayList or something easy to work with, I'm not sure how big the array is, so I don't know the index to the last element. Iterate the Array into a new array, and then append CR and LF to the next elements? That seems weird. I'm not sure how to avoid a NullPointerException when adding to the end of the array.

Thufir
  • 7,241
  • 18
  • 103
  • 236
  • where are you initializing outputStream? – M Sach Dec 15 '13 at 10:47
  • its a live telnet connection, it's here: https://github.com/THUFIR/MudSocketClient/tree/master/src/mudsocketclient – Thufir Dec 15 '13 at 10:48
  • Maybe. I'm guessing that there's not much in it. Still, I usually try to assemble a complete line of output before calling something that may trigger an I/O system call. – Martin James Dec 15 '13 at 10:48
  • 1
    Where is the stack trace of the exception? What line does it refer to? – JB Nizet Dec 15 '13 at 10:48
  • There's no exception, I'm just asking how to do it. How to append CR and LF more efficiently. – Thufir Dec 15 '13 at 10:49
  • Doing as you did is fine. Why would you get a NPE when appending to an array? – JB Nizet Dec 15 '13 at 10:51
  • because I don't know the size of the array, and might be writing to element 9, when the size of the array is 7. Or something like that. – Thufir Dec 15 '13 at 10:52
  • 1
    The size of the array is bytes.length. So you just need to create an array of size length + 2, copy the array to the copy, and initialize the last 2 bytes to \r and \n. Accessing an invalid index in an array wouldn't throw a NPE. It would throw an ArrayIndexOutOfBoundsException. – JB Nizet Dec 15 '13 at 11:06
  • right you are, I had the wrong error in mind. – Thufir Dec 15 '13 at 12:42

1 Answers1

1

If your outputStream object is at one level a BufferedOutputStream, then you are good. Nothing to worry about. However, even if you don't have a BufferedOutputStream, socket streams are always buffered, I think.

To answer your question, you could do something like this:

byte[] msg = line.getBytes(Charset.forName("UTF-8"));
byte[] output = new byte[msg.length + 2];
System.arraycopy(msg, 0, output, 0, msg.length);
output[msg.length] = (byte) 13;
output[msg.length] = (byte) 10;
outputStream.write(output);

Or even better would be:

byte[] msg = line.concat("\r\n").getBytes(Charset.forName("UTF-8"));
outputStream.write(msg);
Martijn Courteaux
  • 63,780
  • 43
  • 187
  • 279
  • ok, that's interesting. It's not a BufferedOutputStream, but I'll look into that. – Thufir Dec 15 '13 at 10:50
  • that looks good, I knew about, but had never used arraycopy, so it didn't occur to me. thanks, let me try that. – Thufir Dec 15 '13 at 10:53
  • Can someone else confirm the fact that Socket streams are buffered on a lower level? – Martijn Courteaux Dec 15 '13 at 11:10
  • I don't think so, because you have to go through extra steps to get a Buffered stream. From a Socket, you can only directly get an OutputStream, which you can **then** buffer. Maybe a case that OutputStream **should** be buffered by default. Java is fully of those sorts of legacy API hassles, IMHO. Thanks for the nice way to copy arrays, again. – Thufir Dec 15 '13 at 12:40
  • The fact that a socket has an outputstream does not mean it is not buffered. OutputStream is only an abstract class. It can have whatever buffer implementation you can think of. – Martijn Courteaux Dec 15 '13 at 13:41
  • http://stackoverflow.com/questions/11373259/sockets-bufferedoutputstream-or-just-outputstream – Martijn Courteaux Dec 15 '13 at 13:43