Java I/O操作

引言

在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操作,提高程序的读取和写入效率。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++之函数重载

函数重载概念&#xff1a; 是函数的一种特殊情况&#xff0c; C 允许在 同一作用域中 声明几个功能类似 的同名函数 &#xff0c;这 些同名函数的 形参列表(参数个数 或 类型 或 类型顺序)不同 &#xff0c;常用来处理实现功能类似数据类型 不同的问题。 #include<iostre…

struts2框架漏洞

title: struts2框架漏洞 categories: 漏洞复现 abbrlink: 48203 date: 2024-06-14 15:45:27 前言知识 ognl表达式注入 对象导航图语言&#xff0c;用于访问对象的字段、方法。基于简化访问java对象属性和调用方法需求&#xff0c;实现字段类型转化等功能&#xff1b;访问列表…

详情资料SR560(斯坦福)SR570 低噪声前置放大器

SR560 低噪声前置放大器 SR560 是一款高性能、低噪声前置放大器&#xff0c;非常适合各种应用&#xff0c;包括低温测量、光学检测和音频工程。 输入 SR560 有一个差分前端&#xff0c;输入噪声为 4 nV/√Hz&#xff0c;输入阻抗为 100 MΩ。完整的噪声系数轮廓如下图所示。…

深度解析响应式异步编程模型

上一篇文章中我们聊了一下线程池,基于线程池的多线程编程是我们在高并发场景下提升系统处理效率的有效手段,但却不是唯一的。今天我们来看一下另一种异步开发的常用手段-响应式编程模型 传统多线程模型的缺陷 多线程模型是目前应用最为广泛的并发编程手段,但凡遇到什么性能…

斯坦福SR810和SR830 DSP锁定放大器

SR810 和 SR830 DSP 锁定放大器 SR810 锁定放大器和 SR830锁定放大器以合理的成本提供高性能。SR830 同时显示信号的幅度和相位&#xff0c;而 SR810 仅显示幅度。两种仪器都使用数字信号处理 (DSP) 来代替传统锁定中的解调器、输出滤波器和放大器。SR810 和 SR830 具有 1 mHz…

泛微开发修炼之旅--18泛微OA节点后操作代码自动退回流程的代码示例

文章链接&#xff1a;17泛微OA节点后操作代码自动退回流程的代码示例

6月15号作业

使用手动连接&#xff0c;将登录框中的取消按钮使用第二中连接方式&#xff0c;右击转到槽&#xff0c;在该槽函数中&#xff0c;调用关闭函数 将登录按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admin"&#xff0…

大型Web应用的模块化与组织实践:Flask Blueprints深入解析

目录 一、引言 二、Flask Blueprints概述 三、Flask Blueprints的使用 创建Blueprint对象 定义路由和视图函数 注册Blueprint 使用Blueprints组织代码 四、案例分析 创建模块目录结构 创建Blueprint对象 注册Blueprint 五、代码示例与最佳实践 1. 代码示例 …

Proxmox VE 超融合集群扩容后又平稳运行了170多天--不重启的话,488天了

五个节点的Proxmox VE 超融合集群&#xff0c;扩从了存储容量&#xff0c;全NVMe高速盘&#xff0c;单机4条3.7TB容量&#xff08;扩容前是两块NVMe加两块16TB的慢速SATA机械盘&#xff0c;拔掉机械盘&#xff0c;替换成两块NVMe&#xff09;&#xff0c;速度那叫一个快啊。 当…

专业酒窖的布局与设计:为红酒提供理想保存条件

对于云仓酒庄雷盛红酒的爱好者而言&#xff0c;拥有一个专业的酒窖是保存和欣赏这些珍贵佳酿的方式。一个布局合理、设计精良的专业酒窖不仅能提供稳定的保存条件&#xff0c;还能确保红酒在理想状态下陈年&#xff0c;释放其深邃的香气和口感。 首先&#xff0c;酒窖的位置选择…

