Как решить проблему с абстракцией Java?

Сделал программу которая передает файлы клиент-сервер (через сокеты) , изначально все было в методе public static void main(String[] args) , решил сделать абстракцию (разбить программу на макс. кол-во методов и классов). Но столкнулся с такой проблемой, читает и принимает (например текст) клиент - сервер поочередно, то есть нельзя принять или отправить определенную переменную и т.д. После того как сделал абстракцию, выдает ошибку, проблема скорее всего именно в этом, как ее решить? Нужно с сервера спросить название файла и сервер должен отправить на клиент.

Это мой первый такой "масштабный" проект. Так же есть пару вопросов:
1) Это нормально, что почти к каждому файлу приписал throws IOException (компилятор требует)
2)Нормально ли сделал абстракцию?
3)Пришлось сделать метод "startProgram" , потому что в public static void main(String[] args) пришлось бы каждый метод вызывать client.МЕТОД , т.к. мои методы не статические. Как можно сделать лучше?

public class Client {

    Socket sock = null;
    //InputStream sin = null;
    DataInputStream in = null;
    //OutputStream sout = null;
    DataOutputStream out = null;
    BufferedReader reader = null;

    public void makeServer() throws IOException {
        sock = new Socket("127.0.0.1", 4444);
    }

    public String readFName() throws IOException {
        reader = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("Введите полный путь файла (например C:/image/cat.jpg)");
        String s = reader.readLine();
        out.writeUTF(s);
        return s;
    }

    public void fExists() throws IOException {

        if (!in.readBoolean()) {
            System.out.println("Файл не существует");
            System.exit(0);
        }
    }

    public String pFile(String s) throws IOException {
        String[] c = s.split("\\/");                                      //Разбиваем весь путь по знаку / для того чтобы взять имя файла

        System.out.println("Введи папку для сохранения файла (например C:/downloads) ");
        String fp = reader.readLine();                                    //Читаем путь куда сохранить
        String p = fp + "/" + c[c.length-1];                              //Берем имя файла

        return p;
    }

    public void writeFile(String s) throws IOException {
        pFile(readFName());

        byte[] mybytearray = new byte[4*1024];
        InputStream is = sock.getInputStream();
        FileOutputStream fos = new FileOutputStream(s);
        BufferedOutputStream bos = new BufferedOutputStream(fos);

        int bytesRead = is.read(mybytearray, 0, mybytearray.length);


        while (true) {
            bos.write(mybytearray, 0, bytesRead);

            if ((in.read(mybytearray)) == -1) {
                break;
            }
        }

        System.out.println("Файл передан");
        bos.close();
        sock.close();
    }

    public void startProgram() throws IOException {
        makeServer();
        readFName();
        fExists();
        writeFile(pFile(readFName()));

    }


    public static void main(String[] args) throws Exception {
          Client client = new Client();
          client.startProgram();
    }

}
  • Вопрос задан
  • 2731 просмотр
Пригласить эксперта
Ответы на вопрос 2
timych
@timych
Это декомпозиция а не "абстракция" :)
На сокетах что-то делал один раз , но не помню ни черта :) . Но вот что сразу бросается в глаза :
Во первых раз уж делите на классы, то Client должен быть отдельным классом. Во вторых DataInputStream и DataOutputStream не инстанцированы - естественно что на out.writeUTF() вываливается exception . В третьих мне кажется вместо throws лучше использовать try catch блоки .
В четветых - зачем readFname() вызывать три раза? . Запишите результат первого вызова в пременную .
Ну и для того чтобы получить часть строки не обязательно делать split() , можно использовать substring() например.
Ответ написан
Комментировать
@sderevyanko
Кроме того, что код не работающий, архитектурных проблем тут много:
1. public маркированны методы не используемые за пределами класса.
2. fExists(); не возвращает значений. Тут хорошо бы проверять наличие файла с возвращением boolean переменной.
3. Валидировать данные хорошо сразу после ввода.
4. Если приложение клиент серверное, то хорошо бы иметь как клиент, так и сервер, и не важно что они работают на одном компе.
5. Ну и как указано выше, не нужно выбрать где корректно обработать исключение в try - catch блоке, а не пробрасывать исключение через все методы.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы