DataOutputStream to Array - java

Is there any way to write DataOutputStream content to an Array or a String regardless which type of data it contains?
DataOutputStream output = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(String dataPath)));
Thanks

Use ByteArrrayOutputStream.
https://docs.oracle.com/javase/7/docs/api/java/io/ByteArrayOutputStream.html
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = new DataOutputStream(baos);
os.write(...);
byte[] data = baos.toByteArray();
String dataAsString = new String(data, "UTF-8"); // or whatever encoding you are using
You may use the following strategy as well:
class CompositeOutputStream implements OutputStream {
private OutputStream first,second;
public CompositeOutputStream(OutputStream first, OutputStream second) {
this.first = first;
this.second=second;
}
public void write(int b) throws IOException {
first.write(b);
second.write(b);
}
// etc.
}
Use with:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = new CompositeOutputStream(new DataOutputStream(...), baos);
os.write(...);
byte[] data = baos.toByteArray();
String dataAsString = new String(data, "UTF-8"); // or whatever encoding you are using
// etc.
The "baos" is only a "mirror" of what's got written to your original DataOutputStream
You still need to handle exceptions correctly, and be carefull about the amount of data written (holding everything in memory may lead to out of memory), etc.

Related

How to replace fileoutstream to stringwriter

I would like to persist a sort of object using ObjectOutputStream into stringwriter as a last outoput data. If this was not clear check out this piece of code bellow.
StringWriter sw = new StringWriter();
OutputStream out = null ; which object wrap sw here?
try (ObjectOutputStream obj = new ObjectOutputStream(out)){
} catch (IOException e) {
e.printStackTrace();
}
As you can see which class should I use to wrap an object of Stringwriter.
Here's a working snippet of code:
// Create a base 64 encoded string and print it
byte[] data = {-1,-2,-3,0,1,2,3,};
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream enc = new ObjectOutputStream( bos );
enc.writeObject( data );
enc.close();
String b64 = Base64.getEncoder().encodeToString( bos.toByteArray() );
System.out.println( "data=" + b64 );
Don't use a StringWriter, use a ByteArrayOutputStream. The Writer interface and the OutputStream interface are two different things and you can't mix them up.

Android: Trying to test sockets

I'm trying to test socket communication in Android Java, but can't seem to get a mock working.
First of all, using Mockito, mock(Socket.class) throws an Exception java.lang.VerifyError.
So I coded my mock like so:
public void testMyTest(){
final ByteArrayOutputStream os = new ByteArrayOutputStream();
final ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
try{
byte[] buffer = new byte[6];
os.write("poulet".getBytes());
is.read(buffer, 0, 6);
Log.w(LOG_TAG, "Read result:" + (new String(buffer, "UTF-8")));
} catch(IOException e){}
}
However is is not reading from os when I call os.write(). The raw result is [B#42204320 and, in string form, it looks like ������������. I tried commenting os.write() but nothing changed.
Does anyone know how to link an input stream to read form an output stream?
To test my classes I just called
final Socket mockedSocket1 = new Socket();
final Socket mockedSocket2 = new Socket();
when(mockedSocket1.getInputStream()).thenReturn(is);
when(mockedSocket2.getOutputStream()).thenReturn(os)
So that my classes get the linked output and input streams that I'm going to test with.
Thanks a lot!
The is's buffer will always be empty.
This: ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray()); just creates an ByteArrayInputStream with an empty buffer, that buffer won't change when you write something to the ByteArrayOutputStream.
public byte[] toByteArray()
Creates a newly allocated byte array. Its size is the current size of this output stream and the valid contents of the buffer have been copied into it.
...
What you can do is to create the ByteArrayInputStream after you write something to the ByteArrayOutputStream, eg:
try (ByteArrayOutputStream os = new ByteArrayOutputStream();){
byte[] buffer = new byte[6];
os.write("poulet".getBytes("UTF-8"));
try(ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());){
is.read(buffer, 0, 6);
System.out.println("Read result:|" + (new String(buffer, "UTF-8") + "|"));
}
} catch (IOException e) {
}

Java ObjectOutputStream Not Writing to ZipEntry

I am trying to serialize an object into a ZipEntry using an ObjectOutputStream, however it doesn't appear to be writing anything because when I print the byte array produced, it shows null. I tried writing a string with the ZipOutputStream, and upon printing the resulting byte array got a sizeable result. SO my question is: why is the objectoutput stream not correctly writing into the ZipEntry. (ConfigEntry does implement Serializable).
String s = "Tired, Exhausted";
ConfigEntry con = new ConfigEntry("rand", "random", 3);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
ZipOutputStream zos = new ZipOutputStream(baos);
ZipEntry entry = new ZipEntry("test.txt");
ObjectOutputStream obs = new ObjectOutputStream(zos);
zos.putNextEntry(entry);
obs.writeObject(con);
obs.close();
zos.closeEntry();
zos.close();
} catch(IOException ioe) {
ioe.printStackTrace();
}
os = bs.getOutputStream();
byte[] result = baos.toByteArray();
String test = new String(result, "UTF-8");
Log.v("Mac Address", test);
Log.v("Mac Address", Arrays.toString(result));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
This baos goes out of scope after the try block. You are writing to one baos and you are looking into another baos declared in an outer scope, probably an instance member of the class.

