I have rewritten my little chat application and tried to pay attention to former hints and tips. The viewer and the writer have to run as seperate applications. the Writer.class basically stores messages as property files. The directory, where the files get stored, is watched by the Viewer.class and gets scanned every 0.5 seconds.
I tried to implement a clear structure to my source code and to implement clean methods with clear names and unique resposibilities. I also tried to write clear comments.
What do you think about my program? Is there something that I can improve?
Viewer.java
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
import java.util.Date;
import java.util.Properties;
import java.io.File;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
public class Viewer {
public static void main(String[] args) {
Viewer viewer = new Viewer();
viewer.view();
}
// contains all messages within two sub-dirs
private File saveDir;
// contains messages that have to be displayed
private File currentDir;
// contains messages that don't have to be displayed
private File archiveDir;
// determines the maximal amount of messages in the current directory
private int currentMessagesCount;
// last message read into program
private File lastMessage;
public Viewer() {
// initialize members from file named config
try (BufferedInputStream stream = new BufferedInputStream(new FileInputStream("config"))) {
Properties config = new Properties();
config.load(stream);
currentMessagesCount = Integer.parseInt(config.getProperty("current_messages_count"));
saveDir = new File(config.getProperty("save_dir"));
} catch (IOException e) {
e.printStackTrace();
}
currentDir = new File(saveDir, "current");
archiveDir = new File(saveDir, "archive");
lastMessage = new File("no last message");
// create save directories if don't exist
if (!saveDir.exists()) {
saveDir.mkdir();
}
if (!currentDir.exists()) {
currentDir.mkdir();
}
if (!archiveDir.exists()) {
archiveDir.mkdir();
}
File[] messages = currentDir.listFiles();
Arrays.sort(messages);
}
public void view() {
printAllMessages();
while (true) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
printNewMessage();
checkLimit();
}
}
// prints all messages immediately
private void printAllMessages() {
File[] messages = currentDir.listFiles();
if (messages.length == 0) {
return;
}
Arrays.sort(messages);
for (int i = 0; i < messages.length; i++) {
printMessage(messages[i]);
}
lastMessage = messages[messages.length - 1];
}
// prints newest if there is a more recent than last read message
private void printNewMessage() {
File[] messages = currentDir.listFiles();
Arrays.sort(messages);
if (messages.length == 0) {
return;
}
// add all new messages to a list and print it out reversively
List<File> newMessages = new ArrayList<>();
for (int i = messages.length - 1; i >= 0 ; i--) {
if (!messages[i].toString().equals(lastMessage.toString())) {
newMessages.add(messages[i]);
} else {
break;
}
}
while (newMessages.size() > 0) {
File currentMessage = newMessages.get(newMessages.size() - 1);
printMessage(currentMessage);
newMessages.remove(currentMessage);
lastMessage = currentMessage;
}
}
private void printMessage(File file) {
try (BufferedInputStream stream = new BufferedInputStream(new FileInputStream(file))) {
Properties currentMessage = new Properties();
currentMessage.load(stream);
System.out.println(currentMessage.getProperty("date") + " (" + currentMessage.getProperty("nickname") + ")");
System.out.println(currentMessage.getProperty("content") + "\n");
} catch (IOException e) {
e.printStackTrace();
}
}
// checks if there are too much messages in currentDir
private void checkLimit() {
File[] messages = currentDir.listFiles();
Arrays.sort(messages);
int numOfSuperfluousMessages = messages.length - currentMessagesCount;
if (numOfSuperfluousMessages > 0) {
for (int i = 0; i < numOfSuperfluousMessages; i++) {
messages[i].renameTo(new File(archiveDir, messages[i].getName()));
}
}
}
}
Writer.java
import java.util.Scanner;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.BufferedWriter;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.Properties;
public class Writer {
public static void main(String[] args) {
System.out.print("Your nickname: ");
String nickname = scanner.nextLine();
Writer writer = new Writer(nickname);
writer.chat();
}
private static Scanner scanner = new Scanner(System.in);
private String nickname;
// directory in which messages get stored
// initialized by file named config
private File currentDir;
public Writer(String nickname) {
this.nickname = nickname;
try (BufferedInputStream stream = new BufferedInputStream(new FileInputStream("config"))) {
Properties config = new Properties();
config.load(stream);
currentDir = new File(config.getProperty("save_dir"), "current");
} catch (IOException e) {
e.printStackTrace();
}
// create current dir if not exists
if (!currentDir.exists()) {
currentDir.mkdirs();
}
}
public void chat() {
while (true) {
System.out.print(nickname + " > ");
String newContent = scanner.nextLine();
long millis_bygone = new Date().getTime();
File newMessage = new File(currentDir, new Long(millis_bygone).toString());
// create file
try {
newMessage.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
// store message to file in currentDir
try (BufferedWriter br = new BufferedWriter(new FileWriter(newMessage))) {
br.write("nickname: " + nickname + "\n");
// create date string
Calendar cal = Calendar.getInstance();
StringBuilder dateString = new StringBuilder();
dateString.append(cal.get(Calendar.DAY_OF_MONTH) + "." + (cal.get(Calendar.MONTH) + 1) + "." + cal.get(Calendar.YEAR) + " ");
dateString.append(cal.get(Calendar.HOUR_OF_DAY) + ":" + cal.get(Calendar.MINUTE));
br.write("date: " + dateString + "\n");
br.write("content: " + newContent + "\n");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}