I am geeting image in input stream and encoding it into base64 and sending it to client using JSON
Following is code snippet.
Server side :
JsonObject myObj = new JsonObject();
StringBuilder responseStrBuilder = new StringBuilder();
int ch =0; ;
sun.misc.BASE64Encoder encoder= new sun.misc.BASE64Encoder();
byte[] contents = new byte[5000000];
int bytesRead = 0;
String strFileContents;
while ((bytesRead = bin.read(contents)) != -1) {
responseStrBuilder.append(encoder.encode(contents).getBytes());
}
myObj.addProperty("1",responseStrBuilder.toString());
out.println(myObj.toString());
Client side ajax code :
success: function(result)
{
if(result)
{
$('#dynamicCamping01').html('<img src='+result[Object.keys(result)[0]]+'/>');
$('#dynamicCampingDesc01').html("<h3>"+allData[0]+"</h3>");
}
else
{
alert("Something went wrong while retriving events");
}
getting data at client side but image is not displaying.
This one worked :
BufferedInputStream bin = new BufferedInputStream(fin);
BufferedOutputStream bout = new BufferedOutputStream(out);
int ch =0; ;
sun.misc.BASE64Encoder encoder= new sun.misc.BASE64Encoder();
byte[] contents = new byte[5000000];
int bytesRead = 0;
String strFileContents;
while ((bytesRead = bin.read(contents)) != -1) {
bout.write(encoder.encode(contents).getBytes());
}
bout.close();
fin.close();
bin.close();
out.close();
and main important part is on client converting image into UTF-8 and Base64 decoding.
$(imageIDSData[i]).html('<img src="data:image/jpeg;charset=utf-8;base64,'+imageData[i]+'"/> ');
$(imageNameIDSData[i]).html("<h3>"+allData[i]+"</h3>");
Related
I have two projects; one for my server and one for my client, I am able to send images to the server with ease. But I am wondering how would you be able to download that image you just sent to the server back to the client when I press the download button I have created on my client GUI? My code is written in java.
Many Thanks
This is my serverhandler
String fileName;
fileName = "RecievedImageoutreach1.jpg";
DataOutputStream dout = new DataOutputStream(sock.getOutputStream());
//Coding for image transfer
int flag=0,i;
String extn="";
for(i=0; i<fileName.length(); i++)
{
if(fileName.charAt(i)=='.' || flag==1)
{
flag=1;
extn += fileName.charAt(i);
}
}
if(extn.equals(".jpg") || extn.equals(".gif"))
{
try{
File file = new File(fileName);
FileInputStream fin = new FileInputStream(file);
dout.writeUTF(fileName);
byte[] readData = new byte[1024];
while((i = fin.read(readData)) != -1)
{
dout.write(readData, 0, i);
}
//ta.appendText("\nImage Has Been Sent");
dout.flush();
fin.close();
}catch(IOException ex)
{System.out.println("Image ::"+ex);}
}
}
And this is my client
public void download() throws IOException {
// Get input from the server
DataInputStream dis = new DataInputStream (sock.getInputStream());
String str,extn = "";
str = dis.readUTF();
int flag=0,i;
for(i=0;i<str.length();i++)
{
if(str.charAt(i)=='.' || flag==1)
{
flag=1;
extn+=str.charAt(i);
}
}
//**********************reading image*********************************//
if(extn.equals(".jpg") || extn.equals(".gif"))
{
File file = new File("Downloaded"+str);
FileOutputStream fout = new FileOutputStream(file);
//receive and save image from client
byte[] readData = new byte[1024];
while((i = dis.read(readData)) != -1)
{
fout.write(readData, 0, i);
if(flag==1)
{
ta.append("Image Has Been Downloaded");
flag=0;
}
}
fout.flush();
fout.close();
}
}
But when run nothing occurs? i have linked the client method to run when a button is clicked.
I would do something like this:
//Server Handler
File file = new File(fileName);
FileInputStream fin = new FileInputStream(file);
// dout.writeUTF(fileName);
byte[] readData = new byte[1024];
fin.read(readData);
fin.close();
dout.write(readData, 0, readData.length);
dout.flush();
/* while((i = fin.read(readData)) != -1)
{
dout.write(readData, 0, i);
}*/
//ta.appendText("\nImage Has Been Sent");
dout.flush();
fin.close();
}catch(IOException ex)
{System.out.println("Image ::"+ex);}
}
//Receiving image
if(extn.equals(".jpg") || extn.equals(".gif"))
{
//give path to new file
File file = new File(".//Downloaded"+str);
FileOutputStream fout = new FileOutputStream(file);
//receive and save image from client
byte[] readData = new byte[1024];
int offset =0;
while((i = dis.read(readData,0,readData.length-offset)) != -1){
offset += i;
}
fout.write(readData, 0, readData.length);
if(flag==1)
{
ta.append("Image Has Been Downloaded");
flag=0;
}
fout.flush();
fout.close();
}
}
Assuming that you would have to provide file name and then press download button. So on server side convert the image into byte stream and write over the connection socket. On client side recieve bytes into buffer and then create FileOutputStream providing the directory for output. Write the recieved bytes onto the file using the outputstream created.
I sent a GET message with socket. And I received response message as string. But I want to receive as hexadecimal. But I didn't accomplish. This is my code block as string. Can you help me ?
dos = new DataOutputStream(socket.getOutputStream());
dis = new BufferedReader(new InputStreamReader(socket.getInputStream()));
dos.write(requestMessage.getBytes());
String data = "";
StringBuilder sb = new StringBuilder();
while ((data = dis.readLine()) != null) {
sb.append(data);
}
when you use BufferedReader you'll get the input into String format..so better way to use InputStream...
here is sample code to achieve this.
InputStream in = socket.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] read = new byte[1024];
int len;
while((len = in.read(read)) > -1) {
baos.write(read, 0, len);
}
// this is the final byte array which contains the data
// read from Socket
byte[] bytes = baos.toByteArray();
after getting the byte[] you can convert it to hex string using the following function
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02X ", b));
}
System.out.println(sb.toString());// here sb is hexadecimal string
reference from java-code-to-convert-byte-to-hexadecimal
I have an inputstream and I tried to process it but it gave me this error "not in gzip format" but the file is in gzip format "Content-Encoding: gzip"
protected String readResponse(InputStream is) throws IOException {
StringBuffer string;
int b;
byte[] buffer;
String eol, s = null;
GZIPInputStream gis;
int read;
int index;
eol = new String(new byte[] {(byte)0, (byte)0, (byte)-1, (byte)-1});
buffer = new byte[1];
string = new StringBuffer();
while ( (b = is.read()) > 0 ) {
buffer[0] = (byte)b;
s = new String(buffer);
string.append(s);
index = string.indexOf(eol);
if ( index > 0 && index == string.length() - 4 ) {
break;
}
}
System.out.println(string);
gis = new GZIPInputStream(is); << here I got the error
buffer = new byte[1024];
while ( (read = gis.read(buffer)) > 0 ) {
string.append(new String(buffer, 0, read));
}
return string.toString();
}
any thoughts?
thanks
Seeing this line:
eol = new String(new byte[] {(byte)0, (byte)0, (byte)-1, (byte)-1});
is enough to arrive to a conclusion: you are doomed from the start.
DO NOT USE STRING FOR BINARY DATA.
bytes and chars have no relationship to one another; what you are doing here is roughly equivalent to the following:
final CharsetDecoder decoder = Charset.defaultCharset()
.newDecoder().onMalformedInput(CodingErrorAction.REPLACE);
final ByteBuffer buf = ByteBuffer.wrap(new byte[]{...});
final CharBuffer cbuf = decoder.decode(buf);
final String eol = new String(cbuf.array());
Note the REPLACE action. Any unmappable byte sequence will trigger the decoder to output the Unicode replacement character, U+FFFD (looks familiar, right?).
Now try and put REPORT instead.
What is more, you use the default charset... Which differs from platform to platform.
Your code should really just read the input stream and return a byte array. use a ByteArrayOutputStream.
And if you want to write to a file directly, it's easy: use Files.copy().
Anyway, fixed that for you:
// Note: return code is byte[]
protected byte[] readResponse(final InputStream in)
throws IOException
{
try (
final InputStream gzin = new GzipInputSream(in);
final ByteArrayOutputStream out = new ByteArrayOutputStream();
) {
final byte[] buf = new byte[4096];
int bytesRead;
while ((bytesRead = gzin.read(buf)) != -1)
out.write(buf, 0, bytesRead);
return out.toByteArray();
}
}
The problem could be you're advancing the file pointer in the input stream before you pass it to GZIPInputStream. GZIPInputStream expects the first few bytes to be a standard header.
Try moving new GZIPInputStream(is); before your while loop
There is so many things wrong in your code..... But lets try anyway.
So you have ascii header and after that there shoulbe gzipped part? Gzip file always starts with id bytes. These have the fixed values 'ID1 = 31 (0x1f, \037), ID2 = 139 (0x8b, \213)'. Can you find those from your inputstream. There you should start the gzipstream.
I have tested this with a file composed from a few header lines, followed by an empty line, and an appended gzipped text file. The latter is written, unexpanded, to x.gz and unzipped and read from there, assuming that it is a text file. (If it is a binary file, a BufferedReader is pointless.)
try/with resources and catch should be added, but that's just a technicality.
InputStream is = ...;
StringBuilder lsb = new StringBuilder();
int c = -1;
while( (c = is.read()) != -1 ){
if( c == '\n' ){
String line = lsb.toString();
if( line.matches( "\\s*" ) ){
break;
}
System.out.println( line );
lsb.delete( 0, lsb.length() );
} else {
lsb.append( (char)c );
}
}
byte[] buffer = new byte[1024];
int nRead = 0;
OutputStream os = new FileOutputStream( "x.gz" );
while ( (nRead = is.read(buffer, 0, buffer.length )) > 0 ) {
os.write( buffer, 0, nRead );
}
os.close();
is.close();
InputStream gis = new GZIPInputStream( new FileInputStream( "x.gz" ) );
InputStreamReader isr = new InputStreamReader( gis );
BufferedReader br = new BufferedReader(isr);
String line;
while( (line = br.readLine()) != null ){
System.out.println("line: " + line );
}
br.close();
I have a task that
read a zip file from local into binary message
transfer binary message through EMS as String (done by java API)
receive transferred binary message as String (done by java API)
decompress the binary message and then print it out
The problem I am facing is DataFormatException while decompress the message.
I have no idea which part went wrong.
I use this to read file into binary message:
static String readFile_Stream(String fileName) throws IOException {
File file = new File(fileName);
byte[] fileData = new byte[(int) file.length()];
FileInputStream in = new FileInputStream(file);
in.read(fileData);
String content = "";
System.out.print("Sent message: ");
for(byte b : fileData)
{
System.out.print(getBits(b));
content += getBits(b);
}
in.close();
return content;
}
static String getBits(byte b)
{
String result = "";
for(int i = 0; i < 8; i++)
result = ((b & (1 << i)) == 0 ? "0" : "1") + result;
return result;
}
I use this to decompress message:
private static byte[] toByteArray(String input)
{
byte[] byteArray = new byte[input.length()/8];
for (int i=0;i<input.length()/8;i++)
{
String read_data = input.substring(i*8, i*8+8);
short a = Short.parseShort(read_data, 2);
byteArray[i] = (byte) a;
}
return byteArray;
}
public static byte[] unzipByteArray(byte[] file) throws IOException {
byte[] byReturn = null;
Inflater oInflate = new Inflater(false);
oInflate.setInput(file);
ByteArrayOutputStream oZipStream = new ByteArrayOutputStream();
try {
while (! oInflate.finished() ){
byte[] byRead = new byte[4 * 1024];
int iBytesRead = oInflate.inflate(byRead);
if (iBytesRead == byRead.length){
oZipStream.write(byRead);
}
else {
oZipStream.write(byRead, 0, iBytesRead);
}
}
byReturn = oZipStream.toByteArray();
}
catch (DataFormatException ex){
throw new IOException("Attempting to unzip file that is not zipped.");
}
finally {
oZipStream.close();
}
return byReturn;
}
The message I got is
java.io.IOException: Attempting to unzip file that is not zipped.
at com.sourcefreak.example.test.TibcoEMSQueueReceiver.unzipByteArray(TibcoEMSQueueReceiver.java:144)
at com.sourcefreak.example.test.TibcoEMSQueueReceiver.main(TibcoEMSQueueReceiver.java:54)
After check, the binary message does not corrupted after transmission.
Please help to figure out the problem.
Have you tried using InflaterInputStream? Based on my experience, using Inflater directly is rather tricky. You can use this to get started:
public static byte[] unzipByteArray(byte[] file) throws IOException {
InflaterInputStream iis = new InflaterInputStream(new ByteArrayInputStream(file));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[512];
int length = 0;
while ((length = iis.read(buffer, 0, buffer.length) != 0) {
baos.write(buffer, 0, length);
}
iis.close();
baos.close();
return baos.toByteArray();
}
I finally figure out the problem.
The problem is the original file is a .zip file, so I should use zipInputStream to unzip the file before further processing.
public static byte[] unzipByteArray(byte[] file) throws IOException {
// create a buffer to improve copy performance later.
byte[] buffer = new byte[2048];
byte[] content ;
// open the zip file stream
InputStream theFile = new ByteArrayInputStream(file);
ZipInputStream stream = new ZipInputStream(theFile);
ByteArrayOutputStream output = new ByteArrayOutputStream();
try
{
ZipEntry entry;
while((entry = stream.getNextEntry())!=null)
{
//String s = String.format("Entry: %s len %d added %TD", entry.getName(), entry.getSize(), new Date(entry.getTime()));
//System.out.println(s);
// Once we get the entry from the stream, the stream is
// positioned read to read the raw data, and we keep
// reading until read returns 0 or less.
//String outpath = outdir + "/" + entry.getName();
try
{
//output = new FileOutputStream(outpath);
int len = 0;
while ((len = stream.read(buffer)) > 0)
{
output.write(buffer, 0, len);
}
}
finally
{
// we must always close the output file
if(output!=null) output.close();
}
}
}
finally
{
// we must always close the zip file.
stream.close();
}
content = output.toByteArray();
return content;
}
This code work for zip file containing single file inside.
I want to read a file from a server and get the data of it.
I have written following piece of code.
URL uurl = new URL(this.m_FilePath);
BufferedReader in = new BufferedReader(new InputStreamReader(uurl.openStream()));
String str;
while ((str = in.readLine()) != null) {
text_file=text_file+str;
text_file=text_file+"\n";
}
m_byteVertexBuffer=text_file.getBytes();
But i am getting wrong result! If I read data from a string, I get m_bytevertexbuffer length=249664.
Now when I read a local file into the bytearray then i get m_bytevertexbuffer length=169332.
FileInputStream fis = new FileInputStream(VertexFile);
fis.read(m_byteVertexBuffer);
ByteBuffer dlb=null;
int l=m_byteVertexBuffer.length;
I want the same data in bytebuffer from a server and also from a local file!
If the server sends a header Content-Length: 999 you could allocate a new byte[999].
URL url = new URL("http://www.android.com/");
URLConnection urlConnection = url.openConnection();
int contentLength = urlConnection.getContentLength();
// -1 if not known or > int range.
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
//if (contentLength >= 0) {
// byte[] bytes = new byte[contentLength];
// in.read(bytes);
// m_byteVertexBuffer = bytes;
//} else {
ByteArrayOutputStream baos;
byte[] bytes = new byte[contentLength == -1 ? 10240 : contentLength];
for (;;) {
int nread = in.read(bytes, 0, bytes.length);
if (nread <= 0) {
break;
}
baos.write(bytes, 0, nread);
}
m_byteVertexBuffer = baos.toByteArray();
//}
} finally {
urlConnection.disconnect();
}
In the general case you would use only the code of the else-branch. But still, one the presence of a valid content-length it is usable.