Weird issue with zip/gzip files - java

Below is a program which saves the bytes to a .png file and zips into a given name folder.
byte[] decodedBytes = Base64.decodeBase64(contents);
// System.out.println(new String(decodedBytes));
InputStream targetStream = new ByteArrayInputStream(decodedBytes);
int count;
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFilePath));
out.putNextEntry(new ZipEntry(pngFile));
byte[] b = new byte[1024];
while ((count = targetStream.read(b)) > 0) {
out.write(b, 0, count);
}
out.flush();
out.close();
targetStream.close();
When i open it manually using 7 zip I see the following folder structure (c:\output\nameofzipfile.zip\nameofpng.png\nameofpng). Why is this happening? What am I doing wrong? As per my understanding this should be the structure (c:\output\nameofzipfile.zip\nameofpng.png)

Worked with the following code
byte[] decoded = Base64.decodeBase64(contents);
try (FileOutputStream fos = new FileOutputStream(zipFilePath + amazonOrderId + zipFileName)) {
fos.write(decoded);
fos.close();
}
file = new File(destDirectory + amazonOrderId + pngFile);
if (file.exists()) {
file.delete();
}
try (OutputStream out = new FileOutputStream(destDirectory + amazonOrderId + pngFile)) {
try (InputStream in = new GZIPInputStream(
new FileInputStream(zipFilePath + amazonOrderId + zipFileName))) {
byte[] buffer = new byte[65536];
int noRead;
while ((noRead = in.read(buffer)) != -1) {
out.write(buffer, 0, noRead);
}
}
}

Related

java: send large files through sockets

So im making a client-server based architecture programm where server is sending a file and client receives it.
I have seen a lot of code parts and i also made a lot where i send small files. ex images. In my case i want to send .wav audio files which are large(40mb). This is what i have done so far. When i run my client, it just proceed to download, but never really downloads the file. I guess its because its too large.
How to send such large files?
server
public void send_file_to_client(String requested_file) throws IOException {
FileInputStream fis = null;
BufferedInputStream bis = null;
File FILE_TO_SEND = new File("C:\\ServerMusicStorage\\" + requested_file + ".wav");
byte[] mybytearray = new byte[(int) FILE_TO_SEND.length()];
try {
fis = new FileInputStream(FILE_TO_SEND);
bis = new BufferedInputStream(fis);
} catch (FileNotFoundException ex) {
Logger.getLogger(ClientHandler.class.getName()).log(Level.SEVERE, null, ex);
}
OutputStream os = null;
bis.read(mybytearray, 0, mybytearray.length);
os = connsock.getOutputStream();
System.out.println("Sending " + FILE_TO_SEND + "(" + mybytearray.length + " bytes)");
toClient.writeUTF(Integer.toString(mybytearray.length));
os.write(mybytearray, 0, mybytearray.length);
os.flush();
System.out.println("Done.");
if (bis != null) {
bis.close();
}
if (os != null) {
os.close();
}
if (connsock != null) {
connsock.close();
}
}
client
public static void receive_file(String requested_file) throws IOException {
File file_to_save = new File("C:\\ClientMusicStorage\\" + requested_file + ".wav");
int bytesRead;
int current = 0;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
//get file size to create the bytearray
String fileSize=fromServer.readUTF();
int final_file_size = Integer.parseInt(fileSize);
byte[] mybytearray = new byte[final_file_size];
InputStream is = clientSocket.getInputStream();
fos = new FileOutputStream(file_to_save);
bos = new BufferedOutputStream(fos);
bytesRead = is.read(mybytearray, 0, mybytearray.length);
current = bytesRead;
do {
bytesRead
= is.read(mybytearray, current, (mybytearray.length - current));
if (bytesRead >= 0) {
current += bytesRead;
}
} while (bytesRead > -1);
bos.write(mybytearray, 0, current);
bos.flush();
}

Java Socket Programming Buffer for Large File