胡说八道(24.6.9)——离散时间系统及simulink仿真

上回说道拉普拉斯变换的定义、性质以及在电路分析中的应用。今天先来谈谈simulink仿真&#xff0c;可为是让我非常的震惊&#xff0c;今天做了三种模型的应用。第一个是simulink中有限状态机的应用&#xff0c;用来解决一些复杂的逻辑问题&#xff0c;实现状态之间的转换。第一…

高考志愿填报选专业,把兴趣和职业进行结合!

把兴趣和职业进行结合&#xff0c;可以获取更加丰富的物质回报和精神回报。如果说兴趣因为职业化而消失&#xff0c;那么我只能说&#xff0c;这个是兴趣是假的。 一个真正的兴趣&#xff0c;应该具备以下几个问题&#xff0c;不问清楚的兴趣&#xff0c;只能叫一时兴起&#…

Clearedge3d EdgeWise 5.8 强大的自动化建模软件

EdgeWise是功能强大的建模软件&#xff0c;提供领先的建模功能和先进的技术&#xff0c;让您的整个过程更快更准确&#xff01;您可以获得使用自动特征提取和对象识别的 3D 建模&#xff0c;ClearEdge3D 自动建模和对象识别软件通过创建竣工文档和施工验证完成该过程。拓普康和…

LabVIEW、Matlab与Python的比较:从多角度详解三大编程工具

LabVIEW、Matlab和Python是工程和科学领域中常用的编程工具&#xff0c;各具特色。本文将从开发效率、计算性能、应用场景、学习曲线、成本和社区支持等多个角度&#xff0c;详细比较这三者的优缺点&#xff0c;帮助读者选择最适合其项目需求的编程工具。 比较维度 开发效率 La…

【每日LeetCode】递归、记忆化搜索

递归、记忆化搜索 【leetcode70 爬楼梯】 class Solution {public int climbStairs(int n) {int[] memo new int[n 1];return dfs(n, memo);}private int dfs(int i, int[] memo){if(i < 1){return 1;}if(memo[i] ! 0){return memo[i];}return memo[i] dfs(i-1,memo) d…

Web应用安全测试-权限缺失

Web应用安全测试-权限缺失 Flash跨域访问 漏洞描述&#xff1a;flash跨域通信&#xff0c;依据的是crossdomain.xml文件。该文件配置在服务端&#xff0c;一般为根目录下&#xff0c;限制了flash是否可以跨域获取数据以及允许从什么地方跨域获取数据。举个例子&#xff1a; 1、…

全域推广和标准推广可以一起做吗?可行性分析结果如何?

作为全域时代的新赛道&#xff0c;全域推广从出现之日起便备受关注&#xff0c;许多创业者经常将其与标准推广进行对比或捆绑&#xff0c;类似于全域推广和标准推广的区别、全域推广和标准推广哪个好以及全域推广和标准推广可以一起做吗等问题也因此长期霸占该赛道相关话题榜单…

405 Method Not Allowed

因为路径或方法匹配错误&#xff0c;报错405 改为GetMapping

空间双重差分模型案例

一、案例简介 使用空间双重差分模型研究中国“一带一路”政策对经济发展的影响效应。 二、变量选择 选取全国30个省(西藏缺失)2007-2017年面板数据,其中18个省为一带一路沿线省份(新疆、重庆、陕西、甘肃、宁夏、青海、内蒙古、黑龙江、吉林、辽宁、广西、云南、上海、福…

酷开系统带你观看《庆余年》第二季,探索大庆权谋与主角成长

酷开系统为广大剧迷带来了激动人心的消息——时隔五年&#xff0c;《庆余年第二季》强势归来&#xff0c;原班人马将再次集结&#xff0c;带领观众进入更加变幻莫测的权谋世界。 第一季结束时&#xff0c;范闲被刺的悬念让无数剧迷悬悬而望&#xff0c;而第二季的开播无疑将解…