【问题标题】:image receiving at android with no content- socket programming在没有内容套接字编程的情况下在 android 上接收图像
【发布时间】:2013-09-03 18:36:37
【问题描述】:

我创建了一个应用程序,它通过套接字编程将图像从服务器(桌面)发送到客户端(android)............问题是我在客户端获取文件(android),但没有内容。

谁能告诉我是什么问题

客户端(Android)

    DataInputStream dis=new DataInputStream(socket.getInputStream());
    receiveFile(dis); // call method receiveFile()

public Bitmap receiveFile(InputStream is) throws Exception{
                 String baseDir =     Environment.getExternalStorageDirectory().getAbsolutePath();
                    String fileName = "myFile.png";
                    String imageInSD = baseDir + File.separator + fileName;
                    System.out.println("FILE----------------->"+imageInSD);
                  int filesize=6022386;
                  int bytesRead;
                  int current = 0;
                  byte [] data  = new byte [filesize];

                    FileOutputStream fos = new FileOutputStream(imageInSD);
                    BufferedOutputStream bos = new BufferedOutputStream(fos);
                    bytesRead = is.read(data,0,data.length);
                    current = bytesRead;
                    int index = 0;
                    while (index < filesize)
                    {
                        bytesRead = is.read(data, index, filesize - index);
                        if (bytesRead < 0)
                        {
                            throw new IOException("Insufficient data in stream");
                        }
                        index += filesize;
                    }

                    bos.write(data, 0 , current);  
                    bos.flush();
                    bos.close();
                    return null;
              }

服务器(桌面)

send(socket.getOutputStream()); // call method send()


    public void send(OutputStream os) throws Exception{
      // sendfile
      File myFile = new File ("C:/div.png");
      System.out.println("the file is read");
      byte [] mybytearray  = new byte [(int)myFile.length()+1];
      FileInputStream fis = new FileInputStream(myFile);
      BufferedInputStream bis = new BufferedInputStream(fis);
      bis.read(mybytearray,0,mybytearray.length);
      System.out.println("Sending...");
      os.write(mybytearray,0,mybytearray.length);
      os.flush();
      }

【问题讨论】:

  • 只是滚动浏览,但您在is.read(data,0,data.length) 行中读取,但不使用其中读取的字节数(不应该进入index)?
  • 问题可能出在index +=filesize; 应该是index +=bytesread; 并且还要考虑之前的评论。

标签: java android sockets


【解决方案1】:

Java中复制流的正确方法如下:

while ((count = in.read(buffer)) > 0)
{
   out.write(buffer, 0, count);
}

目前你的代码:

  1. 假设read() 填满了缓冲区。 Javadoc 中没有任何规定。
  2. 忽略read()返回的结果,除了是无价的计数外,还可能是-1,表示EOS。
  3. 浪费地分配了整个文件大小的缓冲区。
  4. 假设文件大小适合int
  5. 依靠接收器神奇地知道传入文件的大小。

上面的代码没有做任何这些假设,并且适用于从 1 开始的任何缓冲区大小。

【讨论】:

    【解决方案2】:

    查看您的代码,我看到您希望接收一个文件并将其保存到外部存储并返回该文件的位图。这就是我猜你想要做的,但你的代码并没有这样做。如果您愿意,可以使用以下代码来完成该任务。首先,服务器发送 4 个字节指示文件的大小,然后是文件的内容;客户端读取这 4 个字节,然后读取整个文件,并将其保存到磁盘它读取的每个块。最后,它将接收到的文件转换为位图并返回。

    客户端代码:

    public Bitmap receiveFile(InputStream is) throws Exception
        {
            String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath();
            String fileName = "myFile.png";
            String imageInSD = baseDir + File.separator + fileName;
            System.out.println("FILE----------------->" + imageInSD);
    
            // read first 4 bytes containing the file size
            byte[] bSize = new byte[4];
            is.read(bSize, 0, 4);
    
            int filesize;
            filesize = (int) (bSize[0] & 0xff) << 24 | 
                       (int) (bSize[1] & 0xff) << 16 | 
                       (int) (bSize[2] & 0xff) << 8 | 
                       (int) (bSize[3] & 0xff);
    
            int bytesRead;
            // You may but don't have to read the whole file in memory
            // 8k buffer is good enough
            byte[] data = new byte[8 * 1024];
            int bToRead;
            FileOutputStream fos = new FileOutputStream(imageInSD);
            BufferedOutputStream bos = new BufferedOutputStream(fos);
            while (filesize > 0)
            {
                // EDIT: just in case there is more data in the stream. 
                if (filesize > data.length) bToRead=data.length;
                else bToRead=filesize;
                bytesRead = is.read(data, 0, bToRead);
                if (bytesRead > 0)
                {
                    bos.write(data, 0, bytesRead);
                    filesize -= bytesRead;
                }
            }
            bos.close();
            // I guess you want to return the received image as a Bitmap
            Bitmap bmp = null;
            FileInputStream fis = new FileInputStream(imageInSD);
            try
            {
                bmp = BitmapFactory.decodeStream(fis);
            }
            catch (Exception e)
            {
                // in case of an error set it to null
                bmp = null;
            }
            finally
            {
                fis.close();
            }
            return bmp;
        }
    

    服务器代码:

    public void send(OutputStream os) throws Exception
    {
        // sendfile
        File myFile = new File("C:/div.png");
        System.out.println("the file is read");
        int fSize = (int) myFile.length();
        byte[] bSize = new byte[4];
        bSize[0] = (byte) ((fSize & 0xff000000) >> 24);
        bSize[1] = (byte) ((fSize & 0x00ff0000) >> 16);
        bSize[2] = (byte) ((fSize & 0x0000ff00) >> 8);
        bSize[3] = (byte) (fSize & 0x000000ff);
    
        // send 4 bytes containing the filesize
        os.write(bSize, 0, 4);
    
        byte[] mybytearray = new byte[(int) fSize];
        FileInputStream fis = new FileInputStream(myFile);
        BufferedInputStream bis = new BufferedInputStream(fis);
        int bRead = bis.read(mybytearray, 0, mybytearray.length);
        System.out.println("Sending...");
        os.write(mybytearray, 0, bRead);
        os.flush();
        bis.close();
    }
    

    【讨论】:

    • 此代码不起作用。您需要限制读取长度,以便您永远不会超过filesize。此外,所有位移都应使用DataOutputStream.writeLong()DataInputStream.readLong().
    猜你喜欢
    • 1970-01-01
    • 2016-01-25
    • 1970-01-01
    • 2012-05-07
    • 2016-05-14
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 2020-01-10
    相关资源
    最近更新 更多