Java I/O操作

news2024/10/5 17:24:07

引言

在Java编程中,输入和输出(I/O)操作是必不可少的部分。Java I/O通过一系列流(Stream)类和方法,支持文件操作、控制台输入输出、网络I/O等多种I/O操作。本文将详细介绍Java I/O的基础概念、文件操作、字符流与字节流的区别、序列化与反序列化以及新的I/O(NIO)等内容,并通过表格进行总结和示范。

Java I/O基础概念

流的概念

流(Stream)是指数据的流动,是一个顺序读写数据的抽象。Java定义了两种基本类型的流:

  • 字节流:用于处理字节数据,最基础的类是InputStreamOutputStream
  • 字符流:用于处理字符数据,最基础的类是ReaderWriter

流的分类

Java I/O流可以按照数据类型分类为字节流和字符流,也可以按照数据流向分为输入流和输出流。

类型输入流输出流
字节流InputStreamOutputStream
字符流ReaderWriter

文件与目录操作

文件类(File)

File类表示文件或目录,可以对其进行创建、删除、获取信息等操作。

import java.io.File;
import java.io.IOException;

public class FileExample {
    public static void main(String[] args) {
        // 创建一个File对象
        File file = new File("example.txt");

        try {
            // 创建新文件
            if (file.createNewFile()) {
                System.out.println("File created: " + file.getName());
            } else {
                System.out.println("File already exists.");
            }

            // 获取文件信息
            System.out.println("Absolute path: " + file.getAbsolutePath());
            System.out.println("Writable: " + file.canWrite());
            System.out.println("Readable: " + file.canRead());
            System.out.println("File size in bytes: " + file.length());

        } catch (IOException e) {
            System.out.println("An error occurred.");
            e.printStackTrace();
        }
    }
}

文件与目录操作方法表

方法描述示例
createNewFile()创建一个新的文件file.createNewFile();
delete()删除文件或目录file.delete();
exists()判断文件或目录是否存在file.exists();
getAbsolutePath()获取文件的绝对路径file.getAbsolutePath();
canWrite()判断文件是否可写file.canWrite();
canRead()判断文件是否可读file.canRead();
length()获取文件大小(字节)file.length();

字符流和字节流

字节流

字节流用于处理字节数据,通过InputStreamOutputStream类及其子类进行输入输出操作。

