The present of FileOutputStream cause the InputStream.read error - java

I have some problem with Java IO, this code below is not working, the variable count return -1 directly.
public void putFile(String name, InputStream is) {
try {
OutputStream output = new FileOutputStream("D:\\TEMP\\" + name);
byte[] buf = new byte[1024];
int count = is.read(buf);
while( count >0) {
output.write(buf, 0, count);
count = is.read(buf);
}
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
}
But if I commented the OutputStream such as
public void putFile(String name, InputStream is) {
try {
//OutputStream output = new FileOutputStream("D:\\TEMP\\" + name);
byte[] buf = new byte[1024];
int count = is.read(buf);
while( count >0) {
//output.write(buf, 0, count);
count = is.read(buf);
}
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
}
The count will return the right value (>-1).
How is this possible ? Is it a bug ?
I'm using Jetty in Eclipse with Google plugins and Java 6.21 in Windows 7.
PS :I change the original code, but it doesn't affect the question

Related

Resources should be closed - Sonar

I have the following piece of code:
public static byte[] readSomeFile(String filePath) {
byte[] buffer = new byte[FILE_SIZE];
FileInputStream fileIn = null;
BufferedInputStream buffIn = null;
DataInputStream inData = null;
int size = 0;
byte[] someArray= null;
try {
fileIn = new FileInputStream(filePath);
buffIn = new BufferedInputStream(fileIn);
inData = new DataInputStream(buffIn);
size = inData.read(buffer, 0, FILE_SIZE);
someArray= new byte[size];
System.arraycopy(buffer, 0, someArray, 0, size);
} catch (IOException e) {
//log(Log.ERROR,"IO ERROR: " + e.toString());
} finally {
try {
if (null != fileIn) {
fileIn.close();
}
if (null != buffIn) {
buffIn.close();
}
if (null != inData) {
inData.close();
}
} catch (Exception exFinally) {
// some stuff
someArray= null;
}
}
return someArray;
}
the problem is Sonar is still complaining about fileIn not being closed, although it's the first resource addressed in the finally block.
How does Sonar work in this case ? and how to resolve the Resources should be closed rule ?
If you have to use the Java 7 and above, I prefer you to use try with resources which was introduced in Java 7 new features.
Try-with-resources in Java 7 is a new exception handling mechanism that makes it easier to correctly close resources that are used within a try-catch block.
As to your code:
finally {
try {
if (null != fileIn) {
fileIn.close();
}
if (null != buffIn) {
buffIn.close();
}
if (null != inData) {
inData.close();
}
} catch (Exception exFinally) {
// some stuff
someArray= null;
}
}
Do you notice that ugly double try?
But, if you used the try with resources , close() is automatically called, if it throws an Exception or not, it will be supressed (as specified in the Java Language Specification 14.20.3) . Same happens for your case. I hope it helps.
So, your code will be looked like:
public static byte[] readSomeFile(String filePath) {
byte[] buffer = new byte[FILE_SIZE];
int size = 0;
byte[] someArray= null;
try (FileInputStream fileIn = new FileInputStream(filePath);
BufferedInputStream buffIn = new BufferedInputStream(fileIn);
DataInputStream inData = new DataInputStream(buffIn);) {
size = inData.read(buffer, 0, FILE_SIZE);
someArray= new byte[size];
System.arraycopy(buffer, 0, someArray, 0, size);
} catch (IOException e) {
//log(Log.ERROR,"IO ERROR: " + e.toString());
}
return someArray;
}

Java LZ4 compression using Input/Output streams

I'm using jpountz LZ4 to try and compress files and I want to read in and output files using Java file input and output streams. I've tried to find a solution online but theres nothing, I found a previous stackoverflow question on how to implement LZ4 correctly and I've taken that and tried to modify it to use the streams, but I'm not sure if this is correct or if it's even working.
When running the compression on a text file it outputs a file which has some characters missing or replaced with symbols
ðHello world Heðo world Hello ðrld Hello worlðHello worl
but when running it with a image file it throws an out of bounds error. I've also been unable to get decompression to work as it throws a Error decoding offset 3 of input buffer.
Here is my code any help would be appreciated thanks
public void LZ4Compress(InputStream in, OutputStream out){
int noBytesRead = 0; //number of bytes read from input
int noBytesProcessed = 0; //number of bytes processed
try {
while ((noBytesRead = in.read(inputBuffer)) >= 0) {
noBytesProcessed = inputBuffer.length;
decompressedLength = inputBuffer.length;
outputBuffer = compress(inputBuffer, decompressedLength);
out.write(outputBuffer, 0, noBytesRead);
}
out.flush();
in.close();
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void LZ4decompress(InputStream in, OutputStream out){
int noBytesRead = 0; //number of bytes read from input
try {
while((noBytesRead = in.read(inputBuffer)) >= 0){
noBytesProcessed = inputBuffer.length;
outputBuffer = decompress(inputBuffer);
out.write(outputBuffer, 0, noBytesRead);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static byte[] compress(byte[] src, int srcLen) {
decompressedLength = srcLen;
int maxCompressedLength = compressor.maxCompressedLength(decompressedLength);
byte[] compressed = new byte[maxCompressedLength];
int compressLen = compressor.compress(src, 0, decompressedLength, compressed, 0, maxCompressedLength);
byte[] finalCompressedArray = Arrays.copyOf(compressed, compressLen);
return finalCompressedArray;
}
private static LZ4SafeDecompressor decompressor = factory.safeDecompressor();
public static byte[] decompress(byte[] finalCompressedArray) {
byte[] restored = new byte[finalCompressedArray.length];
restored = decompressor.decompress(finalCompressedArray, finalCompressedArray.length);
return restored;
}
So I solved my problem by using LZ4block input/output streams
public static void LZ4compress(String filename, String lz4file){
byte[] buf = new byte[2048];
try {
String outFilename = lz4file;
LZ4BlockOutputStream out = new LZ4BlockOutputStream(new FileOutputStream(outFilename), 32*1024*1024);
FileInputStream in = new FileInputStream(filename);
int len;
while((len = in.read(buf)) > 0){
out.write(buf, 0, len);
}
in.close();
out.close();
} catch (IOException e) {
}
}
public static void LZ4Uncompress(String lz4file, String filename){
byte[] buf = new byte[2048];
try {
String outFilename = filename;
LZ4BlockInputStream in = new LZ4BlockInputStream(new FileInputStream(lz4file));
FileOutputStream out = new FileOutputStream(outFilename);
int len;
while((len = in.read(buf)) > 0){
out.write(buf, 0, len);
}
in.close();
out.close();
} catch (IOException e) {
}
}
Looking only at code, I would say you are going wrong here:
outputBuffer = compress(inputBuffer, decompressedLength);
out.write(outputBuffer, 0, noBytesRead);
You have already trimmed outputBuffer in compress. Try:
out.write(outputBuffer);

copying files in android with input/output stream: the good and the bad way

i have made this two routines to copy files using inputstream and outpustream.
they are quite the same however the second one rise ArrayIndexOutOfBoundsException while the first one works flawlessly and i don't know why:
public void CopyStream(long size, InputStream is, OutputStream os) {
final int buffer_size = 4096;
byte[] bytes = new byte[buffer_size];
try {
int count,prog=0;
while ((count = is.read(bytes)) != -1) {
os.write(bytes, 0, count); //write buffer
prog = prog + count;
publishProgress(((long) prog) * 100 / size);
}
os.flush();
is.close();
os.close();
} catch (Exception ex) {
Log.e(TAG,"CS "+ex);
}
}
as you may guess the routine is called inside an AsyncTask, therefore the publishProgresss
public void CopyStream(long size, InputStream is, OutputStream os) {
final int buffer_size = 4096;
try {
byte[] bytes = new byte[buffer_size];
for (int count=0,prog=0;count!=-1;) {
count = is.read(bytes);
os.write(bytes, 0, count);
prog=prog+count;
publishProgress(((long) prog)*100/size);
}
os.flush();
is.close();
os.close();
} catch (Exception ex) {
Log.e(TAG,"CS "+ex);
}
}
Does anyone know why the while works but the for no ? what am i missing?
The problem lies in your for loop checking the condition after the first run through. Basically the error occurs when it has read fine the last loop but on the next loop the is.read call returns -1. Afterwards you try to call os.write(bytes,0,-1); -1 is an invalid index. The solution would be:
public void CopyStream(long size, InputStream is, OutputStream os) {
final int buffer_size = 4096;
try {
byte[] bytes = new byte[buffer_size];
for (int count=0,prog=0;count!=-1;) {
count = is.read(bytes);
if(count != -1) {
os.write(bytes, 0, count);
prog=prog+count;
publishProgress(((long) prog)*100/size);
}
}
os.flush();
is.close();
os.close();
} catch (Exception ex) {
Log.e(TAG,"CS "+ex);
}
}
But it is much more readable as the while loop so I would stick with that. For loops should be used either when you know the quantity of times to loop or as a for each where you loop through each individual item of a collection.
For loop stop condition is checked before calling is.read(). This allow situation when you try to read bytes, get result in -1 value and try to continue executing for loop code. While stops immediately after is.read() returns -1
Try following:
int count = is.read(bytes);
for (prog=0;count!=-1;) {
os.write(bytes, 0, count);
prog=prog+count;
publishProgress(((long) prog)*100/size);
count = is.read(bytes);
}
private static final int BASE_BUFFER_SIZE = 4096;
public static void copyFile(InputStream inputStream, OutputStream outputStream)
throws IOException {
byte[] bytes = new byte[BASE_BUFFER_SIZE];
int count;
while ((count = inputStream.read(bytes)) != -1){
outputStream.write(bytes, 0, count);
}
close(inputStream);
close(outputStream);
}
public static void close(#Nullable OutputStream stream) {
if (stream != null) {
try {
stream.flush();
} catch (IOException ignored) {
}
try {
stream.close();
} catch (IOException ignored) {
}
}
}
public static void close(#Nullable InputStream stream) {
if (stream != null) {
try {
stream.close();
} catch (IOException ignored) {
}
}
}

Packet loss in socket programming java

I am trying to send a file from client to server. Below is the code i have tried. But at times, there is a packet loss during the transfer. I am not sure where i am wrong.
SERVER SIDE CODE:
public static void ReadAndWrite(byte[] aByte, Socket clientSocket,
InputStream inputStream, String fileOutput)
throws FileNotFoundException, IOException {
int bytesRead;
FileOutputStream fileOutputStream = null;
BufferedOutputStream bufferedOutputStream = null;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try
{
fileOutputStream = new FileOutputStream( fileOutput );
bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
bytesRead = inputStream.read(aByte, 0, aByte.length);
System.out.println("The length is "+bytesRead);
int count = 0;
do {
count++;
byteArrayOutputStream.write(aByte);
bytesRead = inputStream.read(aByte);
} while (bytesRead != -1);
System.out.println("The count is "+count);
System.out.println("The length is "+byteArrayOutputStream.size());
bufferedOutputStream.write(byteArrayOutputStream.toByteArray());
bufferedOutputStream.flush();
bufferedOutputStream.close();
clientSocket.close();
}
catch(Exception ex)
{
Logger.writeLog(ex,Listen.class.getName(), LogType.EXCEPTION);
throw ex;
}
CLIENT SIDE CODE:
public void readByteArrayAndWriteToClientSocket(
Socket connectionSocket, BufferedOutputStream outToClient, String fileToSend ) throws Exception
{
try{
if (outToClient != null)
{
File myFile = new File(fileToSend);
System.out.println(myFile.length());
byte[] byteArray = new byte[(int) myFile.length()];
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream(myFile);
} catch (IOException ex) {
Logger.writeLog(ex, FileUtility.class.getName(), LogType.EXCEPTION);
throw ex;
}
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
try {
bufferedInputStream.read(byteArray, 0, byteArray.length);
outToClient.write(byteArray, 0, byteArray.length);
outToClient.flush();
outToClient.close();
connectionSocket.close();
return;
} catch (IOException ex) {
Logger.writeLog(ex, FileUtility.class.getName(), LogType.EXCEPTION);
throw ex;
}
}
}catch (Exception e) {
Logger.writeLog(e, getClass().getName(), LogType.EXCEPTION);
throw e;
}
}
There is no 'packet loss', just bugs in your code.
The canonical way to copy a stream in Java is as follows:
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
If you know the number of bytes in advance and the sender must keep the connection open after the transfer, it becomes:
while (total < expected && (count = in.read(buffer, 0, expected-total > buffer.length ? buffer.length : (int)(expected-total))) > 0)
{
out.write(buffer, 0, count);
total += count;
}
Forget all the ByteArrayInput/OutputStreams and the extra copies. Just read from the file and send to the socket, or read from the socket and write to the file.
The sockets read method will return when its has obtained all the bytes you asked for, OR, when it stops receiving data from the network.
As transmission is often interrupted in any real network you need to keep issuing read calls until you have the number of bytes you want.
You need code something like this:
char [] buffer = new char[1024];
int expect = 1000;
int sofar = 0;
int chars_read;
try
{
while((chars_read = from_server.read(buffer[sofar])) != -1)
{
sofar = sofar + chars_read;
if (sofar >= expected) break;
}
}
catch(IOException e)
{
to_user.println(e);
}

how to add ProgressMonitorInputStream to ftp upload?

Can anybody see what is wrong with this code. it does not show up progress-bar but uploades all the files.
I did checkout sun tutorial and swingworkers also but i couldn't fix it yet.
private static boolean putFile(String m_sLocalFile, FtpClient m_client) {
boolean success = false;
int BUFFER_SIZE = 10240;
if (m_sLocalFile.length() == 0) {
System.out.println("Please enter file name");
}
byte[] buffer = new byte[BUFFER_SIZE];
try {
File f = new File(m_sLocalFile);
int size = (int) f.length();
System.out.println("File " + m_sLocalFile + ": " + size + " bytes");
System.out.println(size);
FileInputStream in = new FileInputStream(m_sLocalFile);
//test
InputStream inputStream = new BufferedInputStream(
new ProgressMonitorInputStream(null,"Uploading " + f.getName(),in));
//test
OutputStream out = m_client.put(f.getName());
int counter = 0;
while (true) {
int bytes = inputStream.read(buffer); //in
if (bytes < 0)
break;
out.write(buffer, 0, bytes);
counter += bytes;
System.out.println(counter);
}
out.close();
in.close();
inputStream.close();
success =true;
} catch (Exception ex) {
System.out.println("Error: " + ex.toString());
}
return true;
}
I think your code is fine.
Maybe the task isn't taking long enough for the progress bar to be needed?
Here's a modified version of your code which reads from a local file and writes to another local file.
I have also added a delay to the write so that it gives the progress bar time to kick in.
This works fine on my system with a sample 12MB PDF file, and shows the progress bar.
If you have a smaller file then just increase the sleep from 5 milliseconds to 100 or something - you would need to experiment.
And I didn't even know that the ProgressMonitorInputStream class existed, so I've learnt something myself ;].
/**
* main
*/
public static void main(String[] args) {
try {
System.out.println("start");
final String inf = "d:/testfile.pdf";
final String outf = "d:/testfile.tmp.pdf";
final FileOutputStream out = new FileOutputStream(outf) {
#Override
public void write(byte[] b, int off, int len) throws IOException {
super.write(b, off, len);
try {
// We delay the write by a few millis to give the progress bar time to kick in
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
putFile(inf, out);
System.out.println("end");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
private static boolean putFile(String m_sLocalFile, OutputStream out /*FtpClient m_client*/) {
boolean success = false;
int BUFFER_SIZE = 10240;
if (m_sLocalFile.length() == 0) {
System.out.println("Please enter file name");
}
byte[] buffer = new byte[BUFFER_SIZE];
try {
File f = new File(m_sLocalFile);
int size = (int) f.length();
System.out.println("File " + m_sLocalFile + ": " + size + " bytes");
System.out.println(size);
FileInputStream in = new FileInputStream(m_sLocalFile);
//test
InputStream inputStream = new BufferedInputStream(
new ProgressMonitorInputStream(null,"Uploading " + f.getName(),in));
//test
//OutputStream out = m_client.put(f.getName());
int counter = 0;
while (true) {
int bytes = inputStream.read(buffer); //in
if (bytes < 0)
break;
out.write(buffer, 0, bytes);
counter += bytes;
System.out.println(counter);
}
out.close();
in.close();
inputStream.close();
success =true;
} catch (Exception ex) {
System.out.println("Error: " + ex.toString());
}
return true;
}

Categories