I am trying to transfer a large file from a server to a client. My code so far works but only if I set the buffer size in the client code to the exact size of the file. I won't always know what the file size is going to be. I keep finding examples that claim it doesn't matter what the size of the file or buffer is because it will just keep reading from the input stream...? However, when I implement the code that supposedly does this, it transfers 0 bytes.
Client:
public static void main (String [] args ) throws IOException {
int bytesRead;
int current = 0;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
Socket sock = null;
try {
sock = new Socket(hostname, 20000);
System.out.println("Connecting...");
// receive file
InputStream is = sock.getInputStream();
fos = new FileOutputStream(FILE_TO_RECEIVE);
bos = new BufferedOutputStream(fos);
//////////// replaced this ////////////////////////////
byte[] buffer = new byte[BUFFER_SIZE];
bytesRead = is.read(buffer,0,buffer.length);
current = bytesRead;
do {
bytesRead = is.read(buffer, current, (buffer.length-current));
if(bytesRead >= 0){ current += bytesRead;}
} while(bytesRead > 0);
bos.write(buffer, 0 , current);
///////////////////////////////////////
// with this:
// int count;
// byte[] buffer = new byte[8192];
// while ((count = is.read(buffer)) > 0)
// {
// bos.write(buffer, 0, count);
// }
//////////// transfers 0 bytes ///////////
bos.flush();
System.out.println("File " + FILE_TO_RECEIVE
+ " downloaded (" + current + " bytes read)");
}
finally {
if (fos != null){ fos.close();}
if (bos != null){ bos.close();}
if (sock != null){ sock.close();}
}
}
Server:
public static void main(String[] args) throws IOException{
FileInputStream fis = null;
BufferedInputStream bis = null;
OutputStream os = null;
ServerSocket servsock = null;
Socket sock = null;
try {
servsock = new ServerSocket(20000);
while (true) {
System.out.println("Waiting...");
try {
sock = servsock.accept();
System.out.println("Accepted connection : " + sock);
// send file
File myFile = new File (FILE_TO_SEND);
byte [] mybytearray = new byte [(int)myFile.length()];
fis = new FileInputStream(myFile);
bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
os = sock.getOutputStream();
System.out.println("Sending " + FILE_TO_SEND + "(" + mybytearray.length + " bytes)");
os.write(mybytearray,0,mybytearray.length);
os.flush();
System.out.println("Done.");
}
finally {
if (bis != null){ bis.close();}
if (os != null){ os.close();}
if (sock!=null){ sock.close();}
}
}
}
finally {
if (servsock != null){
servsock.close();
}
}
}
Thank you for your help
Your copy loops are both different, and both nonsense. One of them isn't even a loop. Try this:
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
This works for any buffer of size >= one byte.
Use this at both ends.

Reading JPEG Stream over socket gives Null characters

