JavaRush /Курсы /Java Collections /Учимся гуглить | 2 уровень | 11 лекция

Учимся гуглить | 2 уровень | 11 лекция

Java Collections
2 уровень , 11 лекция
Открыта

— Привет, Амиго!

Продолжаем наши уроки – учимся гуглить.

Вот тебе несколько заданий:

Что надо найти в Google
1 Как записать информацию в файл в произвольном месте
2 Как прочитать 10000-ю строку из файла, не читая предыдущих
3 Как преобразовать строку в Reader
4 Как преобразовать Writer в строку
5 Как создать прокси-объект
6 Как переопределить InvokeHandler
7 Как написать RMI клиент
8 Как написать RMI сервер
9 Как разрешитьRMI-доступ из других компьютеров сети
10 Распространённые RMI ошибки
Комментарии (71)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
onidza Уровень 1
2 сентября 2025
2. Такой способ позволяет не читать все 1000 строк, а сразу перепрыгнуть на нужную: Строим индекс: List<Long> offsets = new ArrayList<>(); try (RandomAccessFile raf = new RandomAccessFile("big.txt", "r")) { offsets.add(0L); // первая строка всегда начинается с 0 String line; while ((line = raf.readLine()) != null) { long pos = raf.getFilePointer(); // где курсор после прочитанной строки offsets.add(pos); } } Читаем по индексу: int n = 10000; // нужна 10000-я строка try (RandomAccessFile raf = new RandomAccessFile("big.txt", "r")) { raf.seek(offsets.get(n - 1)); // прыгаем на начало строки String line = raf.readLine(); System.out.println(line); } А skip, seek без индекса и другие способы все равно под капотом читают 1000 строк, пока не дойдут до нужной.
AhanSere Уровень 1
16 ноября 2023
погуглил и наткнулся на эту же страницу. Рекурсия однако
milniy87 Уровень 41
18 марта 2023
1. Чтобы записать информацию в файл в произвольном месте в Java, можно воспользоваться классом RandomAccessFile. Например, чтобы записать строку в файл в позицию 50, можно сделать так:

RandomAccessFile file = new RandomAccessFile("file.txt", "rw");
file.seek(50); // устанавливаем позицию, на которую будем записывать
file.write("Hello, world!".getBytes()); // записываем данные
file.close();
2. Чтобы прочитать 10000-ю строку из файла без чтения предыдущих строк, можно воспользоваться классом LineNumberReader. Например, чтобы прочитать 10000-ю строку из файла file.txt, можно сделать так:

LineNumberReader reader = new LineNumberReader(new FileReader("file.txt"));
String line = null;
while ((line = reader.readLine()) != null) {
    if (reader.getLineNumber() == 10000) {
        System.out.println(line);
        break;
    }
}
reader.close();
3. Чтобы преобразовать строку в Reader, можно воспользоваться классом StringReader. Например:

String str = "Hello, world!";
Reader reader = new StringReader(str);
4. Чтобы преобразовать Writer в строку, можно воспользоваться классом StringWriter. Например:

StringWriter writer = new StringWriter();
writer.write("Hello, world!");
String str = writer.toString();
milniy87 Уровень 41
18 марта 2023
5. Чтобы создать прокси-объект в Java, можно воспользоваться классом java.lang.reflect.Proxy. Для этого нужно имплементировать интерфейс InvocationHandler и передать его в метод Proxy.newProxyInstance(). Например:

interface MyInterface {
    void doSomething();
}

class MyInvocationHandler implements InvocationHandler {
    private MyInterface target;

    public MyInvocationHandler(MyInterface target) {
        this.target = target;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Before");
        Object result = method.invoke(target, args);
        System.out.println("After");
        return result;
    }
}

MyInterface realObject = new MyInterface() {
    public void doSomething() {
        System.out.println("Doing something");
    }
};

MyInterface proxyObject = (MyInterface) Proxy.newProxyInstance(
    MyInterface.class.getClassLoader(),
    new Class[] { MyInterface.class },
    new MyInvocationHandler(realObject)
);

proxyObject.doSomething();
6. Чтобы переопределить InvocationHandler в Java, нужно имплементировать этот интерфейс и переопределить метод invoke(). Например:

class MyInvocationHandler implements InvocationHandler {
    private Object target;

    public MyInvocationHandler(Object target) {
        this.target = target;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Before");
        Object result = method.invoke(target, args);
        System.out.println("After");
        return result;
    }
}
milniy87 Уровень 41
18 марта 2023
7. Как написать RMI клиент? Для написания RMI клиента вам нужно сделать следующее: Создать интерфейс удаленного объекта Создать клиентскую программу, которая будет использовать удаленный объект Пример интерфейса удаленного объекта:

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface MyRemoteInterface extends Remote {
    public String sayHello() throws RemoteException;
}
Пример клиентской программы:

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class MyClient {
    public static void main(String[] args) {
        try {
            // Получение удаленного объекта из реестра
            Registry registry = LocateRegistry.getRegistry("localhost");
            MyRemoteInterface remoteObj = (MyRemoteInterface) registry.lookup("MyRemoteObject");

            // Вызов удаленного метода
            String response = remoteObj.sayHello();
            System.out.println(response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
milniy87 Уровень 41
18 марта 2023
8. Как написать RMI сервер? Для написания RMI сервера вам нужно сделать следующее: Создать класс, который будет реализовывать интерфейс удаленного объекта Создать серверную программу, которая будет регистрировать удаленный объект в реестре RMI Пример класса, реализующего интерфейс удаленного объекта:

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class MyRemoteObject extends UnicastRemoteObject implements MyRemoteInterface {
    public MyRemoteObject() throws RemoteException {
        super();
    }

    public String sayHello() throws RemoteException {
        return "Hello from remote object!";
    }
}
Пример серверной программы:

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class MyServer {
    public static void main(String[] args) {
        try {
            // Создание удаленного объекта
            MyRemoteObject remoteObj = new MyRemoteObject();

            // Регистрация удаленного объекта в реестре
            Registry registry = LocateRegistry.createRegistry(1099);
            registry.rebind("MyRemoteObject", remoteObj);

            System.out.println("Server is running...");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
milniy87 Уровень 41
18 марта 2023
9. Как разрешить RMI-доступ из других компьютеров сети Для разрешения RMI-доступа из других компьютеров сети необходимо выполнить несколько шагов: Убедитесь, что ваш RMI-сервер привязан к нужному IP-адресу и порту. Это можно сделать с помощью метода UnicastRemoteObject.exportObject(Remote obj, int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf). Например:


MyRemoteImpl obj = new MyRemoteImpl();
int port = 12345;
Remote stub = UnicastRemoteObject.exportObject(obj, port);
Registry registry = LocateRegistry.createRegistry(port);
registry.bind("MyRemote", stub);
Здесь мы экспортируем удаленный объект MyRemoteImpl на порту 12345, и привязываем его к реестру RMI. Убедитесь, что на вашем компьютере открыты порты, используемые RMI. По умолчанию, RMI использует порты 1099 и 1098 для регистрации и передачи данных соответственно. Проверьте настройки брандмауэра на вашем компьютере. Если вы используете брандмауэр, убедитесь, что он разрешает RMI-соединения на нужных портах. Проверьте настройки маршрутизации в вашей сети. Если ваш RMI-сервер находится за маршрутизатором, убедитесь, что маршрутизатор правильно настроен для передачи трафика на нужный порт. Если вы используете статический IP-адрес для вашего RMI-сервера, убедитесь, что он правильно настроен. Если вы используете динамический IP-адрес, убедитесь, что ваш DNS-сервер правильно настроен для преобразования имени хоста в IP-адрес. Если вы все еще не можете подключиться к вашему RMI-серверу, попробуйте использовать утилиту rmiregistry в качестве отдельного процесса, а не встроенную в ваш RMI-сервер. Это может помочь избежать проблем с разрешением имен и портов.
milniy87 Уровень 41
18 марта 2023
10. Распространенные RMI ошибки Некоторые распространенные ошибки, связанные с RMI: RemoteException: Вызываемый метод не может быть найти на удаленном объекте Эта ошибка обычно возникает, когда вызываемый метод не определен в интерфейсе удаленного объекта. RemoteException: Нет ответа от удаленного хоста Эта ошибка может возникнуть, когда клиент не может связаться с сервером. Проблема может быть вызвана неправильными параметрами хоста или порта. AccessException: Нет разрешения на вызов удаленного метода Эта ошибка может возникнуть, когда клиент не имеет прав на вызов метода на сервере. Проблема может быть вызвана неправильными настройками безопасности RMI. ConnectException: Не удалось подключиться к серверу RMI Эта ошибка может возникнуть, когда клиент не может подключиться к серверу RMI. Проблема может быть вызвана неправильными параметрами хоста или порта. ClassNotFoundException: Удаленный класс не найден Эта ошибка может возникнуть, когда сервер не может найти класс, необходимый для удаленного вызова. Проблема может быть вызвана неправильными настройками CLASSPATH или нехваткой прав доступа. InvalidClassException: Несовместимость сериализуемых классов Эта ошибка может возникнуть, когда клиент и сервер используют разные версии сериализуемых классов. Проблема может быть вызвана изменением классов без соответствующего обновления клиента и сервера. UnmarshalException: Ошибка при разборе входных данных Эта ошибка может возникнуть, когда сервер не может разобрать входные данные от клиента. Проблема может быть вызвана неправильной сериализацией или передачей неправильных данных.
Радик Уровень 37
21 марта 2023
благодарю , отличный комент !
Dimash Уровень 1
23 марта 2023
спасибо за проделанную работу!
Андрей Уровень 42
19 мая 2023
вместо всех дремучих лекций коротко и по существу. спасибо!
ElenaN Уровень 37
19 декабря 2023
Спасибо! Я очень надеялась найти такой комментарий здесь)
Евгений Уровень 38
15 декабря 2022
Ответ на 2 вопрос: НИКАК. В любом случае надо либо изначально всё прочитать, либо знать № позиции курсора для 10000-й строки
Вадим Уровень 40
2 сентября 2022
Интересный второй вопрос. Чтобы найти строку, нужно найти \n. Чтобы найти \n, нужно последовательно читать символы. То есть какой бы класс и метод мы не использовали, в любом случае все строки до 1000-й будут прочитаны/просмотрены.
Станислав Future Уровень 39
12 августа 2022
Никому не рассказывайте, гуглить не буду
LuneFox Уровень 41 Expert
24 декабря 2021
Вопрос #2 Для небольших файлов:
String line32 = Files.readAllLines(Paths.get("file.txt")).get(32);
Для больших файлов:
try (Stream<String> lines = Files.lines(Paths.get("file.txt"))) {
    line32 = lines.skip(31).findFirst().get();
}
source
LuneFox Уровень 41 Expert
24 декабря 2021
Ещё немного информации, которую я узнал про RMI: - Чтобы обратиться к реестру на удалённой машине, в аргументах перед портом нужно передать адрес хоста - Сервер может хранить реестр удалённых объектов не только у себя локально, но и выгружать куда-то в сеть - RMI не стоит использовать в глобальной сети интернет, так как могут возникать проблемы с доступом к портам, в этом случае лучше пользоваться REST через HTTP (информация 9-летней давности, может уже придумали что получше?)
Ilia lenskii Уровень 32
11 сентября 2022
> - Сервер может хранить реестр удалённых объектов не только у себя локально, но и выгружать куда-то в сеть В унике на лекции про java, препод сказал, что норм практика держать один сервак, который раздает такие объекты по требованию. Посему, вы правы, я думаю.
Daniel Уровень 51
12 марта 2023
А я то все думал, как скрестить этот ваш RMI с сокетами, а надо было просто полный адрес хоста указывать... В любом случае все на REST работает, так что бог с ним)
Anonymous #2539565 Уровень 51
9 декабря 2021
может есть ответы, как на предыдущем уровне?
Дмитрий Уровень 33
5 октября 2021
10 https://spec-zone.ru/RU/Java/Docs/7/technotes/guides/rmi/faq.html#domain
Максим Глотов Уровень 35
19 сентября 2021
Самые крутые лекции про гуглёжку :-\