首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java DataInputStream长度

Java DataInputStream长度
EN

Stack Overflow用户
提问于 2011-05-10 16:34:05
回答 2查看 13.2K关注 0票数 5

我正在为学校作业创建一个文件服务器应用程序。我目前拥有的是一个通过TCP发送图像的简单Client类和一个接收图像并将其写入文件的Server类。

这是我的客户端代码

代码语言:javascript
复制
import java.io.*;
import java.net.*;

class Client {
    public static void main(String args[]) throws Exception {
        long start = System.currentTimeMillis();
        Socket clientSocket = new Socket("127.0.0.1", 6789);
        DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());

        File file = new File("hot.jpg");
        FileInputStream fin = new FileInputStream(file);
        byte sendData[] = new byte[(int)file.length()];
        fin.read(sendData);

        outToServer.write(sendData, 0, sendData.length);
        clientSocket.close();

        long end = System.currentTimeMillis();
        System.out.println("Took " + (end - start) + "ms");
    }
}

这是我的服务器代码。

代码语言:javascript
复制
import java.io.*;
import java.net.*;

class Server {
    public static void main(String args[]) throws Exception {
        ServerSocket serverSocket = new ServerSocket(6789);
        Socket connectionSocket = serverSocket.accept();
        DataInputStream dis = new DataInputStream(connectionSocket.getInputStream());

        byte[] receivedData = new byte[61500]; // <- THIS NUMBER

        for(int i = 0; i < receivedData.length; i++)
            receivedData[i] = dis.readByte();

        connectionSocket.close();
        serverSocket.close();

        FileOutputStream fos = new FileOutputStream("received.jpg");
        fos.write(receivedData);
        fos.close();
    }
}

我的问题是如何获得正在发送的文件的大小。如果你检查一下Server代码,你会发现我已经硬编码了这个数字,也就是61500。如何动态检索此号码?

或者,我做错了吗?另一种解决方案是什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-05-10 16:37:33

在发送文件之前添加一个“长度字段”。(请注意,由于您将文件读取到内存中,因此文件的最大大小可以为~2 2GB。)

在发送文件之前,写入文件的长度:

代码语言:javascript
复制
  outToServer.writeInt(sendData.length);

在接收时,先读取长度,并将其用作长度:

代码语言:javascript
复制
  int dataLength = dis.readInt()
  byte[] receivedData = new byte[dataLength];

一个更好的方法是先将文件读取到内存中,而不是,而是直接从FileInputStream传输文件-这样您就可以传输更大的文件!

票数 7
EN

Stack Overflow用户

发布于 2011-05-10 16:45:11

如果您知道长度,那么使用readFully()比一次读取一个字节要高效得多。

在这种情况下,您不需要知道长度,您可以编写循环来读取/写入尽可能多的数据。

代码语言:javascript
复制
InputStream is = connectionSocket.getInputStream();

byte[] bytes = new byte[8192];
int len;
while((len = is.read(bytes)) > 0)
    fos.write(bytes, 0, len);

通过在读取数据时复制数据,可以避免将整个文件读取到内存中。

代码语言:javascript
复制
FileInputStream fis = new FileInputStream(filename);
OutputStream os = socket.getOutputStream();

byte[] bytes = new byte[8192];
int len;
while((len = fis.read(bytes)) > 0)
    os.write(bytes, 0, len);

如果愿意,您可以使用Apache IOUtils.copy()执行从一个流到另一个流的复制。

这种方法的优点是文件可以是任何大小(大于2 GB)。使用数组的限制为2 GB (并且使用更多的内存)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5947365

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档