0

我正在尝试通过套接字发送多个文件。我写的发送者和接收者函数如下所示。 发件人

public void sendFileX() throws IOException {
    DataOutputStream dos = new DataOutputStream(
            connection.getOutputStream());
    //send file number
    dos.writeInt(filesToSend.length);
    dos.flush();
    //send file names
    for (int i = 0; i < filesToSend.length; i++) {
        dos.writeUTF(filesToSend[i].getName());
    }
    dos.flush();
    //send file sizes
    for (int i = 0; i < filesToSend.length; i++) {
        File myFile = new File("" + filesToSend[i] + "");
        dos.writeLong(myFile.length());
    }
    dos.flush();
    // send the file
    os = connection.getOutputStream();
    for (int i = 0; i < filesToSend.length; i++) {
        File myFile = new File("" + filesToSend[i] + "");
        byte[] mybytearray = new byte[(int) myFile.length()];

        fis = new FileInputStream(myFile);
        bis = new BufferedInputStream(fis);
        bis.read(mybytearray, 0, mybytearray.length);

        os.write(mybytearray, 0, mybytearray.length);
    }
    os.flush();
    os.close();
    bis.close();
}

接收方是: Receiver

private void recieveFileY() throws IOException
{
    DataInputStream dis = new DataInputStream(connection.getInputStream());
    //receive file number
    int len = dis.readInt();

    //receive file names
    fileNames = new String[len];
    for(int i = 0; i < len; i++)
    {
        fileNames[i] = dis.readUTF();
    }
    //receive file sizes
    fileSizes = new long[len];
    for(int i = 0; i < len; i++)
    {
        fileSizes[i] = dis.readLong();
    }

    for(int i = 0; i <len; i++)
    {
        System.out.println(fileNames[i]+", size: "+fileSizes[i]);
    }
    //receive files
    is = connection.getInputStream();
    BufferedReader br = new BufferedReader(new InputStreamReader(is));
    for(int i = 0; i < len; i++)
    {
        String fileSaveLocation = "c:/"+fileNames[i];
        fos = new FileOutputStream(fileSaveLocation);
        bos = new BufferedOutputStream(fos);
        byte[] bytesToRead = new byte[(int) fileSizes[i]];
        is.read(bytesToRead, 0, bytesToRead.length);
        bos.write(bytesToRead);

}

对于此接收器,我正在获取所有文件,但某些文件缺少数据,因为 is.read() 可能无法读取完整数据。但是如果我使用这个接收器,我应该得到整个文件。 接收器2

private void recieveFileX() throws IOException
{
    DataInputStream dis = new DataInputStream(connection.getInputStream());
    //receive file number
    int len = dis.readInt();

    //receive file names
    fileNames = new String[len];
    for(int i = 0; i < len; i++)
    {
        fileNames[i] = dis.readUTF();
    }
    //receive file sizes
    fileSizes = new long[len];
    for(int i = 0; i < len; i++)
    {
        fileSizes[i] = dis.readLong();
    }

    for(int i = 0; i <len; i++)
    {
        System.out.println(fileNames[i]+", size: "+fileSizes[i]);
    }
    //receive files
    is = connection.getInputStream();
    BufferedReader br = new BufferedReader(new InputStreamReader(is));
    for(int i = 0; i < len; i++)
    {
        String fileSaveLocation = "c:/"+fileNames[i];
        fos = new FileOutputStream(fileSaveLocation);
        bos = new BufferedOutputStream(fos);
        byte[] bytesToRead = new byte[(int) fileSizes[i]];

        bytesRead = is.read(bytesToRead, 0, bytesToRead.length);
        current = bytesRead;

        do {
            bytesRead = is.read(bytesToRead, current,
                    (bytesToRead.length - current));
            if (bytesRead >= 0)
                current += bytesRead;
            System.out.println("I am in do while loop");
        } while (bytesRead > -1);

        bos.write(bytesToRead);
        System.out.println("Saved " + fileNames[i]);
    }
    bos.flush();
    bos.close();
    is.close();
}

但这里的问题是,在读完一个文件后,inputStream 中有更多数据可用,因此 is.read() 不会将 -1 返回到 bytesRead,我陷入了无限循环。 请任何人帮助我。提前致谢。

终于我的代码奏效了

private void recieveFileX() throws IOException
{
    DataInputStream dis = new DataInputStream(connection.getInputStream());
    //receive file number
    int len = dis.readInt();

    //receive file names
    fileNames = new String[len];
    for(int i = 0; i < len; i++)
    {
        fileNames[i] = dis.readUTF();
    }
    //receive file sizes
    fileSizes = new long[len];
    for(int i = 0; i < len; i++)
    {
        fileSizes[i] = dis.readLong();
    }

    for(int i = 0; i <len; i++)
    {
        System.out.println(fileNames[i]+", size: "+fileSizes[i]);
    }
    //receive files
    is = connection.getInputStream();
    BufferedReader br = new BufferedReader(new InputStreamReader(is));
    for(int i = 0; i < len; i++)
    {
        String fileSaveLocation = "c:/"+fileNames[i];
        fos = new FileOutputStream(fileSaveLocation);
        bos = new BufferedOutputStream(fos);
        byte[] bytesToRead = new byte[(int) fileSizes[i]];
        /*is.read(bytesToRead, 0, bytesToRead.length);
        bos.write(bytesToRead);
        bos.flush();
        int count;
        while ((count = is.read(bytesToRead)) > 0)
        {
            bos.write(bytesToRead, 0, count);
        }
        bytesRead = is.read(bytesToRead, 0, bytesToRead.length);
        current = bytesRead;

        do {
            bytesRead = is.read(bytesToRead, current,
                    (bytesToRead.length - current));
            if (bytesRead >= 0)
                current += bytesRead;
            System.out.println("I am in do while loop");
        } while (bytesRead > -1);*/
        while(true)
        {
            bytesRead = is.read(bytesToRead,current,(bytesToRead.length - current));
            System.out.println("BytesRead = " + bytesRead);
            if(bytesRead <=0)
            {
                System.out.println("loop breker 1 worked");
                break;
            }
            current += bytesRead;
            if(current == fileSizes[i])
            {
                System.out.println("loop breker 2 worked");
                break;
            }
            System.out.println("Current = " + current);
        }
        bos.write(bytesToRead);
        System.out.println("Saved " + fileNames[i]);
        current = 0;
    }
    bos.flush();
    bos.close();
    is.close();
}

谢谢大家帮助我。

4

1 回答 1

1

您正在使用两种不同的复制循环。在这个:

is.read(bytesToRead, 0, bytesToRead.length);

你完全忽略了返回值。它可能是 -1 表示文件结束,也可能是读取计数。所以你还假设它read()填充了缓冲区。没有指定这样做。你不需要两个不同的循环来做同样的事情。在两端使用相同的代码:

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

这适用于任何大于零的缓冲区大小。我通常使用 8192,但如果您愿意,可以使用更多。

如果要保持套接字打开以进行更多发送,则需要:

  • 在文件之前发送文件的长度,用DataOutputStream.writeLong()
  • 在接收器上读取它,用DataInputStream.readLong()
  • 修改复制循环以准确读取那么多字节:

    long runningTotal = 0;
    while (runningTotal < total && (count = in.read(buffer, 0, (int)Math.min(buffer.length, total-runningTotal)) > 0)
    {
        out.write(buffer, 0, count);
        runningTotal += count;
    }
    

E&OE

于 2014-08-06T10:39:54.440 回答