【问题标题】:how to transfer a file in network (socket programming(TCP) ) in android [duplicate]如何在android中的网络中传输文件(套接字编程(TCP))[重复]
【发布时间】:2015-11-10 21:45:43
【问题描述】:

我正在尝试将一些文件从服务器发送到 android 中的一些客户端。 我通过 read(byte[] array,int startIndex,int arraySize) 方法通过 bufferedInputStream 接收文件,该方法返回它可以读取的字节数,如果没有要读取的输入,则返回 -1。 我在循环中接收文件,当我的文件完成时我必须退出循环,但是读取方法不返回-1,只是等待更多输入来读取:/ 所以我的代码被阻塞了...... 我试图从服务器发送文件大小,并在接收它时,每次读取缓冲区时都会从中减去读取字节的数字,所以当这个数字达到 0 时意味着我收到了所有文件并且应该打破循环,但在某些文件中它没有达到 0,就好像我的文件的某些部分没有发送一样:|但是当我在服务器端做同样的事情时(从早期文件大小中减去发送的部分)它总是命中 0 .... 所以我的问题是如何知道我阅读了所有文件以打破阅读循环:( similar question 我的问题与此链接不同,因为我完成了建议的答案,但某些文件中剩余的文件大小未达到 0,我不知道为什么

这是我在服务器端发送文件的代码:

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();
            }
        }
    }

这是接收文件的客户端代码部分:

     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;

【问题讨论】:

  • @ejp 我的问题没有重复,我解释了原因...请删除您的重复标签:(
  • 上面的代码中没有任何类似于建议的答案。

标签: java android sockets stream


【解决方案1】:

您需要关闭文件发送方中的输出流,以便文件接收方中的输入流获取EOF。

使用 try-with-resources 可以显着简化代码:

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();
    }
}

【讨论】:

  • 因为我稍后需要流,我无法关闭它。顺便说一句,我试过了,但文件接收器流仍然没有得到 EOF ;(
  • 您以后只需要流,因为您依赖于 STDIN 和 STDOUT。这很难做到:它需要提出一个自定义协议并在应用程序级别而不是方法级别处理缓冲。如果您为每个请求打开新流,这将不是问题。我认为你应该从使用 STDIN/STDOUT 切换到 ServerSocket 或 ZeroMQ 之类的东西。
  • STDIN/STDOUT 是什么意思?我正在通过文件中的流读取文件并写入套接字输出流,在客户端我在套接字的输入流中接收它并通过另一个输出流将其写入文件...
  • 顺便说一句,我从主套接字的输入流中获得了 2 个阅读器。扫描仪和缓冲输入阅读器
  • 从您的代码中不清楚。尝试发布带有您的问题的 SSCCE,以避免歧义。 sscce.org
猜你喜欢
  • 1970-01-01
  • 2013-04-24
  • 2012-07-12
  • 2021-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-11
相关资源
最近更新 更多