В выходной день во время телефонного интервью дома я задал собеседнику несколько вопросов о 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);
}
}
Капля капля капля, вода закипела.