How to get number of bytes? - java

How do I obtain the number of bytes before allocating the byte size of the array 'handsize' as shown below as the incoming ByteArray data are sent in 3 different sizes. Thanks.
BufferedInputStream bais = new
BufferedInputStream(requestSocket.getInputStream());
DataInputStream datainput = new DataInputStream(bais);
//need to read the number of bytes here before proceeding.
byte[] handsize = new byte[bytesize];
datainput.readFully(handsize);

You could use a ByteArrayOutputStream, then you wouldn't have to worry about it.
ByteArrayOutputStream out = new ByteArrayOutputStream();
//write data to output stream
byte[] bytes = out.toByteArray();

There's no way to know how many bytes of data are yet to be received on a socket--knowing this would be tantamount to clairvoyance. If you're using your own protocol for client/server communication, you could send the number of bytes of data as an integer, before sending the actual bytes themselves. Then the receiving side would know how many bytes to expect.

As has been pointed out, the problem as stated is impossible. But why do you need to know? Why not store the data in a variable size structure, like an ArrayList, as you read it? Or maybe even process it as you read?

Related

Creating a packet bytearray using a bytebuffer in Java

How can I make a packet that is in the form of a byte[] in Java? I know that it should be done with a ByteBuffer and then I need to make it a byte[] and send it through a DataOutputStream.
How can I make a packet that is in the form of a byte[] in Java? I know that it should be done with a ByteBuffer and then I need to make it a byte[] and send it through a DataOutputStream.
No, you don't know that. You either:
Use a ByteBuffer and send it through a Channel directly, without an intermediate byte[]
Use a DataOutputStream wrapped around a file or socket output stream, again without an intermediate byte[]
use a DataOutputStream wrapped around a ByteArrayOutputStream, get the byte[] array from that, and send the byte[] array. This technique is unnecessary unless what you're trying to construct is a DatagramPacket.

store fixed bytes into byte array from input stream

