Both method write bytes to outputstream. To compare them first we should look at their source code:
On the one hand in OutputStream class we have these 3 nested method to writing bytes:
public void write(byte b[]) throws IOException {
write(b, 0, b.length);
}
public void write(byte b[], int off, int len) throws IOException {
Objects.checkFromIndexSize(off, len, b.length);
for (int i = 0 ; i < len ; i++) {
write(b[off + i]);
}
}
public abstract void write(int b) throws IOException;
All above method throws IOException.
On the other hand writesByte method of ByteArrayOutputStream calls this method:
public void writeBytes(byte b[]) {
write(b, 0, b.length);
}
public synchronized void write(byte b[], int off, int len) {
Objects.checkFromIndexSize(off, len, b.length);
ensureCapacity(count + len);
System.arraycopy(b, off, buf, count, len);
count += len;
}
These methods check byte array capacity before writing bytes, so they got rid of IOException. Also, the write method is trade safe because it is synchronized method.