Java 读取文件时发生IndexOutOfBoundException
我正在开发一个TFTP服务器应用程序。我成功地处理了从服务器到客户机的文件传输,但另一方面却出现了错误 客户端没有传输整个文件,只是终止了whit编译器,没有返回任何错误。调试器在表示数组超出范围的标记代码上显示IOBE异常 整个转移过程如下所示:Java 读取文件时发生IndexOutOfBoundException,java,sockets,exception,networking,inputstream,Java,Sockets,Exception,Networking,Inputstream,我正在开发一个TFTP服务器应用程序。我成功地处理了从服务器到客户机的文件传输,但另一方面却出现了错误 客户端没有传输整个文件,只是终止了whit编译器,没有返回任何错误。调试器在表示数组超出范围的标记代码上显示IOBE异常 整个转移过程如下所示: 客户端传输文件名和请求的操作WRQ-写入请求 服务器接收到数据包,并确定WRQ是否为新文件提供了适当的名称 服务器现在开始执行receiveData(),直到它得到一个数据包
private void sendWRQ() throws Exception
{
String rrq = "WRQ-" + data;
outgoingData = rrq.getBytes();
DatagramPacket output = new DatagramPacket(outgoingData, outgoingData.length, serverAddress, serverPort);
clientSocket.send(output);
//Thread.sleep(50);
sendData();
}
byte outgoingData = new byte[512];
private void sendData() throws Exception
{
DatagramPacket dataTransfer = new DatagramPacket(outgoingData, outgoingData.length, serverAddress, serverPort);
InputStream fis = new FileInputStream(new File(data));
int x;
while((x = fis.read(outgoingData,0,512)) != -1) // << Debugged gives IOBE
{
dataTransfer.setLength(x);
clientSocket.send(dataTransfer);
Thread.sleep(5);
}
fis.close();
}
唯一可能发生的情况是偏移量或长度参数违反了为
InputStream.read(byte[],int,int)
指定的约束;在这种情况下,缓冲区可能不是512字节长。在这种情况下,无需指定第二个和第三个参数,只需省略它们,然后它在内部变成read(buffer,0,buffer.length)
,这不会出错。好的,按照编码方式,“outgoingData”字段是:
1) 初始化为512的长度
2) 然后,在sendWRQ()中,“outgoingData”被重新初始化为rrq.getBytes()发回的任何内容
3) 然后,在sendData()中,“outgoingData”用作中间缓冲区,从文件中读取数据并将其放入dataTransfer对象中
然而,由于“outgoingData”在步骤2中重新初始化,因此步骤3中“outgoingData”的长度仍然为512字节的假设是错误的
因此,虽然EJP说使用read(outgoingData,0,outgoingData.length())可以工作是正确的,但是如果您解决了一些架构问题,您将清除许多潜在的错误
例如:
使用提供的代码,似乎没有理由在类级别声明outgoingData并在两个函数之间共享。根据应用程序的其他部分,这可能最终成为线程问题。
也许byte[]buffer=rrq.getBytes();在sendWRQ()中,字节[]缓冲区=新字节[1024];在sendData()中。
此外,“数据”参数位于类级别。。。。为什么?如果它是传入的参数,则可以更好地进行控制
最后,我很幸运地在网络环境中使用了do{}while()循环。确保send()至少有一次机会发送数据,并使代码更具可读性。打印
rrq.getBytes()
,然后查看它是否正确。不确定字符串
是否正确处理特殊字符。它是正确的。问题不在此发送和接收此部分,因为它应该是有问题的部分,我在代码中标记了它。您没有提供outgoingData
定义,它是否有足够的空间容纳512字节?byte[]outgoingData的大小是多少?我建议您创建一个新字节[],以便从FileInputStream读取。@Zaki您是对的。似乎一个新的byte[]数组解决了这个问题。
private void listen() throws Exception
{
DatagramPacket incTransfer = new DatagramPacket(incomingData, incomingData.length);
serverSocket.receive(incTransfer);
clientAddress = incTransfer.getAddress();
clientPort = incTransfer.getPort();
String output = new String(incTransfer.getData());
if(output.substring(0, 3).equals("RRQ"))
{
File test = new File(output.substring(4));
responseData = output.substring(4);
if(test.exists())
{
sendResponse("Y");
} else {
sendResponse("N");
}
} else if (output.substring(0, 3).equals("WRQ"))
{
File test = new File(output.substring(4));
if(test.exists())
{
Calendar cal = Calendar.getInstance();
SimpleDateFormat prefix = new SimpleDateFormat(date_format);
String date = prefix.format(cal.getTime()).toString();
responseData = date + output.substring(4);
receiveData();
} else {
responseData = output.substring(4);
receiveData();
}
}
}
private void receiveData() throws Exception
{
DatagramPacket receiveData = new DatagramPacket(incomingData, incomingData.length);
OutputStream fos = new FileOutputStream(new File(responseData));
while(true)
{
serverSocket.receive(receiveData);
if(receiveData.getLength() == 512)
{
fos.write(receiveData.getData());
} else {
fos.write(receiveData.getData(), receiveData.getOffset(), receiveData.getLength());
break;
}
}
fos.close();
}