Issue in writing data into a file using Servlet - java

I'm trying to read an XML file and send to the local server using HttpPost. When reading the data at the server side and writing into a file always last few lines are missing.
Client code :
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://xxx.xxx.xxx.xxx:yyyy/FirstServlet/HelloWorldServlet");
InputStreamEntity reqEntity = new InputStreamEntity(
new FileInputStream(dataFile), -1);
reqEntity.setContentType("binary/octet-stream");
// Send in multiple parts if needed
reqEntity.setChunked(true);
httppost.setEntity(reqEntity);
HttpResponse response = httpclient.execute(httppost);
int respcode = response.getStatusLine().getStatusCode();
Server code :
response.setContentType("binary/octet-stream");
InputStream is = request.getInputStream();
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("C:\\Files\\copyFile.xml")));
byte[] buf = new byte[4096];
for (int nChunk = is.read(buf); nChunk!=-1; nChunk = is.read(buf))
{
bos.write(buf, 0, nChunk);
}
I tried using BufferedReader as well, but same issue.
BufferedReader in = new BufferedReader(
new InputStreamReader(request.getInputStream()));
response.setContentType("binary/octet-stream");
String line = null;
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("C:\\Files\\copyFile.xml")));
while((line = in.readLine()) != null) {
line = in.readLine();
bos.write((line + "\n").getBytes());
}
I tried using scanner as well. In this case it's working fine only when I use StringBuilder and passing the value again to the BufferedOutputStream.
response.setContentType("binary/octet-stream");
StringBuilder stringBuilder = new StringBuilder(2000);
Scanner scanner = new Scanner(request.getInputStream());
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("C:\\Files\\copyFile.xml")));
while (scanner.hasNextLine()) {
stringBuilder.append(scanner.nextLine() + "\n");
}
String tempStr = stringBuilder.toString();
bos.write(tempStr.getBytes());
I can't use the above logic for processing very large XML's since converting to string value will throw Java heap space error.
Kindly let me know what is the issue with the code?
Thanks in advance!

flush() and close() your output streams. what happens is that youre not flushing and the last few lines remain in some internal buffer and are not written out.
so in your server code:
response.setContentType("binary/octet-stream");
InputStream is = request.getInputStream();
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("C:\\Files\\copyFile.xml")));
byte[] buf = new byte[4096];
for (int nChunk = is.read(buf); nChunk!=-1; nChunk = is.read(buf)) {
bos.write(buf, 0, nChunk);
}
bos.flush();
bos.close();

Related

How to read InputStream twice if I am using ReadableByteChannel and BufferedReader?

How to read an InputStream twice if I am using ReadableByteChannel and BufferedReader?
Here is my code:
ReadableByteChannel inputChannel = Channels.newChannel(input);
WritableByteChannel outputChannel = Channels.newChannel(output);
InputStream ind = Channels.newInputStream(inputChannel);
ReadableByteChannel inputChannel1 = Channels.newChannel(ind);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
org.apache.commons.io.IOUtils.copy(ind, baos);
ByteBuffer buffer = ByteBuffer.allocateDirect(10240);
long size = 0;
while (inputChannel1.read(buffer) != -1) {
buffer.flip();
size += outputChannel.write(buffer);
buffer.clear();
}
byte[] bytes = baos.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
BufferedReader in = new BufferedReader(new InputStreamReader(bais));
String inputLine;
StringBuffer bufferResponse = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
bufferResponse.append(inputLine);
}
JSONObject jsonResponse = new JSONObject(bufferResponse.toString());
You've written a lot of code to copy input to two destinations: output and jsonResponse. As you have made an in-memory copy of input => bytes there is no need to scan input twice, and you don't need to use IOUtils for a simple copy to byte[] which you can re-use to send to the two destinations:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
input.transferTo(baos);
byte[] bytes = baos.toByteArray();
output.write(bytes);
Then do as #g00se suggests - if the char encoding is platform default:
String s = new String(bytes /*, or insert another charset here */);
JSONObject jsonResponse = new JSONObject(s);
You should also deal with closing the input/output streams, best done with try-with-resources block.

How to send either String or File through android socket?

