0

i'm trying to send some files from a server to some clients in android. i receive the file through a bufferedInputStream by read(byte[] array,int startIndex,int arraySize) method that returns the number of bytes it can read and -1 if there is no input to read. i receive the file in a loop and i must go out of the loop when my file finishes, but the read method is not returns -1 and just waiting for more input to read :/ so my code is blocking.... i tried to send the file size from the server and when receiving it,and subtract number reads byte from it every time i read a buffer, so when this number hits 0 means i received all file and should break the loop, BUT in some files it doesn't hit 0 as if some part of my file is not sent :| but when i do the same thing in the server side (subtract the sent part from the early file size) it always hit 0 .... SO my problem is how to know i read all file to break the reading loop :( similar question my question is differ from this link because i done the suggested answer but the remaining file size is NOT reach 0 in some files and i dont know why

here is my code for send the file in sever side:

public void sendFile(File file){
        BufferedOutputStream bos = null;
        BufferedInputStream bis = null;
        try {
            bis = new BufferedInputStream(new FileInputStream(file));
            bos = new BufferedOutputStream(outputStream);

            byte[] temp = new byte[2 * 1024];
            int length ;
            int fileSize=(int)file.length();
            Log.d("file size",Integer.toString(fileSize));
            //int sendSize =0;
            while (true){
                length = bis.read(temp,0,temp.length);

                if(length == -1) break;
                bos.write(temp,0,length);

                fileSize-=length;

                assert (fileSize >=0 );
                //if(fileSize==0)break;
            }
             // outputStream.write(-1);
            bos.flush();
            Log.d("File ", "Send finisheeed!");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e){
            e.printStackTrace();
        }finally {
            try {
                bis.close();
              //bos.close();

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

and here is the part of client code that receives the file :

     Log.d("File name is", fileName);
               // File outFile = new File("/storage/sdcard0/m2app" + fileName);
                //    outFile.createNewFile();
                    bos = new BufferedOutputStream(new FileOutputStream("/storage/sdcard0/m2app" + fileName));

                    byte[] temp = new byte[2 * 1024];
                    int length = 0;
                    while (true)
                    {
                        length = bis.read(temp,0,temp.length);
                        fileLength -= length;
                       // Log.d("read",Integer.toString(fileLength) );
                        if(length == -1 || fileLength == 0 ) {
                      //  if(temp[length-1] == -1){
                      //      bos.write(temp,0,length-1);
                      //      bos.flush();
                      //      Log.d("file","recived!!!!!!!!!!");
                            break;
                        }
                        if(fileLength < 4000 && bis.available() == 0)
                            break;

                        bos.write(temp,0,length);
                        bos.flush();
                        /*if(fileLength == 0){
                            Log.d("file","0 shod");
                            break;
                        }*/
                    }
                    while (fileLength > 0 )
                        fileLength-=bis.skip(fileLength);

                  //  inputStream.reset();
                    bos.close();
                    Log.d("File " , "Receiving finisheeeeeeeeeddddd!!!");
                    isFile = false;
Community
  • 1
  • 1
Meysam
  • 1
  • 3

1 Answers1

0

You need to close the output stream in the file sender for the input stream in the file receiver to get the EOF.

Using try-with-resources you can dramatically simplify the code:

public void sendFile(File file) {
    try(BufferedOutputStream bos = new BufferedOutputStream(outputStream);
        FileInputStream fis = new FileInputStream(file));
        BufferedInputStream bis = new BufferedInputStream(fis)) {
        byte[] temp = new byte[64 * 1024];
        int length ;
        int fileSize=(int)file.length();
        Log.d("file size",Integer.toString(fileSize));
        while ((bis.read(temp,0,temp.length) != -1){
            bos.write(temp,0,length);
        }
        Log.d("File ", "Send finished!");
    } catch (IOException e) {
        e.printStackTrace();
    }
}
Alain O'Dea
  • 21,033
  • 1
  • 58
  • 84
  • cause i need the stream later i can't close it. BTW i tried this but the file receiver stream still doesn't get EOF ;( – Meysam Nov 10 '15 at 22:00
  • You only need the stream later because you are relying on STDIN and STDOUT. This is very difficult to make work: it requires coming up with a custom protocol and handling the bufferring at the app-level not the method level. If you open new streams for each request this would not be an issue. I think you should switch from using STDIN/STDOUT to something like ServerSocket or ZeroMQ. – Alain O'Dea Nov 10 '15 at 22:07
  • what do u mean by STDIN/STDOUT? i am reading a file by a stream from file and writing to the sockets output stream and in client side i receive it in socket's input stream and write it to a file by another output stream... – Meysam Nov 10 '15 at 22:18
  • BTW i got 2 reader from main socket's input stream. a scanner and a buffered input reader – Meysam Nov 10 '15 at 22:20
  • 1
    That's not clear from your code. Try to post SSCCEs with your questions to avoid ambiguity. http://sscce.org/ – Alain O'Dea Nov 10 '15 at 22:21