学做网站培训,龙岩市建筑设计院,网站视觉风格,深圳最新消息文章目录 一、简介二、字节流与字符流1. 字节流#xff08;InputStream、OutputStream#xff09;介绍与用法2. 字符流#xff08;Reader、Writer#xff09;介绍与用法 三、文件操作与目录遍历1. File类的基本使用2. 目录遍历与递归操作 四、序列化与反序列化1. 序列化与反… 文章目录 一、简介二、字节流与字符流1. 字节流InputStream、OutputStream介绍与用法2. 字符流Reader、Writer介绍与用法 三、文件操作与目录遍历1. File类的基本使用2. 目录遍历与递归操作 四、序列化与反序列化1. 序列化与反序列化概念和作用2. 实现Serializable接口的对象序列化3. 自定义序列化与反序列化 五、NIO与异步IO1. NIO概述及与传统IO的区别2. 缓冲区(Buffer)的使用3. 通道(Channel)的基本使用4. 选择器(Selector)的使用 一、简介 Java IO概述 Java的IO输入/输出是用于处理与外部设备、文件和网络资源之间数据传输的机制。它提供了一套丰富的类和方法用于读取和写入数据并提供了灵活的处理方式。 IO模型和IO流的概念 IO模型是指描述程序与外部设备进行数据交换的方式主要有阻塞IO模型和非阻塞IO模型。阻塞IO模型是指程序在进行IO操作时会阻塞等待返回结果而非阻塞IO模型是指程序在进行IO操作时可以继续执行其他任务不需要等待返回结果。
IO流是Java中用来处理输入和输出的抽象概念。它将数据的输入和输出视为连续的数据流通过流的方式进行读取和写入操作。Java中的IO流分为字节流和字符流两种类型分别对应处理字节数据和字符数据。
Java IO类库的分类和用途 Java的IO类库可以分为两个大类字节流和字符流。
字节流以字节为单位进行读写操作主要包括InputStream和OutputStream两个类用于处理二进制数据例如图片、视频等。字符流以字符为单位进行读写操作主要包括Reader和Writer两个类用于处理文本数据例如文本文件等。
除了字节流和字符流Java的IO类库还提供了许多其他类和接口用于处理特定类型的数据或提供更高级别的功能例如处理文件、网络通信等。
总结起来Java的IO类库提供了丰富的工具和方法来进行各种输入和输出操作能够满足不同场景下的需求。
二、字节流与字符流
1. 字节流InputStream、OutputStream介绍与用法
// 1.1 输入字节流的基本使用FileInputStream、ByteArrayInputStream等// 使用FileInputStream读取文件内容
try (InputStream inputStream new FileInputStream(file.txt)) {int data;while ((data inputStream.read()) ! -1) {// 处理读取到的字节数据System.out.print((char) data);}
} catch (IOException e) {e.printStackTrace();
}// 1.2 输出字节流的基本使用FileOutputStream、ByteArrayOutputStream等// 使用FileOutputStream写入数据到文件
try (OutputStream outputStream new FileOutputStream(file.txt)) {String data Hello, World!;outputStream.write(data.getBytes());
} catch (IOException e) {e.printStackTrace();
}// 1.3 使用缓冲字节流提高IO性能BufferedInputStream、BufferedOutputStream等// 使用BufferedInputStream读取文件内容
try (InputStream inputStream new BufferedInputStream(new FileInputStream(file.txt))) {int data;while ((data inputStream.read()) ! -1) {// 处理读取到的字节数据System.out.print((char) data);}
} catch (IOException e) {e.printStackTrace();
}// 使用BufferedOutputStream写入数据到文件
try (OutputStream outputStream new BufferedOutputStream(new FileOutputStream(file.txt))) {String data Hello, World!;outputStream.write(data.getBytes());
} catch (IOException e) {e.printStackTrace();
}2. 字符流Reader、Writer介绍与用法
// 2.1 输入字符流的基本使用FileReader、StringReader等// 使用FileReader读取文件内容
try (Reader reader new FileReader(file.txt)) {int data;while ((data reader.read()) ! -1) {// 处理读取到的字符数据System.out.print((char) data);}
} catch (IOException e) {e.printStackTrace();
}// 2.2 输出字符流的基本使用FileWriter、StringWriter等// 使用FileWriter写入数据到文件
try (Writer writer new FileWriter(file.txt)) {String data Hello, World!;writer.write(data);
} catch (IOException e) {e.printStackTrace();
}// 2.3 使用缓冲字符流提高IO性能BufferedReader、BufferedWriter等// 使用BufferedReader读取文件内容
try (Reader reader new BufferedReader(new FileReader(file.txt))) {int data;while ((data reader.read()) ! -1) {// 处理读取到的字符数据System.out.print((char) data);}
} catch (IOException e) {e.printStackTrace();
}// 使用BufferedWriter写入数据到文件
try (Writer writer new BufferedWriter(new FileWriter(file.txt))) {String data Hello, World!;writer.write(data);
} catch (IOException e) {e.printStackTrace();
}三、文件操作与目录遍历
1. File类的基本使用
// 1.1 创建、删除和重命名文件
File file new File(file.txt);try {// 创建文件if (file.createNewFile()) {System.out.println(文件创建成功);}// 删除文件if (file.delete()) {System.out.println(文件删除成功);}// 重命名文件File newFile new File(newFile.txt);if (file.renameTo(newFile)) {System.out.println(文件重命名成功);}
} catch (IOException e) {e.printStackTrace();
}// 1.2 获取文件信息大小、路径、修改时间等
File file new File(file.txt);System.out.println(文件大小 file.length() 字节);
System.out.println(文件路径 file.getAbsolutePath());
System.out.println(最后修改时间 new Date(file.lastModified()));// 1.3 文件遍历与过滤
File dir new File(directory);// 遍历文件夹下的所有文件和子文件夹
for (File file : dir.listFiles()) {if (file.isFile()) {System.out.println(文件 file.getName());} else if (file.isDirectory()) {System.out.println(文件夹 file.getName());}
}2. 目录遍历与递归操作
// 2.1 递归遍历目录下的文件
public static void listFiles(File directory) {File[] files directory.listFiles();if (files ! null) {for (File file : files) {if (file.isFile()) {System.out.println(文件 file.getName());} else if (file.isDirectory()) {System.out.println(文件夹 file.getName());listFiles(file);}}}
}// 调用递归遍历目录
listFiles(new File(directory));// 2.2 搜索指定类型的文件
public static void searchFiles(File directory, String extension) {File[] files directory.listFiles();if (files ! null) {for (File file : files) {if (file.isFile() file.getName().endsWith(extension)) {System.out.println(符合条件的文件 file.getName());} else if (file.isDirectory()) {searchFiles(file, extension);}}}
}// 调用搜索指定类型的文件
searchFiles(new File(directory), .txt);// 2.3 统计目录大小
public static long calculateDirectorySize(File directory) {long size 0;File[] files directory.listFiles();if (files ! null) {for (File file : files) {if (file.isFile()) {size file.length();} else if (file.isDirectory()) {size calculateDirectorySize(file);}}}return size;
}// 获取目录大小
long size calculateDirectorySize(new File(directory));
System.out.println(目录大小 size 字节);四、序列化与反序列化
1. 序列化与反序列化概念和作用
序列化是将对象转换为字节序列的过程用于对象的持久化或网络传输。反序列化是将字节序列转换回对象的过程。
2. 实现Serializable接口的对象序列化
// 2.1 序列化对象到文件
try (OutputStream outputStream new FileOutputStream(object.ser)) {ObjectOutputStream objectOutputStream new ObjectOutputStream(outputStream);MyObject myObject new MyObject();objectOutputStream.writeObject(myObject);System.out.println(对象序列化成功);
} catch (IOException e) {e.printStackTrace();
}// 2.2 从文件反序列化对象
try (InputStream inputStream new FileInputStream(object.ser)) {ObjectInputStream objectInputStream new ObjectInputStream(inputStream);MyObject myObject (MyObject) objectInputStream.readObject();System.out.println(对象反序列化成功);
} catch (IOException | ClassNotFoundException e) {e.printStackTrace();
}// 2.3 序列化对象到字节数组
try (ByteArrayOutputStream byteArrayOutputStream new ByteArrayOutputStream()) {ObjectOutputStream objectOutputStream new ObjectOutputStream(byteArrayOutputStream);MyObject myObject new MyObject();objectOutputStream.writeObject(myObject);byte[] bytes byteArrayOutputStream.toByteArray();System.out.println(对象序列化成功字节数组长度 bytes.length);
} catch (IOException e) {e.printStackTrace();
}3. 自定义序列化与反序列化
// 3.1 实现Externalizable接口
public class MyObject implements Externalizable {private String data;// 必须提供默认构造方法public MyObject() {}// 实现writeExternal方法手动控制序列化字段Overridepublic void writeExternal(ObjectOutput out) throws IOException {out.writeObject(data);}// 实现readExternal方法手动控制反序列化字段Overridepublic void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {data (String) in.readObject();}
}// 3.2 控制序列化的过程writeObject、readObject方法
public class MyObject implements Serializable {private String data;private void writeObject(ObjectOutputStream out) throws IOException {out.defaultWriteObject();// 手动调用其他操作}private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {in.defaultReadObject();// 手动调用其他操作}
}// 3.3 解决序列化版本兼容性问题
public class MyObject implements Serializable {private static final long serialVersionUID 1L;...
}五、NIO与异步IO
1. NIO概述及与传统IO的区别
NIONew I/O是Java提供的一种基于通道和缓冲区的IO模型相比传统的IO模型NIO具有更高的效率和灵活性。
2. 缓冲区(Buffer)的使用
// 2.1 ByteBuffer、CharBuffer等缓冲区类型
ByteBuffer byteBuffer ByteBuffer.allocate(1024);
CharBuffer charBuffer CharBuffer.allocate(1024);// 2.2 缓冲区的读写操作
byteBuffer.put((byte) H);
byteBuffer.put((byte) e);
byteBuffer.put((byte) l);
byteBuffer.put((byte) l);
byteBuffer.put((byte) o);
byteBuffer.flip();while (byteBuffer.hasRemaining()) {System.out.print((char) byteBuffer.get());
}3. 通道(Channel)的基本使用
// 3.1 文件Channel的读写操作
try (RandomAccessFile file new RandomAccessFile(file.txt, rw);FileChannel channel file.getChannel()) {ByteBuffer buffer ByteBuffer.allocate(1024);int bytesRead channel.read(buffer);while (bytesRead ! -1) {buffer.flip();while (buffer.hasRemaining()) {System.out.print((char) buffer.get());}buffer.clear();bytesRead channel.read(buffer);}
} catch (IOException e) {e.printStackTrace();
}// 3.2 Socket Channel和Server Socket Channel的使用
try (SocketChannel socketChannel SocketChannel.open()) {socketChannel.connect(new InetSocketAddress(example.com, 80));if (socketChannel.isConnected()) {System.out.println(连接成功);ByteBuffer buffer ByteBuffer.allocate(1024);socketChannel.read(buffer);buffer.flip();while (buffer.hasRemaining()) {System.out.print((char) buffer.get());}}
} catch (IOException e) {e.printStackTrace();
}4. 选择器(Selector)的使用
选择器Selector是Java NIONew IO中的一个重要组件用于实现非阻塞IO操作。它可以通过单个线程处理多个通道Channel从而提高系统的IO处理效率。
下面是使用选择器的基本步骤 创建选择器使用Selector.open()方法创建一个Selector对象。 Selector selector Selector.open();注册通道将需要监听IO事件的通道注册到选择器上。通道可以是一些可读、可写或可接受连接的网络通道例如SocketChannel、ServerSocketChannel等。 channel.configureBlocking(false); // 设置通道为非阻塞模式
SelectionKey key channel.register(selector, interestOps);其中interestOps参数表示对该通道感兴趣的事件类型包括SelectionKey.OP_READ可读事件、SelectionKey.OP_WRITE可写事件、SelectionKey.OP_ACCEPT可接受连接事件等。 选择就绪通道使用selector.select()方法来选择已经准备好进行IO操作的通道。该方法会阻塞直到至少有一个通道准备好或者超时时间到达。 int readyChannels selector.select();处理就绪通道使用selector.selectedKeys()方法获取选择器中已经就绪的键集合然后遍历处理每个键对应的通道和事件。 SetSelectionKey selectedKeys selector.selectedKeys();
for (SelectionKey key : selectedKeys) {if (key.isReadable()) {// 处理可读事件} else if (key.isWritable()) {// 处理可写事件} else if (key.isAcceptable()) {// 处理可接受连接事件}// 其他事件处理...
}取消选择键在处理完通道后一般需要将其对应的选择键取消防止重复处理。 key.cancel();关闭选择器使用selector.close()方法关闭选择器释放资源。 selector.close();使用选择器可以实现单个线程管理多个通道提高了系统的IO处理效率。它适用于需要同时处理多个IO操作、提高系统吞吐量的场景例如网络编程中的服务器端。
// 4.1 注册通道到选择器
try (ServerSocketChannel serverSocketChannel ServerSocketChannel.open();Selector selector Selector.open()) {serverSocketChannel.bind(new InetSocketAddress(8080));serverSocketChannel.configureBlocking(false);serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);while (true) {selector.select();SetSelectionKey selectedKeys selector.selectedKeys();for (SelectionKey key : selectedKeys) {if (key.isAcceptable()) {// 处理接收事件ServerSocketChannel channel (ServerSocketChannel) key.channel();SocketChannel socketChannel channel.accept();// ...} else if (key.isReadable()) {// 处理读取事件SocketChannel channel (SocketChannel) key.channel();ByteBuffer buffer ByteBuffer.allocate(1024);int bytesRead channel.read(buffer);// ...}selectedKeys.remove(key);}}
} catch (IOException e) {e.printStackTrace();
}// 4.2 监听通道事件
try (DatagramChannel datagramChannel DatagramChannel.open();Selector selector Selector.open()) {datagramChannel.bind(new InetSocketAddress(8080));datagramChannel.configureBlocking(false);datagramChannel.register(selector, SelectionKey.OP_READ);while (true) {selector.select();SetSelectionKey selectedKeys selector.selectedKeys();for (SelectionKey key : selectedKeys) {if (key.isReadable()) {// 处理读取事件DatagramChannel channel (DatagramChannel) key.channel();ByteBuffer buffer ByteBuffer.allocate(1024);SocketAddress sender channel.receive(buffer);// ...}selectedKeys.remove(key);}}
} catch (IOException e) {e.printStackTrace();
}// 4.3 多路复用(IO多路复用)
try (Selector selector Selector.open()) {SocketChannel channel1 SocketChannel.open(new InetSocketAddress(example.com, 80));SocketChannel channel2 SocketChannel.open(new InetSocketAddress(example.org, 80));channel1.configureBlocking(false);channel2.configureBlocking(false);channel1.register(selector, SelectionKey.OP_READ);channel2.register(selector, SelectionKey.OP_READ);while (true) {selector.select();SetSelectionKey selectedKeys selector.selectedKeys();for (SelectionKey key : selectedKeys) {if (key.isReadable()) {// 处理读取事件SocketChannel channel (SocketChannel) key.channel();ByteBuffer buffer ByteBuffer.allocate(1024);channel.read(buffer);// ...}}}
} catch (IOException e) {e.printStackTrace();
}简介本文介绍了Java中的IO类库包括字节流、字符流的基本使用文件操作与目录遍历序列化与反序列化以及NIO与异步IO的概念与使用。通过学习本文读者能够掌握Java IO类的基本用法和核心概念并且理解NIO的特点和优势。