示例:使用FileInputStreamFileOutputStream进行文件字节操作

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class ByteStreamExample {
    public static void main(String[] args) {
        try (FileInputStream fis = new FileInputStream("input.txt");
             FileOutputStream fos = new FileOutputStream("output.txt")) {

            int byteData;
            // 逐字节读取数据
            while ((byteData = fis.read()) != -1) {
                // 逐字节写入数据
                fos.write(byteData);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

字符流

字符流用于处理字符数据,通过ReaderWriter类及其子类进行输入输出操作。

示例:使用FileReaderFileWriter进行文件字符操作

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class CharStreamExample {
    public static void main(String[] args) {
        try (FileReader fr = new FileReader("input.txt");
             FileWriter fw = new FileWriter("output.txt")) {

            int charData;
            // 逐字符读取数据
            while ((charData = fr.read()) != -1) {
                // 逐字符写入数据
                fw.write(charData);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

字符流和字节流的比较表

特性字节流字符流
基本类InputStream 和 OutputStreamReader 和 Writer
数据处理单位字节(8位)字符(16位)
适用场景二进制数据(如图像、音频)文本数据(如文本文件)
典型实现类FileInputStreamFileOutputStreamFileReaderFileWriter

序列化与反序列化

序列化

序列化是将对象转换为字节流并写到文件或网络中的过程。实现Serializable接口的类可以被序列化。

示例:对象序列化

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;

class Person implements Serializable {
    private static final long serialVersionUID = 1L;
    String name;
    int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

public class SerializationExample {
    public static void main(String[] args) {
        Person person = new Person("John", 30);

        try (FileOutputStream fos = new FileOutputStream("person.ser");
             ObjectOutputStream oos = new ObjectOutputStream(fos)) {

            oos.writeObject(person);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

反序列化

反序列化是将字节流转换为对象的过程。读取序列化文件时使用ObjectInputStream

示例:对象反序列化

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class DeserializationExample {
    public static void main(String[] args) {
        try (FileInputStream fis = new FileInputStream("person.ser");
             ObjectInputStream ois = new ObjectInputStream(fis)) {

            Person person = (Person) ois.readObject();
            System.out.println("Name: " + person.name);
            System.out.println("Age: " + person.age);

        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

序列化与反序列化的表格总结

概念描述示例
序列化将对象转换为字节流并写到文件或网络中ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("file.ser")); oos.writeObject(object);
反序列化将字节流转换为对象ObjectInputStream ois = new ObjectInputStream(new FileInputStream("file.ser")); Object obj = ois.readObject();
必需接口需要实现 Serializable 接口class Person implements Serializable { ... }
序列化ID建议定义 serialVersionUID 字段应避免反序列化不兼容private static final long serialVersionUID = 1L;

新的I/O (NIO)

Java的新的I/O(NIO)引入了多个新概念,如缓冲区、通道和选择器。这些概念提供了更高效的I/O处理,特别是在处理大数据和高性能网络应用方面。下面我们将详细介绍这些概念。

缓冲区(Buffer)

缓冲区是NIO数据操作的基础,用于存储和操作数据。Java NIO提供了多种类型的缓冲区,比如ByteBufferCharBuffer等。

示例:使用ByteBuffer

import java.nio.ByteBuffer;

public class BufferExample {
    public static void main(String[] args) {
        // 创建一个大小为10的字节缓冲区
        ByteBuffer buffer = ByteBuffer.allocate(10);

        // 写入数据到缓冲区
        buffer.put((byte) 1);
        buffer.put((byte) 2);

        // 切换到读模式
        buffer.flip();

        // 读取缓冲区中的数据
        while (buffer.hasRemaining()) {
            byte data = buffer.get();
            System.out.println(data);
        }
    }
}

通道(Channel)

通道是一个连接数据源和缓冲区的通道,数据可以通过通道从数据源读入缓冲区,或从缓冲区写入到数据源。常用的通道有FileChannelSocketChannelServerSocketChannel等。

示例:使用FileChannel

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;

public class ChannelExample {
    public static void main(String[] args) {
        // 文件路径
        Path path = Path.of("example.txt");

        // 使用文件通道写入数据
        try (FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
            ByteBuffer buffer = ByteBuffer.allocate(64);
            buffer.put("Hello, NIO!".getBytes());
            buffer.flip();
            fileChannel.write(buffer);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 使用文件通道读取数据
        try (FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.READ)) {
            ByteBuffer buffer = ByteBuffer.allocate(64);
            fileChannel.read(buffer);
            buffer.flip();

            while (buffer.hasRemaining()) {
                System.out.print((char) buffer.get());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

选择器(Selector)

选择器是NIO中的多路复用器,可以用于管理多个通道,特别适用于网络编程。SelectorSelectableChannel配合使用,可以高效地处理非阻塞I/O操作。

示例:使用Selector进行非阻塞I/O

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class SelectorExample {
    public static void main(String[] args) {
        try {
            // 打开选择器
            Selector selector = Selector.open();

            // 打开服务器套接字通道
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
            serverSocketChannel.socket().bind(new InetSocketAddress(8080));
            serverSocketChannel.configureBlocking(false);

            // 将通道注册到选择器,并监听接受事件
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

            // 循环等待事件
            while (true) {
                selector.select();
                Set<SelectionKey> selectedKeys = selector.selectedKeys();
                Iterator<SelectionKey> iterator = selectedKeys.iterator();

                while (iterator.hasNext()) {
                    SelectionKey key = iterator.next();
                    iterator.remove();

                    if (key.isAcceptable()) {
                        // 接受新连接
                        ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
                        SocketChannel socketChannel = serverChannel.accept();
                        socketChannel.configureBlocking(false);
                        socketChannel.register(selector, SelectionKey.OP_READ);
                    } else if (key.isReadable()) {
                        // 读取数据
                        SocketChannel socketChannel = (SocketChannel) key.channel();
                        ByteBuffer buffer = ByteBuffer.allocate(256);
                        socketChannel.read(buffer);
                        buffer.flip();
                        System.out.println("Received: " + new String(buffer.array()).trim());
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

NIO关键概念表格总结

概念描述示例
缓冲区(Buffer)用于存储数据的容器,可以是字节、字符、短整型等ByteBuffer buffer = ByteBuffer.allocate(10);
通道(Channel)用于连接数据源与缓冲区,实现I/O操作FileChannel.open(path, StandardOpenOption.READ);
选择器(Selector)用于管理多个通道,实现非阻塞I/O的多路复用Selector.open(); selector.select();

表格总结

文件与目录操作方法表

方法描述示例
createNewFile()创建一个新的文件file.createNewFile();
delete()删除文件或目录file.delete();
exists()判断文件或目录是否存在file.exists();
getAbsolutePath()获取文件的绝对路径file.getAbsolutePath();
canWrite()判断文件是否可写file.canWrite();
canRead()判断文件是否可读file.canRead();
length()获取文件大小(字节)file.length();

字符流和字节流的比较表

特性字节流字符流
基本类InputStream 和 OutputStreamReader 和 Writer
数据处理单位字节(8位)字符(16位)
适用场景二进制数据(如图像、音频)文本数据(如文本文件)
典型实现类FileInputStreamFileOutputStreamFileReaderFileWriter

序列化与反序列化的表格总结

概念描述示例
序列化将对象转换为字节流并写到文件或网络中ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("file.ser")); oos.writeObject(object);
反序列化将字节流转换为对象ObjectInputStream ois = new ObjectInputStream(new FileInputStream("file.ser")); Object obj = ois.readObject();
必需接口需要实现 Serializable 接口class Person implements Serializable { ... }
序列化ID建议定义 serialVersionUID 字段以避免反序列化不兼容private static final long serialVersionUID = 1L;

NIO关键概念表格总结

概念描述示例
缓冲区(Buffer)用于存储数据的容器,可以是字节、字符、短整型等ByteBuffer buffer = ByteBuffer.allocate(10);
通道(Channel)用于连接数据源与缓冲区,实现I/O操作FileChannel.open(path, StandardOpenOption.READ);
选择器(Selector)用于管理多个通道,实现非阻塞I/O的多路复用Selector.open(); selector.select();

总结

本文详细介绍了Java I/O操作,包括文件和目录操作、字符流与字节流的区别、序列化与反序列化、新的I/O(NIO)等内容。通过示例代码和表格总结,帮助您更好地理解和应用Java中的I/O操作,提高程序的读取和写入效率。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1830451.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SQL注入攻击

网站是什么工作的&#xff1f; php写的代码电脑不认识&#xff0c;脚本引擎就是做翻译的&#xff0c;把高级代码翻译为机器语言 访问网站的地址&#xff0c;不同的新闻的id是不一样的&#xff0c;就是对应数据库的不同位置 这里面一个ip地址对应三个网站&#xff08;怎么能对应…

JavaScript领域的五大AI工程利器

五大引领AI工程的JavaScript工具&#xff0c;为欲将LLM融入项目的开发者提供关键资源。 译自Top 5 JavaScript Tools for AI Engineering&#xff0c;作者 Alexander T. Williams。 传统上以在网页开发中扮演角色而闻名的JavaScript&#xff0c;令许多人惊讶的是&#xff0c;它…

CAN测试工具——BUSMASTER

文章目录 推荐理由一、菜单栏Transmit WindowDiagnostics二、Tools推荐理由 BUSMASTER是一个用于设计,监测,分析与模拟CAN网络的开源的开放式总线PC软件. 1) 可以和十几种常用CAN总线硬件兼容。比如:IXXAT、PEAK、Kvaser、CANcase XL等。 2)免费,开源 https://rbei-etas.g…

pandas获取某列最大值的所有数据

第一种方法&#xff1a; 按照某列进行由大到小的排序&#xff0c;然后再进去去重&#xff0c;保留第一个值&#xff0c;最终保留的结果就是最大值的数据 # 由大到小排序 data_frame data_frame.sort_values(bycolumn_a, ascendingFalse)# 按照column_b列去重保留第一条&#…

人工智能在数字病理领域的最新进展|顶刊速递·24-06-14

小罗碎碎念 文献主题&#xff1a;人工智能在【数字病理】领域的最新进展 今天在写这篇推文的时候&#xff0c;脑子里就一个念头——大模型的风&#xff0c;终于还是卷到了病理学领域。 这是一个好事哈&#xff0c;如果我们搞病理研究的&#xff0c;也能有一个像Chatgpt一样的工…

如何使用 pip 卸载所有已安装的 Python 包?

在开发过程中&#xff0c;我们可能会安装许多 Python 包&#xff0c;有时需要彻底清理环境&#xff0c;以便从头开始或者解决冲突问题。下面将介绍如何使用 pip 命令卸载所有已安装的 Python 包。 一、列出所有已安装的包 首先&#xff0c;需要列出当前环境中所有已安装的包。…

开源模型应用落地-LangChain高阶-LCEL-表达式语言(七)

一、前言 尽管现在的大语言模型已经非常强大&#xff0c;可以解决许多问题&#xff0c;但在处理复杂情况时&#xff0c;仍然需要进行多个步骤或整合不同的流程才能达到最终的目标。然而&#xff0c;现在可以利用langchain来使得模型的应用变得更加直接和简单。 LCEL是什么&…

树状数组练习

先看一下最后一题&#xff0c;这是一个树状数组的题目&#xff0c;那就水一下吧,但是由于没有注意问题&#xff0c;wa了很多次 const int N (int)1e5 5; int n; int flag[N]; int dp[N]; class Solution { public:vector<int> countOfPeaks(vector<int>& num…

【秋招突围】2024届秋招笔试-小红书笔试题-第二套-三语言题解(Java/Cpp/Python)

&#x1f36d; 大家好这里是清隆学长 &#xff0c;一枚热爱算法的程序员 ✨ 本系计划跟新各公司春秋招的笔试题 &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f497; &#x1f4e7; 清隆这边…

意大利罗马3日自由行攻略

欢迎关注「苏南下」 在这里分享我的旅行和影像创作心得 今天来和大家聊聊我个人很喜欢的一座城市—意大利罗马。 作为意大利的首都&#xff0c;罗马自公元前753年建成至今&#xff0c;有超过2700年的历史&#xff0c;被誉为“永恒之城”。走在罗马街头&#xff0c;几乎看不到一…

使用 Python 进行测试(3)pytest setup

总结 我们前进到更真实的项目&#xff1a; less_basic_project ├── my_awesome_package │ ├── calculation_engine.py │ ├── __init__.py │ ├── permissions.py ├── pyproject.toml └── tests├── conftest.py├── test_calculation_engine.p…

283. 移动零 (Swift版本)

题目描述 最容易想到的解法 从后向前遍历, 发现0就通过交换相邻元素将0移动到最后 class Solution {func moveZeroes(_ nums: inout [Int]) {for index in (0..<nums.count).reversed() {if nums[index] 0 {moveZeroes(&nums, index)}}}func moveZeroes(_ nums: inout …

Mybatis plus join 一对多语法

一对多案例&#xff08;set集合&#xff09; 1. 实体类 题目 package co.yixiang.exam.entity;import co.yixiang.domain.BaseDomain; import co.yixiang.exam.config.CustomStringListDeserializer; import com.baomidou.mybatisplus.annotation.TableField; import com.fa…

youlai-boot项目的学习—本地数据库安装与配置

数据库脚本 在项目代码的路径下&#xff0c;有两个版本的mysql数据库脚本&#xff0c;使用对应的脚本就安装对应的数据库版本&#xff0c;本文件选择了5 数据库安装 这里在iterm2下使用homebrew安装mysql5 brew install mysql5.7注&#xff1a;记得配置端终下的科学上网&a…

PHP7 数组的实现

前提 PHP版本&#xff1a;php7.0.29使用到的文件 php-src/Zend/zend_types.hphp-src/Zend/zend_hash.hphp-src/Zend/zend_hash.cphp-src/Zend/zend_string.h 本文 是《PHP7底层设计和源码实现》第5章 数组的实现&#xff0c;学习笔记 功能分析 整体结构 bucket 里面增加h字段…

android studio CreateProcess error=2, 系统找不到指定的文件

【问题记录篇】 在AndroidStudio编译开发jni相关工程代码的时候&#xff0c;编译遇到的这个报错&#xff1a; CreateProcess error2, 系统找不到指定的文件。排查处理步骤: 先查看Build Output的具体日志输出 2.了解到问题出在了NDK配置上&#xff0c;此时需要根据自己的gra…

RTOS实时操作系统

常见的RTOS有&#xff1a; VxWorks&#xff1a;广泛应用于工业、医疗、通信和航空航天领域。FreeRTOS&#xff1a;一个开源的RTOS&#xff0c;广泛用于嵌入式设备。uc/OS&#xff1a;一个适用于教育和小型商业项目的RTOS。QNX&#xff1a;主要应用于汽车和工业自动化领域。Win…

第 2 章:Spring Framework 中的 IoC 容器

控制反转&#xff08;Inversion of Control&#xff0c;IoC&#xff09;与 面向切面编程&#xff08;Aspect Oriented Programming&#xff0c;AOP&#xff09;是 Spring Framework 中最重要的两个概念&#xff0c;本章会着重介绍前者&#xff0c;内容包括 IoC 容器以及容器中 …

Android-茫茫9个月求职路,终于拿满意offer

线程和进程的区别&#xff1f;为什么要有线程&#xff0c;而不是仅仅用进程&#xff1f;算法判断单链表成环与否&#xff1f;如何实现线程同步&#xff1f;hashmap数据结构&#xff1f;arraylist 与 linkedlist 异同&#xff1f;object类的equal 和hashcode 方法重写&#xff0…

免费分享:2017-2021全球10m土地利用数据(esri)(附下载方法)

美国环境系统研究所公司&#xff08;Environmental Systems Research Institute, Inc. 简称ESRI公司&#xff09;&#xff0c;以其先进的ArcGIS解决方案&#xff0c;为全球各行业提供多层次、可扩展、功能强大且开放性强的GIS技术。哨兵2号&#xff08;Sentinel-2&#xff09;是…