I just realized that DataInputStream and DataOutputStream in writing reading socket
could be used to differentiate the input that was coming over.
Check this code:
Server Side. (receiving string or file)
Socket bSock = serverSocket.accept();
DataInputStream inp = new DataInputStream(bSock.getInputStream());
int iCode = inp.readInt();
switch (iCode) {
case Request.STATE_FILESHARING:
byte bp[] = new byte[iCode];
FileOutputStream fos = new FileOutputStream("s.pdf");
BufferedOutputStream bos = new BufferedOutputStream(fos);
int bytesRead = inp.read(bp, 0, bp.length);
bos.write(bp, 0, bytesRead);
bos.close();
break;
case Request.STATE_CONVERSATION:
requestFound = new Request(inp.readUTF());
sendToUI(requestFound);
break;
}
Client Side. (sending string or file)
Socket socket = new Socket(myServerAddress, SocketServerPORT);
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
if (isThisFileMode()) {
File myFile = new File(sLocationFile);
byte[] mybytearray = new byte[(int) myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray, 0, mybytearray.length);
out.writeInt(Request.STATE_FILESHARING);
out.write(mybytearray, 0, mybytearray.length);
out.flush();
} else {
out.writeInt(Request.STATE_CONVERSATION);
out.write(obReq.toString().getBytes());
out.flush();
}
But I ended up with Error. System crashed!
Anything that I forgot to add?
You're using readUTF() but not writeUTF(). Nearly all the methods of DataInputStream and DataOutputStream are symmetrical: if you call readXXX() you must call writeXXX() at the other end.
You're making the usual mistake of assuming that read() fills the buffer. It is only contracted to transfer at least one byte. You must loop:
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
You need to close the socket at both server and client.

How do you read from an InputStream in Java and convert to byte array?

I am currently trying to read in data from a server response. I am using a Socket to connect to a server, creating a http GET request, then am using a Buffered Reader to read in data. Here is what the code looks like compacted:
Socket conn = new Socket(server, 80);
//Request made here
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String response;
while((response = inFromServer.readLine()) != null){
System.out.println(response);
}
I would like to read in the data, instead of as a String, as a byte array, and write it to a file. How is this possible? Any help is greatly appreciated, thank you.
You need to use a ByteArrayOutputStream, do something like the below code:
Socket conn = new Socket(server, 80);
//Request made here
InputStream is = conn.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int readBytes = -1;
while((readBytes = is.read(buffer)) > 1){
baos.write(buffer,0,readBytes);
}
byte[] responseArray = baos.toByteArray();
One way is to use Apache commons-io IOUtils
byte[] bytes = IOUtils.toByteArray(inputstream);
With plain java:
ByteArrayOutputStream output = new ByteArrayOutputStream();
try(InputStream stream = new FileInputStream("myFile")) {
byte[] buffer = new byte[2048];
int numRead;
while((numRead = stream.read(buffer)) != -1) {
output.write(buffer, 0, numRead);
}
} catch(IOException e) {
e.printStackTrace();
}
// and here your bytes
byte[] myDesiredBytes = output.toByteArray();
If you are not using Apache commons-io library in your project,I have pretty simple method to do the same without using it..
/*
* Read bytes from inputStream and writes to OutputStream,
* later converts OutputStream to byte array in Java.
*/
public static byte[] toByteArrayUsingJava(InputStream is)
throws IOException{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int reads = is.read();
while(reads != -1){
baos.write(reads);
reads = is.read();
}
return baos.toByteArray();
}

Read from http protocol and put into string array (Android/Java)

My code reads from http connection and puts the data into an ByteArrayOutputStream.
The http data content has the first row with the update date/time and then the other data.
Example of data received from http url:
2012-03-02 03:06:34
text1
text2
text3
I have found this:
InputStream content = response.getEntity().getContent();
byte[] buffer = new byte[1024];
int numRead = 0;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while((numRead=content.read(buffer))!=-1){
baos.write(buffer, 0, numRead);
}
content.close();
String result = new String(baos.toByteArray());
How can I use the first row ("2012-03-02 03:06:34") and then the others row?
I'll think to use an array of strings and get the first row with baos[0] and the others with
for (int i=1;i<baos.length;i++) {...}
How I can?
Thanks.
my english is very ugly :-o
What you have works more on a byte-at-a-time level.
Try this for a line at a time:
InputStream is = response.getEntity().getContent();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line;
while((line = br.readLine()) != null)
{
//Do something with each line
}

how to implement PHP file_get_contents() function in JSP(java)?

In PHP we can use file_get_contents() like this:
<?php
$data = file_get_contents('php://input');
echo file_put_contents("image.jpg", $data);
?>
How can I implement this in Java (JSP)?
Here's a function I created in Java a while back that returns a String of the file contents. Hope it helps.
There might be some issues with \n and \r but it should get you started at least.
// Converts a file to a string
private String fileToString(String filename) throws IOException
{
BufferedReader reader = new BufferedReader(new FileReader(filename));
StringBuilder builder = new StringBuilder();
String line;
// For every line in the file, append it to the string builder
while((line = reader.readLine()) != null)
{
builder.append(line);
}
reader.close();
return builder.toString();
}
This will read a file from an URL and write it to a local file. Just add try/catch and imports as needed.
byte buf[] = new byte[4096];
URL url = new URL("http://path.to.file");
BufferedInputStream bis = new BufferedInputStream(url.openStream());
FileOutputStream fos = new FileOutputStream(target_filename);
int bytesRead = 0;
while((bytesRead = bis.read(buf)) != -1) {
fos.write(buf, 0, bytesRead);
}
fos.flush();
fos.close();
bis.close();

Categories