I have been communicating with my Java application using php by creating a socket, from Java end, I will compress the result and write those bytes to the php.
public static byte[] compressString(byte[] b) throws IOException{
byte[] compressedBytes = null;
ByteArrayOutputStream out = new ByteArrayOutputStream(b.length);
try{
GZIPOutputStream gzip = new GZIPOutputStream(out);
gzip.write(b, 0, b.length);
gzip.finish();
gzip.flush();
gzip.close();
compressedBytes = out.toByteArray();
System.out.println("comp1::"+compressedBytes+", length::"+compressedBytes.length);
}finally{
out.close();
}
return compressedBytes;
}
But when i am performing
$data = fgets($fp);
$decompData = gzuncompress($data);
$decompData is returned null.
Kindly provide a solution as i have tried Deflater with gzuncompress, gzdecode and every possible option. There must be something i am missing here. Consider me as newbie in php.
You need to use gzdecode() for gzip streams, and you may need to open the file using "rb" to read binary data without translation.
Related
I would like to rewrite python code to java . This is python code:
zipped = zlib.compress(data_json_upload.encode("utf-8"))
print ("data encode")
print (zipped)
base64_bytes = base64.b64encode(zipped)
base64_string = base64_bytes.decode('utf-8')
and This is my java code :
*
byte[] bytes = inputString.getBytes("UTF-8");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream os = new GZIPOutputStream(baos);
os.write(bytes, 0, bytes.length);
os.close();
byte[] result = baos.toByteArray();
System.out.println(result);
byte [] base64=Base64.encodeBase64(result);
String send= new String(base64,"UTF-8");
*
however they seems to be return different results for the same string any idea what can I change to get the same code is working on java ?
For example send in java not the same as base64_string in java
GZIPOutputStream will produce a *.gz file. If you just need a zlib stream, use DeflaterOutputStream instead.
// ... the rest are the same ...
DeflaterOutputStream os = new DeflaterOutputStream(baos);
// ... the rest are the same ...
I am trying to port the following java code to .net:
private final byte[] zipLicense(byte lic[])
{
byte buf[];
ByteArrayInputStream bis;
DeflaterInputStream dis;
ByteArrayOutputStream bos;
buf = new byte[64];
bis = new ByteArrayInputStream(lic);
dis = new DeflaterInputStream(bis, new Deflater());
bos = new ByteArrayOutputStream();
byte abyte0[];
int len;
while((len = dis.read(buf)) > 0)
bos.write(buf, 0, len);
abyte0 = bos.toByteArray();
try
{
bis.close();
dis.close();
bos.close();
}
catch(IOException ex)
{
ex.printStackTrace();
}
return abyte0;
}
My best shot was this code in C#:
private byte[] zipLicense(byte[] lic)
{
var outputMemStream = new MemoryStream();
ZipOutputStream zipStream;
using (zipStream = new ZipOutputStream(outputMemStream))
{
zipStream.Write(lic, 0, lic.Length);
Debug.WriteLine(string.Format("Compressed bytes: {0}", outputMemStream.Length));
}
return outputMemStream.ToArray();
}
ZipOutputStream is a class from SharpZipLib
When I try to run the C# code, I get error on first attempt to write to zipStream
zipStream.Write(lic, 0, lic.Length);
The error states that I haven't provided "No entry". I see in examples that one can and probably should seciffy an entry string to a zip stream, but what java code puts as an entry then? Please help in porting this java functionality to .Net. Thanks!
The Java DeflaterInputStream is more like .NET's DeflateStream. That is, it's simply a compressed stream, without the directory index that a full .zip file would contain.
Try this:
private byte[] zipLicense(byte[] lic)
{
var outputMemStream = new MemoryStream();
using (DeflateStream stream =
new DeflateStream(outputMemStream, CompressionMode.Compress, true))
{
stream.Write(lic, 0, lic.Length);
}
Debug.WriteLine(string.Format("Compressed bytes: {0}", outputMemStream.Length));
return outputMemStream.ToArray();
}
Note that I've added a call to Flush(). Without this, the outputMemStream.Length property may not be current (i.e. not quite the full length of the resulting stream).
For what it's worth, .NET now has reasonably good .zip file support built-in (e.g. ZipArchive class). So if you do find yourself actually needing that some day, I would try to use that first rather than adding a third-party library to your deployment.
I have a problem with sending large string through socket from server to android client.
String is about 10MB.
Code for writing data to socket is this:
int socketTimeout = 200;
socket = new Socket(client.getHost(), client.getPort());
socket.setSoTimeout(socketTimeout);
OutputStreamWriter oos=new OutputStreamWriter(socket.getOutputStream());
String d = data.getData().toString() + "\n";
oos.write(d);
oos.flush();
Code for reading data from socket is this:
Socket s = params[0];
InputStream is = null;
try {
is = s.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[32768];
while ((nRead = is.read(data, 0, data.length)) != -1) {
baos.write(data, 0, nRead);
}
return new String(baos.toByteArray());
}
So problem comes at line where I'm reading from inputStream where I get OutOfMemoryException. I tried using different examples of reading string from stream. I tried with BufferedInputStream, InputStreamReader, IOUtils, StringBuilder, BufferedReader ..etc. and all of them give me OutOfMemory exception when the string is large. I tested with smaller data something around 100K and it works perfectly.
Exception that I get on server-side is "Connection is reset by peer, socket write error."
You can read byte by byte in the client and write to a File byte by byte, in that way you are not holding the whole string in memory.
And then of course read that file by tokens or lines, not the whole string at once
By storing it in a ByteArrayOutputStream (or similar), you are coming up against the maximum heap size for the JVM in Android. This is a different size depending on the device. See: Android heap size on different phones/devices and OS versions
As has already been suggested, you should consider using a file stream to write the received data to disk.
I am trying to load a .swf file in my page, i would like to make this load faster by converting it to Base64, rather providing a src. This is working great with image formats by using the below code
Java code
BufferedImage buffImg = ImageIO.read(new File(imagePath));
ImageIO.write(buffImg, imgExtension, bos);
byte[] imageBytes = bos.toByteArray();
BASE64Encoder encoder = new BASE64Encoder();
imageString = encoder.encode(imageBytes);
but this is not working for swf file. is there any possible way to achieve this.
Html
<object width="10" height="10" data="data:application/x-shockwave-flash;base64, RldTCSEAAABIAZAAZAAADAEARBEIAAAAQwIAAP9AAAAA"></object>
thanks in advance.
Trying to get the file in base64 will not speed up the file transfer, it's just the opposite as it will convert the file which is stored in bytes (base256 if it can be said that way) to base64 (64 printable characters), so the final amount of data you will be transfering is more.
The only "win" is that you might be able to load it as part of the page instead of the browser making another call for the swf file, which should be no issue on http 1.1.
Unless you have some other good reason to do this, I would not suggest this kind of practice.
If you have your swf file(s) in a database as a blob, you could just make a servlet which sets the proper contenttype and write the whole file with the ServletOutputStream, without any tags. In your html code, you would have to reference to the servlet instead of a fixed file.
If you still want to convert the file to base64, you shouldn't use some image API, but get the file in a standard way for binary files, here's a sample that should do the job:
http://www.javapractices.com/topic/TopicAction.do?Id=245
You can still do the encoding as you did it once you have a byte array:
File file = new File(imagePath);
log("File size: " + file.length());
byte[] result = null;
try {
InputStream input = new BufferedInputStream(new FileInputStream(file));
result = readAndClose(input);
}
catch (FileNotFoundException ex){
log(ex);
}
BASE64Encoder encoder = new BASE64Encoder();
imageString = encoder.encode(result);
And the readAndClose method:
byte[] readAndClose(InputStream aInput){
byte[] bucket = new byte[32*1024];
ByteArrayOutputStream result = null;
try {
try {
result = new ByteArrayOutputStream(bucket.length);
int bytesRead = 0;
while(bytesRead != -1){
bytesRead = aInput.read(bucket);
if(bytesRead > 0){
result.write(bucket, 0, bytesRead);
}
}
}
finally {
aInput.close();
}
}
catch (IOException ex){
log(ex);
}
return result.toByteArray();
}
This should do the trick, maybe some fine tunings to adapt the code to your specific situation, optimize it and better error handling...
I have a file that can be any thing like ZIP, RAR, txt, CSV, doc etc. I would like to create a ByteArrayInputStream from it.
I'm using it to upload a file to FTP through FTPClient from Apache Commons Net.
Does anybody know how to do it?
For example:
String data = "hdfhdfhdfhd";
ByteArrayInputStream in = new ByteArrayInputStream(data.getBytes());
My code:
public static ByteArrayInputStream retrieveByteArrayInputStream(File file) {
ByteArrayInputStream in;
return in;
}
Use the FileUtils#readFileToByteArray(File) from Apache Commons IO, and then create the ByteArrayInputStream using the ByteArrayInputStream(byte[]) constructor.
public static ByteArrayInputStream retrieveByteArrayInputStream(File file) {
return new ByteArrayInputStream(FileUtils.readFileToByteArray(file));
}
The general idea is that a File would yield a FileInputStream and a byte[] a ByteArrayInputStream. Both implement InputStream so they should be compatible with any method that uses InputStream as a parameter.
Putting all of the file contents in a ByteArrayInputStream can be done of course:
read in the full file into a byte[]; Java version >= 7 contains a convenience method called readAllBytes to read all data from a file;
create a ByteArrayInputStream around the file content, which is now in memory.
Note that this may not be optimal solution for very large files - all the file will stored in memory at the same point in time. Using the right stream for the job is important.
A ByteArrayInputStream is an InputStream wrapper around a byte array. This means you'll have to fully read the file into a byte[], and then use one of the ByteArrayInputStream constructors.
Can you give any more details of what you are doing with the ByteArrayInputStream? Its likely there are better ways around what you are trying to achieve.
Edit:
If you are using Apache FTPClient to upload, you just need an InputStream. You can do this;
String remote = "whatever";
InputStream is = new FileInputStream(new File("your file"));
ftpClient.storeFile(remote, is);
You should of course remember to close the input stream once you have finished with it.
This isn't exactly what you are asking, but is a fast way of reading files in bytes.
File file = new File(yourFileName);
RandomAccessFile ra = new RandomAccessFile(yourFileName, "rw"):
byte[] b = new byte[(int)file.length()];
try {
ra.read(b);
} catch(Exception e) {
e.printStackTrace();
}
//Then iterate through b
This piece of code comes handy:
private static byte[] readContentIntoByteArray(File file)
{
FileInputStream fileInputStream = null;
byte[] bFile = new byte[(int) file.length()];
try
{
//convert file into array of bytes
fileInputStream = new FileInputStream(file);
fileInputStream.read(bFile);
fileInputStream.close();
}
catch (Exception e)
{
e.printStackTrace();
}
return bFile;
}
Reference: http://howtodoinjava.com/2014/11/04/how-to-read-file-content-into-byte-array-in-java/