Случайный разговор: Как объяснить девушке, что такое BIO, NIO и AIO?

Java задняя часть
Случайный разговор: Как объяснить девушке, что такое BIO, NIO и AIO?


В выходной день во время телефонного интервью дома я задал собеседнику несколько вопросов о IO, в том числе о том, что такое BIO, NIO и AIO? В чем разница между тремя? Конкретные вопросы, например, как его использовать, но ответ интервьюируемого не очень удовлетворительным. Поэтому я написал в оценке интервью: «Понимание напоминания о вводе-выводе в Java недостаточно глубоко». Просто случайно увидел мою девушку.

Java IO

IO, часто пишется как I/O, это аббревиатура Input/Output, то есть ввод/вывод. Обычно относится к вводу и выводу данных между внутренней памятью (памятью) и внешней памятью (жесткий диск, USB и т. д.) или другими периферийными устройствами.

Ввод/вывод — это связь между системой обработки информации (например, компьютером) и внешним миром (может быть, человеком или другой системой обработки информации).

Входы — это сигналы или данные, полученные системой, а выходы — это сигналы или данные, отправленные из нее.

В Java разработчикам предоставляется ряд API для чтения и записи внешних данных или файлов. Мы называем эти API Java IO.

IO является относительно важным и сложным аспектом знаний в Java, главным образом потому, что с развитием Java в настоящее время сосуществуют три типа IO. Это BIO, NIO и AIO соответственно.

Java BIO

Полное название BIO — Block-IO.синхронный и блокирующийрежим связи. Это относительно традиционный метод связи с простым режимом и простой в использовании. Однако возможности параллельной обработки невелики, обмен данными занимает много времени и зависит от скорости сети.

Java NIO

Java NIO, весь процесс неблочного ввода-вывода, представляет собой новую функцию, оптимизированную для производительности сетевой передачи после версии Java SE 1.4. этонеблокирующая синхронизациярежим связи.

NIO имеет ту же функцию и назначение, что и исходный ввод-вывод, наиболее важным отличием между ними является способ упаковки и передачи данных. Исходный ввод-вывод обрабатывает данные в потоке, тогда как NIO обрабатывает данные блоками.

Потоковые системы ввода-вывода обрабатывают данные по одному байту за раз. Входной поток создает один байт данных, а выходной поток потребляет один байт данных.

Блочно-ориентированная система ввода-вывода обрабатывает данные блоками. Каждая операция создает или потребляет блок данных за один шаг. Обработка данных фрагментами выполняется намного быстрее, чем обработка данных в виде (потоковых) байтов. Но блочно-ориентированному вводу-выводу не хватает элегантности и простоты потокового ввода-вывода.

Java AIO

Java AIO, полный асинхронный ввод-вывод, даАсинхронный неблокирующийИО. Это неблокирующий асинхронный режим связи.

На основе NIO представлена ​​новая концепция асинхронного канала, а также реализована реализация асинхронного файлового канала и асинхронного канала сокетов.

Разница между тремя IO

Во-первых, давайте перерисуем ключевые точки с точки зрения макроса:

BIO (блокировка ввода-вывода): режим синхронной блокировки ввода-вывода.

NIO (новый ввод-вывод): синхронный неблокирующий режим.

AIO (асинхронный ввод-вывод): модель асинхронного неблокирующего ввода-вывода.

Итак, как насчет синхронной блокировки, синхронной неблокировки и асинхронной неблокировки? Для этой части см. такжеСлучайный разговор: Как объяснить моей девушке, что такое блокировка, неблокировка, синхронность, асинхронность в IO?".

Режим синхронной блокировки: в этом режиме наш рабочий режим заключается в том, чтобы сначала пойти на кухню, начать кипятить воду, сесть перед чайником и дождаться, пока вода закипит.

Синхронный неблокирующий режим: В этом режиме наш режим работы - сначала прийти на кухню и начать кипятить воду, но вместо того, чтобы все время сидеть перед чайником и ждать, мы возвращаемся в гостиную, чтобы посмотреть телевизор. , а потом ходить на кухню смотреть каждые несколько минут Закипела ли вода?

Модель асинхронного неблокирующего ввода-вывода: в этом режиме наш рабочий режим заключается в том, чтобы сначала прийти на кухню и начать кипятить воду.Смотрим телевизор в гостиной, есть переключатель на чайнике, он уведомит меня, когда вода кипит.

Блокировка против блокировки: сидит ли человек перед чайником и ждет.

Синхронный и асинхронный: чайник активно уведомляет людей, когда вода закипает?

Применимая сцена

Метод BIO подходит для структуры с относительно небольшим количеством соединений и фиксированным числом соединений.Этот метод имеет относительно высокие требования к ресурсам сервера, а параллелизм ограничен приложениями.Это единственный выбор до JDK1.4, но программа интуитивно понятна и проста в понимании.

Метод NIO подходит для архитектур с большим количеством подключений и относительно короткими подключениями (легкая операция), таких как чат-серверы, где параллелизм ограничен приложениями, а программирование сложнее, JDK1.4 начал его поддерживать.

