Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java数据输入流长度_Java_Sockets - Fatal编程技术网

Java数据输入流长度

Java数据输入流长度,java,sockets,Java,Sockets,我正在为学校作业创建一个文件服务器应用程序。我目前拥有的是一个简单的客户端类,它通过TCP发送图像,还有一个服务器类,它接收图像并将其写入文件 这是我的客户代码 import java.io.*; import java.net.*; class Client { public static void main(String args[]) throws Exception { long start = System.currentTimeMillis();

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

这是我的客户代码

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");
    }
}
这是我的服务器代码

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();
    }
}
import java.io.*;
导入java.net。*;
类服务器{
公共静态void main(字符串args[])引发异常{
ServerSocket ServerSocket=新的ServerSocket(6789);
套接字连接Socket=serverSocket.accept();
DataInputStream dis=新的DataInputStream(connectionSocket.getInputStream());
byte[]receivedData=new byte[61500];//在发送文件之前添加一个“长度字段”。(注意,由于您将文件读取到内存,因此文件的最大大小可能为~2GB。)


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

  outToServer.writeInt(sendData.length);
接收时,首先读取长度并将其用作长度:

  int dataLength = dis.readInt()
  byte[] receivedData = new byte[dataLength];


更好的方法不是先将文件读入内存,而是直接从
FileInputStream
传输文件-然后可以传输更大的文件!

如果您知道文件的长度,使用readfull()比一次读取一个字节要有效得多

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

InputStream is = connectionSocket.getInputStream();

byte[] bytes = new byte[8192];
int len;
while((len = is.read(bytes)) > 0)
    fos.write(bytes, 0, len);
通过在读取时复制数据,可以避免将整个文件读入内存

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.copy()执行从一个流到另一个流的复制


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

我看不出在发送文件之前我在内存中读到了什么地方?它在哪里?我如何避免它?@David Weng:在你使用'@codymanix'时,它基本上是第一个示例的代码副本。有什么没有意义?