这与我之前的问题-DataInputStream提供java.io.EOFException有关

在该客户端-服务器应用程序中,有一种方法可以检索从服务器发送的文件并将其保存到文件中。

Client.java-

 public void receiveFile(InputStream is, String fileName) throws Exception {
        int filesize = 6022386;
        int bytesRead;
        int current = 0;
        byte[] mybytearray = new byte[filesize];

        System.out.println("Receving File!");
        FileOutputStream fos = new FileOutputStream("RECEIVED_"+fileName);
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        bytesRead = is.read(mybytearray, 0, mybytearray.length);
        current = bytesRead; 
        System.out.println(bytesRead);
        do {
            bytesRead = is.read(mybytearray, current,
                    (mybytearray.length - current));
            System.out.println(bytesRead);
            if (bytesRead >= 0)
                current += bytesRead;
        } while (bytesRead > -1);
        System.out.println("Loop done");
        bos.write(mybytearray, 0, current);
        bos.flush();
        bos.close();
    }
}

Server.Java

public void sendFile(OutputStream os, String fileName) throws Exception {
    File myFile = new File(fileName);
    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 File!");
    os.write(mybytearray, 0, mybytearray.length);
    os.flush();
    bis.close();
}

如您所见,客户端的receiveFile方法中存在多个receiveFile 这是我收到的输出。

在此处输入图片说明

问题在于该方法无法完成其任务,并且永远不会到达System.out.println("Loop done");

有什么问题?

===============>>#1 票数:1

稍后我将介绍循环错误。

源头有一个小字节太多:

public void sendFile(OutputStream os, String fileName) throws Exception {
    File myFile = new File(fileName);
    if (myFile.length() > Integer.MAX_VALUE) {
        throw new IllegalStateException();
    }

    byte[] mybytearray = Files.readAllBytes(myFile.toPath());

要么

    byte[] mybytearray = new byte[(int) myFile.length()]; // No +1.
    // BufferedInputStream here not needed.
    try (BufferedInputStream bis = new BufferedInputStream(
            new FileInputStream(myFile))) {
        bis.read(mybytearray);
    } // Always closed.

接着

    System.out.println("Sending File!");
    os.write(mybytearray);
    os.flush();
}

另外,我添加了java 7 Files.readAllBytes 使用Files.copy甚至可能更简单。

我只是看到已经提到了主要错误。 基本上有一个误解:您可能会完整读取一个字节数组。 它将阻塞直到读完结尾。 如果要读取的内容更少(达到“文件尾”),则返回字节数。 因此,出于所有目的,您可能会完整阅读它。

人们经常看到类似的代码来读取固定大小(为2的幂)的块(例如4096)重复并写入输出流。

同样,java 7 Files简化了所有操作:

    Files.copy(is, Paths.get("RECEIVED_" + fileName));

简而言之:

public void receiveFile(InputStream is, String fileName) throws Exception {
    Files.copy(is, Paths.get("RECEIVED_" + fileName),
        StandardCopyOption.REPLACE_EXISTING);
}

public void sendFile(OutputStream os, String fileName) throws Exception {
    Files.copy(Paths.get(fileName), os);
}

===============>>#2 票数:0

您可能希望您的条件显示为:

} while (bytesRead > -1 && current < mybytearray.length);
//                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

目前,当您读取了整个文件时,您的read语句将继续读取零字节( mybytearray.length - current ),该字节成功并返回零,因此循环永远不会终止。

===============>>#3 票数:0

不保持附加到输入缓冲区会更简单

public void receiveFile(InputStream istream, String fileName) throws Exception {
  System.err.println("Receving File!");
  try (BufferedOutputStream ostream = new BufferedOutputStream(
      new FileOutputStream("RECEIVED_" + fileName))) {
    int bytesRead;
    byte[] mybytearray = new byte[1024];

    do { 
      bytesRead = istream.read(mybytearray);
      if (bytesRead > 0) {
        ostream.write(mybytearray, 0, bytesRead);
      }
    } while (bytesRead != -1);
    System.err.println("Loop done");
    ostream.flush();
  }
}

