首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java通过FIO读取文件

Java通过FIO读取文件
EN

Stack Overflow用户
提问于 2012-03-07 08:04:50
回答 2查看 640关注 0票数 1

我正在制作一个TFTP应用程序。根据RFC协议,所有数据必须以最大大小为512字节的块的形式发送。因此每个分组可以是<= 512字节。

奇怪的是,对于UDP协议,每次高达3mb的传输都没有大的损失。唯一可能发生的损失是当文件的最后一个块被读取时小于512个字节。

代码语言:javascript
复制
private void sendData() throws Exception
{
    DatagramPacket data = new DatagramPacket(outgoingData, outgoingData.length, clientAddress, clientPort);
    InputStream fis = new FileInputStream(responseData);

    int a;
    while((a = fis.read(outgoingData,0,512)) != -1)
    {
        serverSocket.send(data);
        Thread.sleep(5);
    }
}

由于这是一个关于读取文件的问题,我如何修复文件末尾的丢失以及无法读取小于512的文件的问题

客户端:

代码语言:javascript
复制
private void receiveData() throws Exception
{
    DatagramPacket receiveData = new DatagramPacket(incomingData, incomingData.length);
    OutputStream fos = new FileOutputStream(new File("1"+data));
    while(true)
    {
        clientSocket.receive(receiveData);
        if(receiveData.getLength() == 512)
        {
            fos.write(incomingData);xx
        } else {
            fos.write(incomingData);
            fos.close();
            break;
        }
    }
    clientSocket.close();
}
EN

回答 2

Stack Overflow用户

发布于 2012-03-07 08:10:53

您的数据包(data)具有固定长度的outgoingData.length (512?)现在就来。因此,当您调用serverSocket.send(data)时,它会发送outgoingData数组中的所有数据。

问题是fis.read(outgoingData, 0, 512)有时读取的数据少于512字节。这很可能发生在文件输入流的末尾,此时根本没有那么多数据可供读取。但它也可能发生得更早(在实践中不太可能,但您仍然应该检查以确保安全)。

您已经在a中存储了实际读取的字节数。只需将这个数字传递给setLength,这样DatagramSocket就会知道只发送这么多数据。

这应该能起到作用:

代码语言:javascript
复制
private void sendData() throws Exception
{
    DatagramPacket data = new DatagramPacket(outgoingData, outgoingData.length, clientAddress, clientPort);
    InputStream fis = new FileInputStream(responseData);

    int a;
    while((a = fis.read(outgoingData,0,512)) != -1)
    {
        data.setLength(a);
        // or this
        //data = new DatagramPacket(outgoingData, a, clientAddress, clientPort);

        serverSocket.send(data);
        Thread.sleep(5);
    }
}

接收:

代码语言:javascript
复制
private void receiveData() throws Exception {
    DatagramPacket receiveData = new DatagramPacket(new byte[512], 512);
    OutputStream fos = new FileOutputStream(new File("1"+data));
    while (true) {
        clientSocket.receive(receiveData);
        if (receiveData.getLength() == 512) {
            fos.write(receiveData.getData());
        } else {
            fos.write(receiveData.getData(), receiveData.getOffset(), receiveData.getLength());
            break;
        }
    }
    fos.close();
    clientSocket.close();
}
票数 1
EN

Stack Overflow用户

发布于 2012-03-07 08:23:35

代码语言:javascript
复制
    private void sendData() throws Exception
{
    DatagramPacket data = new DatagramPacket(outgoingData, outgoingData.length, clientAddress, clientPort);
    InputStream fis = new FileInputStream(responseData);

    int a;
    while((a = fis.read(outgoingData,0,512)) != -1)
    {
        data.setLength(a); //'a' is the number of bytes read setLength(int) lets you set the length of bytes you want to sent
        serverSocket.send(data);
        Thread.sleep(5);
    }
}

setLength(int) Method DatagramPacket现在在接收端,你可以这样做:

代码语言:javascript
复制
byte[]buffer = new byte[512];
DatagramPacket packet = new DatagramPacket(buffer,buffer.length);
while(socket.isBound() && !socket.isClosed()){
    socket.receive(packet);
    system.out.println("Packet Length: "+packet.getLength());
    //code here
}

修复: Server.java中的

代码语言:javascript
复制
private void sendResponse(String res) throws Exception
        {
            if(res.equals("Y"))
            {
                // Send ACK -> Send File
                DatagramPacket x = new DatagramPacket(outgoingData, outgoingData.length, clientAddress, clientPort);
                serverSocket.send(x); //<<SEND ACK
                sendData();
            } else {
                String error = "ERROR: The file you requested does not exist.";
                outgoingData = error.getBytes();
                DatagramPacket err = new DatagramPacket(outgoingData, outgoingData.length, clientAddress, clientPort);

                serverSocket.send(err);
            }
        }

我注意到你没有发送ack,而客户正在期待它,这似乎是你唯一的问题。第一个包目前对您没有任何帮助。现在,您只需将ack包设置为您想要的。我只是在它不包含字符串"ERROR“的时候发送了它。

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

https://stackoverflow.com/questions/9593886

复制
相关文章

相似问题

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