Good afternoon, everyone! I am writing an application that sends files from the client to the server. With one file, everything works fine, but when several files are sent, the exception is generated

Exception in thread "main" java.lang.NegativeArraySizeException at double2.code.code1.Receiver.receiveFile(Receiver.java:45) at double2.code.code1.Receiver.main(Receiver.java:18) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) 

Server code:

 public class Sender { static ServerSocket server; static final int PORT = 6666; static ArrayList<Socket> sockets; static String basePath = "C:\\as\\server"; public static void main(String[] args) throws IOException { server =new ServerSocket(PORT); sockets = new ArrayList<Socket>(); String fileName ="111.jpg"; ArrayList<String>locations = new ArrayList<String>(); locations.add(fileName); locations.add("1.jpg"); Socket socket = server.accept(); Sender.send(socket,locations); socket.close(); } static void sendFileNames(Socket socket,ArrayList<String>fileNames) throws IOException { DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream()); dataOutputStream.writeInt(fileNames.size());//отправляем размер for (String name:fileNames){ dataOutputStream.writeUTF(name); } } public static void send(Socket socket,ArrayList<String> fileNames) throws IOException { FileInputStream fileInputStream = null; BufferedInputStream bufferedInputStream = null; DataOutputStream outputStream = null; try { System.out.println("Waiting for receiver..."); try { System.out.println("Accepted connection : " + socket); sendFileNames(socket,fileNames); for(String fileName:fileNames) { File file = new File(basePath + "\\"+fileName); byte[] byteArray = new byte[(int) file.length()]; System.out.println("lol"); outputStream = new DataOutputStream(socket.getOutputStream()); outputStream.writeLong(file.length());//TODO System.out.println("lol"); fileInputStream = new FileInputStream(file); bufferedInputStream = new BufferedInputStream(fileInputStream); bufferedInputStream.read(byteArray, 0, byteArray.length); // copied file into byteArray System.out.println("Sending " + fileName + "( size: " + byteArray.length + " bytes)"); outputStream.write(byteArray, 0, byteArray.length); outputStream.flush(); //flushing socket System.out.println("Done."); } } finally { if (bufferedInputStream != null) bufferedInputStream.close(); if (outputStream != null) bufferedInputStream.close(); if (socket!=null) socket.close(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if (server != null) server.close(); } } } 

Client code:

 public class Receiver { static Socket socket; static final int PORT = 6666; static final String IP = "127.0.0.1"; static DataInputStream dim; static String basePath = "C:\\as\\client"; public static void main (String [] args ) throws IOException { socket = new Socket(IP,PORT); receiveFile(); System.out.println("yeeee"); } static ArrayList<String>readFileNames() throws IOException { ArrayList<String>res = new ArrayList<String>(); DataInputStream din = new DataInputStream(socket.getInputStream()); int lenght = din.readInt(); for(int i = 0;i<lenght;i++){ String name = din.readUTF(); res.add(name); } return res; } public static void receiveFile() throws IOException { int bytesRead = 0; int current = 0; FileOutputStream fileOutputStream = null; BufferedOutputStream bufferedOutputStream = null; try { ArrayList<String> locations = readFileNames(); for (String location:locations) { dim = new DataInputStream(socket.getInputStream()); long res = dim.readLong(); System.out.println("res "+res); byte[] byteArray = new byte[(int) res + 1]; System.out.println("sizze" + res); System.out.println("Please wait downloading file"); DataInputStream inputStream = new DataInputStream(socket.getInputStream()); File f = new File(basePath + "\\" + location); fileOutputStream = new FileOutputStream(f); System.out.println(f.createNewFile()); //TODO !!!!!!!!!!! bufferedOutputStream = new BufferedOutputStream(fileOutputStream); bytesRead = inputStream.read(byteArray, 0, byteArray.length); //copying file from socket to byteArray current = bytesRead; System.out.println("hah"); do { bytesRead = inputStream.read(byteArray, current, (byteArray.length - current)); System.out.println(current); if (current == res) break; if (bytesRead >= 0) current += bytesRead; } while (bytesRead > -1); bufferedOutputStream.flush(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if (fileOutputStream != null) fileOutputStream.close(); if (bufferedOutputStream != null) bufferedOutputStream.close(); } } } 
  • The reason for the exception is clear - the size of the file, which is less than 0, resorts. And it is a bit difficult to create an array with this size. Here java and swears. Why this happens - it is not clear, I came up with only one idea - you are trying to transfer a file larger than 2 gigabytes. - KoVadim
  • The file size is small. The file size is transferred 2 times, a few dozen times more than necessary. I’m afraid of mine for such a large size. It remains unclear why the size in 2 cases is sent incorrectly - mr.robot
  • can an archivist throw? :)) - Flippy
  • without problems: my-files.ru/2kizw5 - mr.robot
  • the problem is that the serializer and deserializer code is not synchronized somewhere. But where ... For good, I would take wireshark and look inside. And there it will be clear that the problem is on the client or on the server. - KoVadim

1 answer 1

in the client code, an array of size res (which is the file size) + 1 byte[] byteArray = new byte[(int) res + 1] ;

later it reads bytes in an amount equal to the size of the array (which is +1 more than the resulting file size).

 bytesRead = inputStream.read(byteArray, 0, byteArray.length); 

Here you need to write:

 bytesRead = inputStream.read(byteArray, 0, res); 

or which is preferable to create an array exactly the size of the file:

 byte[] byteArray = new byte[(int) res];