Метод AIO подходит для архитектур с большим количеством подключений и относительно длинными подключениями (тяжелыми операциями), такими как серверы фотоальбомов, он полностью вызывает участие ОС в параллельных операциях, а программирование более сложное JDK7 начал поддерживать Это.

Как пользоваться

Чтение и запись файлов с помощью BIO.

//Initializes The Object
User1 user = new User1();
user.setName("hollis");
user.setAge(23);
System.out.println(user);

//Write Obj to File
ObjectOutputStream oos = null;
try {
    oos = new ObjectOutputStream(new FileOutputStream("tempFile"));
    oos.writeObject(user);
} catch (IOException e) {
    e.printStackTrace();
} finally {
    IOUtils.closeQuietly(oos);
}

//Read Obj from File
File file = new File("tempFile");
ObjectInputStream ois = null;
try {
    ois = new ObjectInputStream(new FileInputStream(file));
    User1 newUser = (User1) ois.readObject();
    System.out.println(newUser);
} catch (IOException e) {
    e.printStackTrace();
} catch (ClassNotFoundException e) {
    e.printStackTrace();
} finally {
    IOUtils.closeQuietly(ois);
    try {
        FileUtils.forceDelete(file);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

//Initializes The Object
User1 user = new User1();
user.setName("hollis");
user.setAge(23);
System.out.println(user);

//Write Obj to File
ObjectOutputStream oos = null;
try {
    oos = new ObjectOutputStream(new FileOutputStream("tempFile"));
    oos.writeObject(user);
} catch (IOException e) {
    e.printStackTrace();
} finally {
    IOUtils.closeQuietly(oos);
}

//Read Obj from File
File file = new File("tempFile");
ObjectInputStream ois = null;
try {
    ois = new ObjectInputStream(new FileInputStream(file));
    User1 newUser = (User1) ois.readObject();
    System.out.println(newUser);
} catch (IOException e) {
    e.printStackTrace();
} catch (ClassNotFoundException e) {
    e.printStackTrace();
} finally {
    IOUtils.closeQuietly(ois);
    try {
        FileUtils.forceDelete(file);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Чтение и запись файлов с помощью NIO.

static void readNIO() {
        String pathname = "C:\\Users\\adew\\Desktop\\jd-gui.cfg";
        FileInputStream fin = null;
        try {
            fin = new FileInputStream(new File(pathname));
            FileChannel channel = fin.getChannel();

            int capacity = 100;// 字节
            ByteBuffer bf = ByteBuffer.allocate(capacity);
            int length = -1;

            while ((length = channel.read(bf)) != -1) {

                bf.clear();
                byte[] bytes = bf.array();
                System.out.write(bytes, 0, length);
                System.out.println();
            }

            channel.close();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fin != null) {
                try {
                    fin.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    static void writeNIO() {
        String filename = "out.txt";
        FileOutputStream fos = null;
        try {

            fos = new FileOutputStream(new File(filename));
            FileChannel channel = fos.getChannel();
            ByteBuffer src = Charset.forName("utf8").encode("你好你好你好你好你好");
            int length = 0;

            while ((length = channel.write(src)) != 0) {
                System.out.println("写入长度:" + length);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

Чтение и запись файлов с помощью AIO

public class ReadFromFile {
  public static void main(String[] args) throws Exception {
    Path file = Paths.get("/usr/a.txt");
    AsynchronousFileChannel channel = AsynchronousFileChannel.open(file);

    ByteBuffer buffer = ByteBuffer.allocate(100_000);
    Future<Integer> result = channel.read(buffer, 0);

    while (!result.isDone()) {
      ProfitCalculator.calculateTax();
    }
    Integer bytesRead = result.get();
    System.out.println("Bytes read [" + bytesRead + "]");
  }
}
class ProfitCalculator {
  public ProfitCalculator() {
  }
  public static void calculateTax() {
  }
}

public class WriteToFile {

  public static void main(String[] args) throws Exception {
    AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(
        Paths.get("/asynchronous.txt"), StandardOpenOption.READ,
        StandardOpenOption.WRITE, StandardOpenOption.CREATE);
    CompletionHandler<Integer, Object> handler = new CompletionHandler<Integer, Object>() {

      @Override
      public void completed(Integer result, Object attachment) {
        System.out.println("Attachment: " + attachment + " " + result
            + " bytes written");
        System.out.println("CompletionHandler Thread ID: "
            + Thread.currentThread().getId());
      }

      @Override
      public void failed(Throwable e, Object attachment) {
        System.err.println("Attachment: " + attachment + " failed with:");
        e.printStackTrace();
      }
    };

    System.out.println("Main Thread ID: " + Thread.currentThread().getId());
    fileChannel.write(ByteBuffer.wrap("Sample".getBytes()), 0, "First Write",
        handler);
    fileChannel.write(ByteBuffer.wrap("Box".getBytes()), 0, "Second Write",
        handler);

  }
}

Капля капля капля, вода закипела.