I'm building a back-up server that I can run on a remote computer. The problem now is that I have a memory leak, I think. When transferring large files, after a while the following error appears:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.lang.StringCoding$StringDecoder.decode(StringCoding.java:149)
at java.lang.StringCoding.decode(StringCoding.java:193)
at java.lang.StringCoding.decode(StringCoding.java:254)
at java.lang.String.<init>(String.java:536)
at java.lang.String.<init>(String.java:556)
at Server.run(Server.java:61)
at Server.main(Server.java:107)
I've read a quiet few of articles about this but none really gave me an answer to how to solve this. The code is down below. Thanks in advance.
Server:
private ServerSocket server;
private Socket acceptingSocket;
public Server(int port){
try {
server = new ServerSocket(port);
} catch (IOException e) {
System.out.println("Try again");
}
}
/**
* Reads all files and puts them in the back-up folder. Also creates the appropriate dirs.
*/
public void run(){
BufferedInputStream buffer = null;
DataInputStream reader = null;
BufferedOutputStream out = null;
DataOutputStream writer = null;
int size = 0;
try {
acceptingSocket = server.accept();
buffer = new BufferedInputStream(acceptingSocket.getInputStream());
reader = new DataInputStream(buffer);
out = new BufferedOutputStream(acceptingSocket.getOutputStream());
writer = new DataOutputStream(out);
size = reader.readInt();
} catch (IOException e1) {
}
System.out.println("Size: " + size);
//Variables I need later on, I thought this would help
byte[] name;
int fileNameLength = 0;
long length=0;
boolean dir = false;
int t = 0;
String dirs = "";
File direcs;
File file;
byte[] b;
int bytes=0;
for(int j = 0; j < size; j++){
try {
fileNameLength = reader.readInt();
name = new byte[fileNameLength];
reader.read(name, 0,fileNameLength);
String path = new String(name);
System.out.println("Path: " + path);
length = reader.readLong();
dir = reader.readBoolean();
path = "/backup" + path;
file = new File(path);
if(!dir){
t = file.getAbsolutePath().lastIndexOf("/");
dirs = file.getAbsolutePath().substring(0, t);
direcs = new File(dirs);
System.out.println(direcs.mkdirs());
FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fos);
b = new byte[(int) length];
bytes = reader.read(b, 0, (int)length);
if(bytes != -1)
bos.write(b,0,(int)length);
writer.writeUTF("File " + file.getAbsolutePath() + " is created!");
writer.flush();
bos.flush();
fos.flush();
bos.close();
fos.close();
out.flush();
} else file.mkdirs();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
buffer.close();
reader.close();
out.close();
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args){
int port = Integer.parseInt(args[0]);
Server server = new Server(port);
while(true)
server.run();
}
Client:
private DataInputStream serverToClient;
private Socket client;
private DataOutputStream clientToServer;
private String name;
public Client(String name, int port){
try {
client = new Socket(name, port);
//receive response server
serverToClient = new DataInputStream(client.getInputStream());
//send message to server
clientToServer = new DataOutputStream(client.getOutputStream());
this.name = name;
}
catch (IOException e) {
}
}
/**
* Closes all connections
*/
public void stop(){
try {
client.close();
serverToClient.close();
clientToServer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Sends all files and content of the files to the back-up server
* @param filePath
*/
public void backUp(String filePath){
ArrayList<File> files = new ArrayList<File>();
boolean dir = false;
long length = 0;
byte[] buffer;
try{
listf(filePath, files, 0);
System.out.println(files.toString());
clientToServer.writeInt(files.size());
for(File fi : files){
dir = false;
if(fi.isDirectory()) dir = true;
clientToServer.writeInt(fi.getAbsolutePath().length());
System.out.println(fi.getAbsolutePath().length());
clientToServer.writeBytes(fi.getAbsolutePath());
System.out.println(fi.getAbsolutePath());
length = fi.length();
clientToServer.writeLong(length);
clientToServer.writeBoolean(dir);
System.out.println("Dir? " + dir);
System.out.println(length);
if(!dir){
FileInputStream fis = new FileInputStream(fi);
BufferedInputStream bis = new BufferedInputStream(fis);
buffer = new byte[(int)length];
bis.read(buffer, 0, (int)length);
clientToServer.write(buffer);
System.out.println(serverToClient.readUTF());
bis.close();
fis.close();
clientToServer.flush();
}
}
} catch(IOException e){
e.printStackTrace();
}
}
/**
* Get all files, folders and subfolders in the file specified by directoryName, recursively.
* @param directoryName
* @param files
* @param size
*/
private void listf(String directoryName, ArrayList<File> files, int size) {
File directory = new File(directoryName);
size = files.size();
if(size > 100){
System.out.println(size);
size += 100;
}
if(directory.isFile()) files.add(directory);
else{
File[] fList = directory.listFiles();
for (File file : fList) {
if(file.isDirectory() && file.listFiles().length == 0) files.add(file);
else{
if (file.isFile()) {
files.add(file);
} else if (file.isDirectory()) {
listf(file.getAbsolutePath(), files, size);
}
}
}
}
}
public static void main(String[] args){
String name = args[0];
int port = Integer.parseInt(args[1]);
System.out.println("Name: " + name + " Port: " + port);
Client client = new Client(name, port);
File file = new File(args[2]);
if(file.exists())client.backUp(args[2]);
else System.out.println("File doesn't exist");
client.stop();
}