Not able to process big file inside a zip file using ZipInputStream

I am having a below mentioned java class which extracts a zip, and one by one convert its content to string and print to console.
Problem is, when the file present inside the zip is big ~80KB. Entire content is not getting displayed (only 3/4 of the data is getting converted to string and displayed in console).
Secondly below mentioned code is introducing null/space in between and also if the file size is small ~1KB
what is wrong in below mentioned code.
public static void main(String[] args) throws Exception {
byte[] buf = new byte[1024];
final int BUFFER = 1024;
String fName = "c:\\DOC00001.zip";
ZipInputStream zinstream = new ZipInputStream(
new FileInputStream(fName));
ZipEntry zentry = zinstream.getNextEntry();
while (zentry != null) {
byte data[] = new byte[BUFFER];
ByteArrayOutputStream out = new ByteArrayOutputStream();
while ((zinstream.read(data, 0, BUFFER)) != -1) {
out.write(data);
}
InputStream is = new ByteArrayInputStream(out.toByteArray());
StringWriter writer = new StringWriter();
IOUtils.copy(is, writer, "UTF-8");
String response = writer.toString();
System.out.println(response);
zentry = zinstream.getNextEntry();
}
zinstream.close();
}
The read method is not guaranteed to read a full buffer; the number of bytes that have been read is returned. The correct way to extract data from a zip file, or any InputStream in general, would be:
byte[] data = new byte[BUFFER];
ByteArrayOutputStream out = new ByteArrayOutputStream();
int bytesRead;
while ((bytesRead = zinstream.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, bytesRead);
}
Or, since you are already using IOUtils,
ByteArrayOutputStream out = new ByteArrayOutputStream();
IOUtils.copy(zinstream, out);
Or, given that you write to a ByteArrayOutputStream only to later write to a String, you can skip the ByteArrayOutputStream entirely:
while (zentry != null) {
StringWriter writer = new StringWriter();
IOUtils.copy(zinstream, writer, "UTF-8");
String response = writer.toString();
System.out.println(response);
zentry = zinstream.getNextEntry();
}

Java: read from binary file, send bytes over socket

This should be easy, but I can't get my head around it right now. I wanna send some bytes over a socket, like
Socket s = new Socket("localhost", TCP_SERVER_PORT);
DataInputStream is = new DataInputStream(new BufferedInputStream(s.getInputStream()));
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(s.getOutputStream()));
for (int j=0; j<40; j++) {
dos.writeByte(0);
}
That works, but now I dont want to writeByte to the Outputstream, but read from a binary file, then write it out. I know(?) I need a FileInputStream to read from, I just can't figure out hot to construct the whole thing.
Can someone help me out?
public void transfer(final File f, final String host, final int port) throws IOException {
final Socket socket = new Socket(host, port);
final BufferedOutputStream outStream = new BufferedOutputStream(socket.getOutputStream());
final BufferedInputStream inStream = new BufferedInputStream(new FileInputStream(f));
final byte[] buffer = new byte[4096];
for (int read = inStream.read(buffer); read >= 0; read = inStream.read(buffer))
outStream.write(buffer, 0, read);
inStream.close();
outStream.close();
}
This would be the naive approach without proper exception handling - in a real-world setting you'd have to make sure to close the streams if an error occurs.
You might want to check out the Channel classes as well as an alternative to streams. FileChannel instances, for example, provide the transferTo(...) method that may be a lot more efficient.
Socket s = new Socket("localhost", TCP_SERVER_PORT);
String fileName = "....";
create a FileInputStream using a fileName
FileInputStream fis = new FileInputStream(fileName);
create a FileInputStream File Object
FileInputStream fis = new FileInputStream(new File(fileName));
to read from the file
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(
s.getOutputStream()));
reading from it byte after byte
int element;
while((element = fis.read()) !=1)
{
dos.write(element);
}
or reading from it buffer wise
byte[] byteBuffer = new byte[1024]; // buffer
while(fis.read(byteBuffer)!= -1)
{
dos.write(byteBuffer);
}
dos.close();
fis.close();
read a byte from the input and write the same byte to the output
or with a byte buffer it like this:
inputStream fis=new fileInputStream(file);
byte[] buff = new byte[1024];
int read;
while((read=fis.read(buff))>=0){
dos.write(buff,0,read);
}
note that you don't need to use the DataStreams for this

Categories

Resources