java - 读取输入流并写入文件

标签 java serversocket

这与我之前的问题有关 - DataInputStream giving 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();
    }
}

服务器.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 方法中有几个搁浅的地方。这是我收到的输出。

enter image description here

问题是该方法没有完成其任务并且从未到达System.out.println("Loop done");

有什么问题吗?

最佳答案

稍后我会讨论循环错误。

源代码中多了一个字节:

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 的幂) block (例如 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);
}

关于java - 读取输入流并写入文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23184166/

相关文章:

java - 如何制作按钮 Swing 进行大处理

在windows 7中创建Java jdk1.8文件

server-side - 暗星计划(红矮星)在哪里

java ssl套接字服务器握手中止

java - 在Java中,是否有一种方法可以通过连接到serverSocket的套接字来获取服务器对象?

java - 为什么我的服务器跳过 if 语句并转到 else 部分(重试)?

java - 为什么 Volley 返回空值?

Java 集合缩减为 Map

java - 我能以某种方式解决 ResourceIterator 惰性的这一特定方面吗?

multithreading - Netty ByteToMessageDecoder 不能@sharable