I am not sure if I got the concept right, but I know that we can verify that the integrity of the files in a zip by getting the CRC values for each entry. However, my question is if I get a zip file, will there be a CRC for it and if so how can I determine that ?
You can use java.util.zip.CRC32 to compute CRC-32 checksum for any data stream.
BufferedInputStream bis = new BufferedInputStream(
new FileInputStream(new File("/path/to/file.zip")));
int read = 0;
CRC32 checksum = new CRC32();
byte[] buffer = new byte[1024];
while ((read = bis.read(buffer)) != -1) {
checksum.update(buffer, 0, read);
}
bis.close();
System.out.println ("CRC32 of your zip is: " + checksum.getValue());
You can use the checksumCRC32 method from the FileUtils class in org.apache.commons.io package.
Related
try
{
FileInputStream fis=new FileInputStream(new File("Binary.txt"));
byte[] infoBin=new byte[fis.available()];
fis.read(infoBin);
for (byte b : infoBin)
{
String bin=Integer.toBinaryString(b);
}
}
How to read a file and convert that file contents into binary then write the binary to a new file using java
After Binary conversion, i don't know how to write the string bin into the new file ?
//reading from file
byte[] array = Files.readAllBytes(Paths.get("Binary.txt"));
//saving to file
FileOutputStream fos = new FileOutputStream("Binary.txt");
fos.write(array );
fos.close();
How to read a file and convert that file contents into binary
They already are binary.
then write the binary to a new file using java
There's no need to waste memory, or assume the file fits into memory, or assume the file size fits into an int. Memorise the following loop for copying between streams in Java:
int count;
byte[] buffer = new byte[8192];
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
I have a list of files from different locations. I create a zip file using the following the code which works without error. But when I try to unzip the file in Windows using Extract All it fails seeing unable to find any bytes, yet if I double click into the zip file itself with Windows Explorer I can see the files and individual ones can be opened and contains the correct data
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile));
for (File next : files)
{
ZipEntry zipEntry = new ZipEntry(next.getName());
zos.putNextEntry(zipEntry);
FileInputStream in = new FileInputStream(next);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0)
{
zos.write(buf, 0, len);
}
zos.closeEntry();
in.close();
}
zos.close();
This may or may not be related but I've found using fixed byte length can lead to a loss of new line characters.
This may help:
final byte[] newLine = System.getProperty(
"line.separator").getBytes("UTF-8");
while ((line = in.readLine()) != null)
final byte[] buffer = line.getBytes("UTF-8");
out.write(buffer, 0, buffer.length);
out.write(newLine, 0, newLine.length);
}
I managed to create zip file in java using this simple piece of code:
BufferedInputStream origin = null;
FileOutputStream dest = new FileOutputStream(zipFile);
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest));
out.setMethod(ZipOutputStream.DEFLATED);
out.setLevel(5);
byte data[] = new byte[BUFFER];
FileInputStream fi = new FileInputStream(file);
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(file.getName());
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
out.closeEntry();
origin.close();
out.close();
zip file created successfully. However when I try to unzip it using WinZip or some other tools I get an error:
Central and local directory mismatch for file "my_file" (general
purpose flags - local:808 hex central: 8 hex).
Severe Error: Local and central GPFlags values don't match.
What's really weird, WinRAR and internal Win7 zip do not show any errors when I decompress the file.
What am I doing wrong? Anybody had this issue?
Thanks a lot!
Must be that out.close is missing.
I think you forgot to close zipentry.
out.closeEntry();
origin.close();
out.close();
My application is unable to transfer data properly over a socket connection and write it to a file properly. Files over about 65,535 bytes get corrupted and are no longer recognized by the programs designed to run them.
I have been able to send small .doc and .txt files successfully, but .mp3 .wmv .m4a .avi and just about anything else does not work. Neither do larger docs.
I have looked all over the internet for a solution to this problem. I have repeatedly tweaked the I/O code to fix the problem but it still doesn't work! Here is the I/O code in the super class that handles sending and receiving files. If you need anymore information/other parts of code, let me know.
protected void sendFile() throws IOException {
byte[] bytes = new byte[(int) file.length()];
buffin = new BufferedInputStream(new FileInputStream(file));
int bytesRead = buffin.read(bytes,0,bytes.length);
System.out.println(bytesRead);
out = sock.getOutputStream();
out.write(bytes,0,fileBytes);
out.flush();
out.close();
}
protected void receiveFile() throws IOException {
byte[] bytes = new byte[fileBytes];
in = sock.getInputStream();
for(int i=0;i<fileBytes;i++) {
in.read(bytes);
}
fos = new FileOutputStream("/Datawire/"+fileName);
buffout = new BufferedOutputStream(fos);
buffout.write(bytes,0,fileBytes);
buffout.flush();
buffout.close();
}
UPDATED CODE (that works):
protected void sendFile() throws IOException {
if((file.length())<63000) {
byte[] bytes = new byte[(int)file.length()];
buffin = new BufferedInputStream(new FileInputStream(file));
buffin.read(bytes,0,bytes.length);
out = sock.getOutputStream();
out.write(bytes,0,bytes.length);
out.close();
} else {
byte[] bytes = new byte[32000];
buffin = new BufferedInputStream(new FileInputStream(file));
out = sock.getOutputStream();
int bytesRead;
while((bytesRead = buffin.read(bytes))>0) {
out.write(bytes,0,bytesRead);
}
out.close();
}
}
protected void receiveFile() throws IOException {
if(fileBytes<63000) {
byte[] bytes = new byte[32000];
in = sock.getInputStream();
System.out.println(in.available());
in.read(bytes,0,fileBytes);
fos = new FileOutputStream("/Datawire/"+fileName);
buffout = new BufferedOutputStream(fos);
buffout.write(bytes,0,bytes.length);
buffout.close();
} else {
byte[] bytes = new byte[16000];
in = sock.getInputStream();
fos = new FileOutputStream("/Datawire/"+fileName);
buffout = new BufferedOutputStream(fos);
int bytesRead;
while((bytesRead = in.read(bytes))>0) {
buffout.write(bytes,0,bytesRead);
}
buffout.close();
}
}
The issue is that you are sending only chunks of it. That is, you are only sending 64k of the file ever. If the file is ever larger then 64k the other end will never see it.
You want to continously read from the BufferedInputStream until the read() returns either less then the length or -1.
Your code is completely wrong. This is how to copy a stream in Java:
int count;
byte[] buffer = new byte[8192]; // more if you like but no need for it to be the entire file size
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
You should use this both when sending the file and when receiving the file. At present your sending method hopes that the entire file fits into memory; fits into INTEGER_MAX bytes; and is read in one chunk by the read method, without even checking the result. You can't assume any of those things. Your receive method is complete rubbish: it just keeps overwriting the same array, again without checking any read() results.
EDIT: Your revised code is just as bad, or worse. You are calling read() to check for EOS and then throwing that byte away, and then calling read() again and throwing away the read count it returns. You pointlessly have a different path for files < 64000, or 63000, or whatever it is, that has zero benefit except to give you two code paths to test, or possibly four, instead of one. The network only gives you 1460 bytes at a time at best anyway so what is the point? You already have (a) a BufferedInputStream with a default buffersize of 8192, and (b) my code that uses a byte[] buffer of any size you like. My code above works for any amount of data in two lines of executable code. Yours is 20. QED.
I suggest that you use some good library to read and write file contents as well as socket read/write. For example Apache Commons IO. If you insist on writig code yourself, do it smaller chunks rather than the whole file at once.
You have to consider that InputStream.read returns the number of bytes read which may be less than the total number of bytes in the file.
You would probably be better off just letting something like CopyUtils.copy take care of this for you.
You need to loop until bytesRead < 0. You need to make sure that fileBytes is => than the transferred file.
protected void receiveFile() throws IOException {
byte [] bytes = new byte [fileBytes];
InputStream is = sock.getInputStream();
FileOutputStream fos = new FileOutputStream("/Datawire/"+fileName);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int bytesRead = is.read(bytes,0,bytes.length);
int current = bytesRead;
do {
bytesRead =
is.read(bytes, current, (bytes.length-current));
if(bytesRead >= 0) current += bytesRead;
} while(bytesRead > -1);
bos.write(bytes, 0 , current);
bos.flush();
bos.close();
}
how do I translate this code into jython?
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(file + ".zip"));
byte[] buf = new byte[1024];
int len;
//Create a new Zip entry with the file's name.
ZipEntry zipEntry = new ZipEntry(file.toString());
//Create a buffered input stream out of the file
//we're trying to add into the Zip archive.
FileInputStream fin = new FileInputStream(file);
BufferedInputStream in = new BufferedInputStream(fin);
zos.putNextEntry(zipEntry);
//Read bytes from the file and write into the Zip archive.
while ((len = in.read(buf)) >= 0) {
zos.write(buf, 0, len);
}
//Close the input stream.
in.close();
//Close this entry in the Zip stream.
zos.closeEntry();
this is what I have but it Fails badly
buf=None <<<< ?
len=None <<<< ?
zipEntry=ZipEntry(file.toString())
fin=FileInputStream(file)
bin=BufferedInputStream(fin)
self._zos.putNextEntry(zipEntry)
while (len=bin.helpme_im_dying(buf)) >= 0): <<<< ?
self._zos.write(buf,0,len) <<<< ?
len = bin.read(buf) <<<< ?
bin.close()
self._zos.closeEntry()
refer to this page for information https://www.acm.org/crossroads/xrds6-3/ovp63.html
Here's an exact translation of that function (except, like your case, using bin instead of reserved keyword in).
from jarray import zeros
from java.io import BufferedInputStream, FileInputStream, FileOutputStream
from java.util.zip import ZipEntry, ZipOutputStream
def test(file):
zos = ZipOutputStream(FileOutputStream(file + ".zip"))
buf = zeros(1024, 'b')
zipEntry = ZipEntry(file)
fin = FileInputStream(file)
bin = BufferedInputStream(fin)
zos.putNextEntry(zipEntry)
len = bin.read(buf)
while len >= 0:
zos.write(buf, 0, len)
len = bin.read(buf)
bin.close()
zos.closeEntry()
It is not an answer to your question, but related. Here is a CPython version:
from zipfile import ZipFile, ZIP_DEFLATED
def test(file):
ZipFile(file+".zip", "w", ZIP_DEFLATED).write(file)
Don't use ZipFile without ensuring it is closed:
with ZipFile('spam.zip', 'w') as myzip:
myzip.write('eggs.txt')