如果可以使用Guava,则可以使用ByteStreams.copy(java.io.InputStream, java.io.OutputStream)Javadoc

  ask by ChamingaD translate from so

未解决问题?本站智能推荐:

1回复

无法使用InputStream读取API读取所有字节?

我在读取Java套接字中的图像字节时遇到问题。 我的iOS客户端正在此处发送图像,它需要读取总字节并将其作为图像存储在服务器端。 当我通过iOS模拟器进行测试时,它工作得很好 。 因为,如果我在模拟器中进行测试,它将发送最多46577字节的图像。 它会非常快速且正确地读取所有内容。 如
3回复

如何读取Server Socket JAVA中的所有Inputstream

我在我的一个项目中使用Java.net。 我写了一个从客户端获取inputStream的App Server。 但有时我的(缓冲)InputStream无法获取客户端发送到我的服务器的所有OutputStream。 我怎么能写一个等待或类似的东西,我的InputStream获取客户端的所有
2回复

将字符串和文件发送到InputStream

我正在尝试发送一个字符串,该字符串是文件名,然后将文件本身发送到服务器。 服务器正在接收该字符串并将其用于创建文件。 但是,服务器实际上没有任何数据写入文件。 在将Writer的文件名(带有硬编码的文件名)添加到服务器和客户端之前,我已经开始进行文件传输了,但是现在我无法同时使它们同时
2回复

使用ServerSocket和HTML客户端上传文件。 卡在InputStream.read()

为了理解套接字编程的概念,我创建了服务器和客户端。 客户端将发送文件,服务器应将其保存在某个位置。 (即文件上传)。 服务器: Java客户端如下: 这样可以正常工作,并将上传的文件写入我的项目根文件夹。 现在,我将客户端更改为HTML页面。 HTML:
3回复

无法在服务器套接字文件传输中获取输入流

我已经开发了一个屏幕,可以从服务器下载文件。 当我单击下载按钮一次时,整个概念工作正常。 但是当我第二次单击下载按钮时,我发现代码在获取输入流时暂停。(我使用显示的sysouts遵循了它。) 下面显示的是两个不同文件中的两个单独的代码片段。 TCPClient具有服务器套接字编码,而
2回复

读取输入流时出错:软件导致连接中止'在java服务器中

我基本上试图在Android设备上托管服务器。 客户端设备通过TCP连接到服务器并发送请求。 服务器执行客户端请求的操作,然后将数据写回套接字。 连接未被服务器终止,并且将通过套接字连续读取请求并回复。 注意:每个请求消息的前4个字节包含实际消息/请求的长度。 parseXml
2回复

InputStream缓冲数据

我的程序使用SSL ServerSocket等待传入连接并接收数据。 客户端连接到服务器,并向Socket的OutputStream写入10字节的块序列。 在每个10字节的块之后,对OutputStream进行flush()编译,因为该块应尽快到达服务器(注意:此处使用WIFI)。 然
2回复

ServerSocket可以在从客户端读取之前写入客户端吗?

ServerSocket接受到客户端的连接后,ServerSocket可以在客户端发送消息之前开始向客户端写入数据吗? 当我尝试首先从ServerSocket向客户端写入数据时,客户端将永远阻止读取它的操作。 但是,如果让客户端首先向服务器发送消息,则它们之间的I / O流可以正常工作。
1回复

Windows块上的Socket InputStream并交换查询

我正在编写一个简单的ServerSocket程序,并通过两个浏览器选项卡通过url连接到它: http : //127.0.0.1 : 8080/Q1,并在暂停10秒钟后http://127.0.0.1:8080/Q2 。 我的问题是,在带有java10的ubuntu18机器上,它可以快速
2回复

Socket Inputstream在流结束时不返回-1

这是发生问题的代码片段: 有人能帮我吗?