I am reading a .jpg file over InputStream using this code but I am receiving NULNUL...n stream after some text. Ii am reading this file link to file and link of file that I received , link is Written File link.
while ((ret = input.read(imageCharArray)) != -1) {
packet.append(new String(imageCharArray, 0, ret));
totRead += ret;
imageCharArray = new char[4096];
}
file = new File(
Environment.getExternalStorageDirectory()
+ "/FileName_/"
+ m_httpParser.filename + ".jpg");
PrintWriter printWriter = new PrintWriter(file);
// outputStream = new FileOutputStream(file); //also Used FileoutputStream for writting
// outputStream.write(packet.toString().getBytes());//
// ,
printWriter.write(packet.toString());
// outputStream.close();
printWriter.close();
}
I have also tried FileoutputStream but hardlucj for this too as commented in my code.
Edit
I have used this also. I have a content length field upto which i am reading and writing
byte[] bytes = new byte[1024];
int totalReadLength = 0;
// read untill we have bytes
while ((read = inputStream.read(bytes)) != -1
&& contentLength >= (totalReadLength)) {
outputStream.write(bytes, 0, read);
totalReadLength += read;
System.out.println(" read size ======= "
+ read + " totalReadLength = "
+ totalReadLength);
}
String is not a container for binary data, and PrintWriter isn't a way to write it. Get rid of all, all, the conversions between bytes and String and vice versa, and just transfer the bytes with input and output streams:
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
If you need to constrain the number of bytes read from the input, you have to do that before calling read(), and you also have to constrain the read() correctly:
while (total < length && (count = in.read(buffer, 0, length-total > buffer.length ? buffer.length: (int)(length-total))) > 0)
{
total += count;
out.write(buffer, 0, count);
}
I tested it in my Nexus4 and it's working for me. Here is the snippet of code what I tried :
public void saveImage(String urlPath)throws Exception{
String fileName = "kumar.jpg";
File folder = new File("/sdcard/MyImages/");
// have the object build the directory structure, if needed.
folder.mkdirs();
final File output = new File(folder,
fileName);
if (output.exists()) {
output.delete();
}
InputStream stream = null;
FileOutputStream fos = null;
try {
URL url = new URL(urlPath);
stream = url.openConnection().getInputStream();
// InputStreamReader reader = new InputStreamReader(stream);
DataInputStream dis = new DataInputStream(url.openConnection().getInputStream());
byte[] fileData = new byte[url.openConnection().getContentLength()];
for (int x = 0; x < fileData.length; x++) { // fill byte array with bytes from the data input stream
fileData[x] = dis.readByte();
}
dis.close();
fos = new FileOutputStream(output.getPath());
fos.write(fileData);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Just Call the above function in a background thread and pass your url. It'll work for sure. Let me know if it helps.
You can check below code.
destinationFile = new File(
Environment.getExternalStorageDirectory()
+ "/FileName_/"
+ m_httpParser.filename + ".jpg");
BufferedOutputStream buffer = new BufferedOutputStream(new FileOutputStream(destinationFile));
byte byt[] = new byte[1024];
int i;
for (long l = 0L; (i = input.read(byt)) != -1; l += i ) {
buffer.write(byt, 0, i);
}
buffer.close();

Zipping a csv file throws a "At Least One ZipEntry" using Java

What I am trying to do is to zip a generated csv file. The file does get generated without issue until it comes to this code here. So the code throws the exception at zos.close() here's the code
try {
FileOutputStream fos = new FileOutputStream(file.getPath());
ZipOutputStream zos = new ZipOutputStream(fos);
FileInputStream in = new FileInputStream(file.getPath());
String fullCSVFileName = file.getName();
String fullFileName = fullCSVFileName.substring(0, fullCSVFileName.length()-3);
String fullZipFileName = fullFileName + "zip";
ZipEntry ze= new ZipEntry(fullZipFileName);
if(ze != null) zos.putNextEntry(ze);
fos = new FileOutputStream("C:\\sourceLocation\\"+fullZipFileName);
zos = new ZipOutputStream(fos);
byte[] buffer = new byte[1024];
int len;// = in.read(buffer);
while ((len = in.read(buffer)) > 0) {
Logger.debug("in Loop, len = " + len);
zos.write(buffer, 0, len);
}
in.close();
zos.closeEntry();
zos.close();
Logger.debug("Zipping complete!");
} catch(IOException ex) {
Logger.error(ex);
}
Corrected Code
try{
String fullCSVFileName = file.getName();
String fullFileName = fullCSVFileName.substring(0, fullCSVFileName.length()-3);
String fullZipFileName = fullFileName + "zip";
FileOutputStream fos = new FileOutputStream("C:\\sourceLocation\\"+fullZipFileName);
ZipOutputStream zos = new ZipOutputStream(fos);
FileInputStream in = new FileInputStream(file.getPath());
ZipEntry ze= new ZipEntry(fullZipFileName);
if(ze != null){
zos.putNextEntry(ze);
}
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
in.close();
zos.closeEntry();
zos.close();
Logger.debug("Zipping complete!");
}catch(IOException ex){
Logger.error(ex);
}
You create fos and zos once at the top of your code:
FileOutputStream fos = new FileOutputStream(file.getPath());
ZipOutputStream zos = new ZipOutputStream(fos);
then add a ZipEntry:
if(ze != null) zos.putNextEntry(ze);
then redifine them later:
fos = new FileOutputStream("C:\\sourceLocation\\"+fullZipFileName);
zos = new ZipOutputStream(fos);
then close the new zos. You never closed, nor wrote to the first zos (which had a ZipEntry) and never added a ZipEntry to the second (which you tried to close without any). Hence, the At Least One ZipEntry error.
------------ Edit --------------
Try adding zos.finish(), also, your close() methods should be in a finally block...
ZipOutputStream zos = null;
FileInputStream in = null;
try{
String fullCSVFileName = file.getName();
String fullFileName = fullCSVFileName.substring(0, fullCSVFileName.length()-3);
String fullZipFileName = fullFileName + "zip";
ZipOutputStream zos = new ZipOutputStream(
new FileOutputStream("C:\\sourceLocation\\"+fullZipFileName));
in = new FileInputStream(file.getPath());
zos.putNextEntry( new ZipEntry(fullZipFileName) );
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
zos.finish();
Logger.debug("Zipping complete!");
}catch(IOException ex){
Logger.error(ex);
}finally {
if ( zos != null ) {
try {
zos.close();
} catch ( Exception e ) {}
}
if ( in != null ) {
try {
in.close();
} catch ( Exception e ) {}
}
}

Zip a file in BlackBerry Java app

Does anyone know how to zip a file using ZipOutputStream?
try {
// Creating Zip Streams
FileConnection path = (FileConnection) Connector.open(
"file:///SDCard/BlackBerry/documents/" + "status.zip",
Connector.READ_WRITE);
if (!path.exists()) {
path.create();
}
ZipOutputStream zinstream = new ZipOutputStream(
path.openOutputStream());
// Adding Entries
FileConnection jsonfile = (FileConnection) Connector.open(
"file:///SDCard/BlackBerry/documents/" + "status.json",
Connector.READ_WRITE);
if (!jsonfile.exists()) {
jsonfile.create();
}
int fileSize = (int) jsonfile.fileSize();
if (fileSize > -1) {
byte[] data = new byte[fileSize];
InputStream input = jsonfile.openInputStream();
input.read(data);
ZipEntry entry = new ZipEntry(jsonfile.getName());
zinstream.putNextEntry(entry);
// zinstream.write(buf);
// ZipEntry entry = null;
path.setWritable(true);
OutputStream out = path.openOutputStream();
int len;
while ((len = input.read(data)) != -1) {
out.write(data, 0, len);
out.flush();
out.close();
zinstream.close();
content = "FILE EXIST" + entry;
}
jsonfile.close();
path.close();
}
} catch (...) {
...
}
The data should be written to the ZipOutputStream zinstream instead of to a new OutputStream out.
Its also important to close the ZipEntry entry after writing is done.
FileConnection path = (FileConnection) Connector.open(
"file:///SDCard/BlackBerry/documents/" + "status.zip",
Connector.READ_WRITE);
if (!path.exists()) {
path.create();
}
ZipOutputStream zinstream = new ZipOutputStream(path.openOutputStream());
// Adding Entries
FileConnection jsonfile = (FileConnection) Connector.open(
"file:///SDCard/BlackBerry/documents/" + "status.json",
Connector.READ_WRITE);
if (!jsonfile.exists()) {
jsonfile.create();
}
int fileSize = (int) jsonfile.fileSize();
if (fileSize > -1) {
InputStream input = jsonfile.openInputStream();
byte[] data = new byte[1024];
ZipEntry entry = new ZipEntry(jsonfile.getName());
zinstream.putNextEntry(entry);
int len;
while ((len = input.read(data)) > 0) {
zinstream.write(data, 0, len);
}
zinstream.closeEntry();
}
jsonfile.close();
zinstream.close();
path.close();
BlackBerry uses the J2ME API which does not have all of the J2SE classes, such as the ZipOutputStream and ZipEntry and related classes. There are some classes such as ZLibOutputStream which may help, but that is just the byte-level compression and you'll end up having to implement the actual PKZIP container yourself (unless there is a third-party library out there that can do this for you).

Categories

Resources