I'm trying to learn Java and I came across this practice problem in which I have to create a URL extractor. I am able to stream data and print it. However I'm not really familiar with the buffered reader therefore I need help with creating a buffer of 100 bytes, copying 100 bytes of data from the stream to this byte array, then process this part, then take the next chunk of 100 bytes from the stream and so on....
The following is my code and any help would greatly be appreciated.
I know that what i want needs to be done inside the while loop. I think I need to create a byte array and then store the data into it. It is the how I'm more interested in.
EDIT: I do not need the code sample for anything because I'm trying to learn. Only the description of how I can do this would suffice . Thanks a lot in advance.
Create a byte array (of the size you want) outside your while-loop (you can re-use it that way, so it's faster).
You can use a BufferedInputStream wrapped around your original InputStream instead of a Reader (as Readers can convert bytes to Strings, but we don't need that).
Then you can use the read(byte[]) method of BufferedInputStream to copy the next series of bytes into the array. You can then process the retrieved bytes the way you want.
See the API documentation as a reference of what read(byte[]) does.
As mentioned in the comments, a Reader (and its subclass BufferedReader) is used to read characters not bytes. You should instead use a BufferedInputStream to read into a byte array of the specified size:
public static void main(String[] args) throws IOException {
String website = "thecakestory.com";
Socket client = new Socket(InetAddress.getByName(website), 80);
PrintWriter pw = new PrintWriter(client.getOutputStream());
pw.println("GET /index.php / HTTP/1.1\r\n");
pw.println("Host: " + website);
pw.flush();
BufferedInputStream input = new BufferedInputStream(client.getInputStream());
String x;
int bytesRead;
byte[] contents = new byte[100];
while ((bytesRead = input.read(contents)) != -1) {
x = new String(contents, 0, bytesRead);
System.out.print(x);
}
client.close();
pw.close();
}
Some useful links:
For an introduction to Java IO related stuff, see the Java tutorial page http://docs.oracle.com/javase/tutorial/essential/io/. This should be the starting point for learning about streams, readers, etc.
For the documentation of BufferedInputStream and BufferedReader, see their API reference:
http://docs.oracle.com/javase/7/docs/api/java/io/BufferedInputStream.html
http://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html

AudioInputStream to an array

I need to get the values from the AudioInputStream and store it in a byte[]. Calling a read(byte[]) returns -1. If I'm able to read the values as integers, I can convert it to byte[]. How do I get around either of the problems ?
If the intention is to store the sound data in a byte[], the best approach is not to get an AudioInputStream at all. Instead, just use a plain InputStream.
The AudioInputStream typically strips the first bytes from an input stream (because they contain formatting data) and then only provides the frames or samples of that stream. Doing it using an InputStream on the other hand, you should be able to get all the bytes. Then once the entire data is in a byte array, an AudioInputStream can be formed from the byte array (if needed).
UPDATED
Use apache commons IOUtils to read the bytes from the wav file.
InputStream is = -> your FileInputStream
ByteArrayOutputStream os = new ByteArrayOutputStream();
IOUtils.copy(is, os);
os.flush();
os.close();
byte[] ba = os.toByteArray();
You cannot read it directly to a ByteArrayOutputStream or you´re gonna get
java.io.IOException: stream length not specified
at com.sun.media.sound.WaveFileWriter.write(Unknown Source)
at javax.sound.sampled.AudioSystem.write(Unknown Source)
It is hard to understand what exactly you want: byte array with data or byte array with WAV file inside. Byte array with only sound data is a very simple task: copy from AudioInputStream to ByteArrayOutputStream.
The second case is more complex. In this case you should read from AudioInputStream to ByteArrayOutputStream and then form WAVE header. I can provide you two examples. I hope they will help you.
How to record audio to byte array - it is example of recording audio to byte array with wave file inside.
How to detect sound - it shows how AudioInputStream can be processed.

Setting Size of Java Deflater (and Inflater) Output Byte Buffer

I need to deflate one or more byte arrays and later inflate them back to normal size. I've looked over the example given in the api docs, and found some other examples.
After looking these examples over, I have two questions which may be unrelated, but they seem connected as I'm trying to understand this.
In the API documentation example, the output buffer for both the Inflater and Deflater is set at 1024 bytes. The example data is only a short sentence, so that is reasonable. But how would I know how big to make the output buffer? Or will Deflater (and Inflater) adjust the size of the output buffer as needed?
Instead of guessing at the size of a buffer, can I use ByteArrayOutputStream and wrap a DeflatorOutputStream around that? Since ByteArrayOutputStream changes the size of the byte array, it wouldn't be necessary to know the size of the output or guess at it, as it seems one would have to do in the API example.
1.In the API documentation example, the output buffer for both the Inflater and Deflater is set at 1024 bytes. The example data is only a short sentence, so that is reasonable. But how would I know how big to make the output buffer? Or will Deflater (and Inflater) adjust the size of the output buffer as needed?
In streams, buffers are just temporary space before passing onto the another stream. Changing the buffers size can change performance but has little to do with the amount of data processed.
2.Instead of guessing at the size of a buffer, can I use ByteArrayOutputStream and wrap a DeflatorOutputStream around that? Since ByteArrayOutputStream changes the size of the byte array, it wouldn't be necessary to know the size of the output or guess at it, as it seems one would have to do in the API example.
You can do that, or you can send it directly to the stream you want the data to go to.
Here's an example of compressing and decompressing using byte arrays:
import java.util.zip.Deflater;
import java.util.zip.InflaterInputStream;
...
byte[] sourceData; // bytes to compress (reuse byte[] for compressed data)
String filename; // where to write
{
// compress the data
Deflater deflater = new Deflater(Deflater.DEFAULT_COMPRESSION);
deflater.setInput(sourceData);
deflater.finish();
int compressedSize = deflater.deflate(data, 0, sourceData.length, Deflater.FULL_FLUSH);
// write the data
OutputStream stream = new FileOutputStream(filename);
stream.write(data, 0, compressedSize);
stream.close();
}
{
byte[] uncompressedData = new byte[1024]; // where to store the data
// read the data
InputStream stream = new InflaterInputStream(new FileInputStream(filename));
// read data - note: may not read fully (or evenly), read from stream until len==0
int len, offset = 0;
while ((len = stream.read(uncompressedData , offset, uncompressedData .length-offset))>0) {
offset += len;
}
stream.close();
}

estimating size of file on disk when using ObjectOutputStream

I am trying to write my spatial data from a table to a file. But I need to know the exact size of the data on disk before writing to disk. As an example, let's say that I am writing to disk using the following code:
FileOutputStream fos = new FileOutputStream("t.tmp",false);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeInt(gid);
oos.writeUTF(fullname);
oos.writeInt(d.shape.length);
oos.write(d.shape);
oos.close();
fos.close();
I was thinking that file size on disk is equal to:
size= 4B {for gid, int} + fullname.getBytes.length() {string} + 4B {d.shape.length, int} + d.shape.length
but in fact, this is very different than the real file size on disk.
I also noticed that even creating an empty file using ObjectOutputstream leads to 4B space on disk.
Any help on how to calculate the file size on disk?
(I can't write the data to disk and then read the real size. This will lower the performance. Instead, I need to calculate the size of data on disk based on data values stored in memory.)
I am trying to write my spatial data from a table to a file. But I need to know the exact size of the data on disk before writing to disk.
You shouldn't use an ObjectOutputStream. An ObjectOutputStream can automatically serialise a complex graph of objects for you - but this doesn't appear to be one of your requirements. As part of this serialisation, the ObjectOutputStream writes some stream header information (this is the 4 bytes you discovered at the beginning), and also keeps track of objects written previously so that it can write special marker values rather than writing out the whole object again.
Instead, just use a DataOutputStream. It provides the same functionality you want:
A data output stream lets an application write primitive Java data types to an output stream in a portable way. An application can then use a data input stream to read the data back in.
FileOutputStream fos = new FileOutputStream("t.tmp",false);
DataOutputStream dos = new DataOutputStream(fos);
dos.writeInt(gid); // write 4 bytes
dos.writeUTF(fullname); // write 2 bytes of length, then variable length string (UTF encoded)
dos.writeInt(d.shape.length); // write 4 bytes
dos.write(d.shape); // write a variable length byte array
dos.close();
fos.close();
There won't be any surprises here (provided you know how many bytes your UTF encoded String will end up), and you can do the arithmetic to calculate what the exact file size will be.
(If you were dealing with strings that didn't just equate to one-character-one-byte, you could render the string to a byte array first using a charset encoder).
Assuming you don't mind wasting some memory, you can write it all out to a ByteArrayOutputStream first, then get the size.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(boas);
oos.writeInt(gid);
oos.writeUTF(fullname);
oos.writeInt(d.shape.length);
oos.write(d.shape);
oos.close();
boas.close();
int size = boas.size();

Categories