Java进阶——IO流核心模块与基本原理

面试官:请讲一讲IO流核心模块与基本原理是什么? 前言 一、IO流与系统 IO技术在JDK中算是极其复杂的模块,其复杂的一个关键原因就是IO操作和系统内核的关联性,另外网络编程,文件管理都依赖IO技术,而且都是编程的难点,想要整体理解IO流,先从Linux操作系统开始。 Linux空间隔离 Linux使用是区分用户的,这个是基础常识,其底层也区分用户和内核两个模块: User space:用户空间 Kernel space:内核空间 常识用户空间的权限相对内核空间操作权限弱很多,这就涉及到用户与内核两个模块间的交互,此时部署在服务上的应用如果需要请求系 阅读详情

一、IO流与系统

IO技术在JDK中算是极其复杂的模块,其复杂的一个关键原因就是IO操作和系统内核的关联性,另外网络编程,文件管理都依赖IO技术,而且都是编程的难点,想要整体理解IO流,先从Linux操作系统开始。

Linux空间隔离

Linux使用是区分用户的,这个是基础常识,其底层也区分用户和内核两个模块:

  • User space:用户空间
  • Kernel space:内核空间

常识用户空间的权限相对内核空间操作权限弱很多,这就涉及到用户与内核两个模块间的交互,此时部署在服务上的应用如果需要请求系统资源,则在交互上更为复杂:

用户空间本身无法直接向系统发布调度指令,必须通过内核,对于内核中数据的操作,也是需要先拷贝到用户空间,这种隔离机制可以有效的保护系统的安全性和稳定性。

参数查看

可以通过Top命令动态查看各项数据分析,进程占用资源的状况:

  • us :用户空间占用CPU的百分比;
  • sy :内核空间占用CPU的百分比;
  • id :空闲进程占用CPU的百分比;
  • wa :IO等待占用CPU的百分比;

对 wa 指标,在大规模文件任务流程里是监控的核心项之一。

IO协作流程

此时再看上面图【1】的流程,当应用端发起IO操作的请求时,请求沿着链路上的各个节点流转,有两个核心概念:

  • 节点交互模式:同步与异步;
  • IO数据操作:阻塞与非阻塞;

这里就是文件流中常说的:【同步/异步】IO,【阻塞/非阻塞】IO,下面看细节。

二、IO模型分析

1、同步阻塞

用户线程与内核的交互方式,应用端请求对应一个线程处理,整个过程中accept(接收)和read(读取)方法都会阻塞直至整个动作完成:

在常规CS架构模式中,这是一次IO操作的基本过程,该方式如果在高并发的场景下,客户端的请求响应会存在严重的性能问题,并且占用过多资源。

2、同步非阻塞

在同步阻塞IO的基础上进行优化,当前线程不会一直等待数据就绪直到完成复制:

在线程请求后会立即返回,并不断轮询直至拿到数据,才会停止轮询,这种模式的缺陷也是显而易见的,如果数据准备好,在通知线程完成后续动作,这样就可以省掉很多中间交互。

3、异步通知模式

在异步模式下,彻底摒弃阻塞机制,过程分段进行交互,这与常规的第三方对接模式很相似,本地服务在请求第三方服务时,如果请求过程耗时很大,会异步执行,第三方第一次回调,确认请求可以被执行;第二次回调则是推送处理结果,这种思想在处理复杂问题时,可以很大程度的提高性能,节省资源:

异步模式对于性能的提升是巨大的,当然其相应的处理机制也更复杂,程序的迭代和优化是无止境的,在NIO模式中再次对IO流模式进行优化。

三、File文件类

1、基础描述

File类作为文件和目录路径名的抽象表示,用来获取磁盘文件的相关元数据信息,例如:文件名称、大小、修改时间、权限判断等。

注意:File并不操作文件承载的数据内容,文件内容称为数据,文件自身信息称为元数据。

public class File01 {
    public static void main(String[] args) throws Exception {
        // 1、读取指定文件
        File speFile = new File(IoParam.BASE_PATH+"fileio-03.text") ;
        if (!speFile.exists()){
            boolean creFlag = speFile.createNewFile() ;
            System.out.println("创建:"+speFile.getName()+"; 结果:"+creFlag);
        }

        // 2、读取指定位置
        File dirFile = new File(IoParam.BASE_PATH) ;
        // 判断是否目录
        boolean dirFlag = dirFile.isDirectory() ;
        if (dirFlag){
            File[] dirFiles = dirFile.listFiles() ;
            printFileArr(dirFiles);
        }

        // 3、删除指定文件
        if (speFile.exists()){
            boolean delFlag = speFile.delete() ;
            System.out.println("删除:"+speFile.getName()+"; 结果:"+delFlag);
        }
    }
    private static void printFileArr (File[] fileArr){
        if (fileArr != null && fileArr.length>0){
            for (File file : fileArr) {
                printFileInfo(file) ;
            }
        }
    }
    private static void printFileInfo (File file) {
        System.out.println("名称:"+file.getName());
        System.out.println("长度:"+file.length());
        System.out.println("路径:"+file.getPath());
        System.out.println("文件判断:"+file.isFile());
        System.out.println("目录判断:"+file.isDirectory());
        System.out.println("最后修改:"+new Date(file.lastModified()));
        System.out.println();
    }
}

上述案例使用了File类中的基本构造和常用方法(读取、判断、创建、删除)等,JDK源码在不断地更新迭代,通过类的构造器、方法、注释等去判断类具有的基本功能,是作为开发人员的必备能力。

在File文件类中缺乏两个关键信息描述: 类型和编码 ,如果经常开发文件模块的需求,就知道这是两个极其复杂的点,很容易出现问题,下面站在实际开发的角度看看如何处理。

2、文件业务场景

如图所示,在常规的文件流任务中,会涉及【文件、流、数据】三种基本形式的转换:

基本过程描述:

  • 源文件生成,推送文件中心;
  • 通知业务使用节点获取文件;
  • 业务节点进行逻辑处理;

很显然的一个问题,任何节点都无法适配所有文件处理策略,比如类型与编码,面对复杂场景下的问题, 规则约束 是常用的解决策略,即在约定规则之内的事情才处理。

上面流程中,源文件节点通知业务节点时的数据主体描述:

public class BizFile {
    /**
     * 文件任务批次号
     */
    private String taskId ;
    /**
     * 是否压缩
     */
    private Boolean zipFlag ;
    /**
     * 文件地址
     */
    private String fileUrl ;
    /**
     * 文件类型
     */
    private String fileType ;
    /**
     * 文件编码
     */
    private String fileCode ;
    /**
     * 业务关联:数据库
     */
    private String bizDataBase ;
    /**
     * 业务关联:数据表
     */
    private String bizTableName ;
}

把整个过程当做一个任务进行封装,即:任务批次、文件信息、业务库表路由等,当然这些信息也可以直接标记在文件命名的策略上,处理的手段类似:

/**
 * 基于约定策略读取信息
 */
public class File02 {
    public static void main(String[] args) {
        BizFile bizFile = new BizFile("IN001",Boolean.FALSE, IoParam.BASE_PATH,
                "csv","utf8","model","score");
        bizFileInfo(bizFile) ;
        /*
         * 业务性校验
         */
        File file = new File(bizFile.getFileUrl());
        if (!file.getName().endsWith(bizFile.getFileType())){
            System.out.println(file.getName()+":描述错误...");
        }
    }
    private static void bizFileInfo (BizFile bizFile){
        logInfo("任务ID",bizFile.getTaskId());
        logInfo("是否解压",bizFile.getZipFlag());
        logInfo("文件地址",bizFile.getFileUrl());
        logInfo("文件类型",bizFile.getFileType());
        logInfo("文件编码",bizFile.getFileCode());
        logInfo("业务库",bizFile.getBizDataBase());
        logInfo("业务表",bizFile.getBizTableName());
    }
}

基于主体描述的信息,也可以转化到命名规则上: 命名策略:编号_压缩_Excel_编码_库_表 ,这样一来在业务处理时,不符合约定的文件直接排除掉,降低文件异常导致的数据问题。

四、基础流模式

1、整体概述

IO流向

基本编码逻辑: 源文件->输入流->逻辑处理->输出流->目标文件 ;

基于不同的角度看,流可以被划分很多模式:

  • 流动方向:输入流、输出流;
  • 流数据类型:字节流、字符流;

IO流的模式有很多种,相应的API设计也很复杂,通常复杂的API要把握住核心接口与常用的实现类和原理。

基础API

  • 字节流:InputStream输入、OutputStream输出;数据传输的基本单位是字节;
    • read():输入流中读取数据的下一个字节;
    • read(byte b[]):读数据缓存到字节数组;
    • write(int b):指定字节写入输出流;
    • write(byte b[]):数组字节写入输出流;
  • 字符流:Reader读取、Writer写出;数据传输的基本单位是字符;
    • read():读取一个单字符;
    • read(char cbuf[]):读取到字符数组;
    • write(int c):写一个指定字符;
    • write(char cbuf[]):写一个字符数组;

缓冲模式

IO流常规读写模式,即读取到数据然后写出,还有一种缓冲模式,即数据先加载到缓冲数组,在读取的时候判断是否要再次填充缓冲区:

缓冲模式的优点十分明显,保证读写过程的高效率,并且与数据填充过程隔离执行,在BufferedInputStream、BufferedReader类中是对缓冲逻辑的具体实现。

2、字节流

API关系图:

字节流基础API:

public class IoByte01 {
    public static void main(String[] args) throws Exception {
        // 源文件 目标文件
        File source = new File(IoParam.BASE_PATH+"fileio-01.png") ;
        File target = new File(IoParam.BASE_PATH+"copy-"+source.getName()) ;
        // 输入流 输出流
        InputStream inStream = new FileInputStream(source) ;
        OutputStream outStream = new FileOutputStream(target) ;
        // 读入 写出
        byte[] byteArr = new byte[1024];
        int readSign ;
        while ((readSign=inStream.read(byteArr)) != -1){
            outStream.write(byteArr);
        }
        // 关闭输入、输出流
        outStream.close();
        inStream.close();
    }
}

字节流缓冲API:

public class IoByte02 {
    public static void main(String[] args) throws Exception {
        // 源文件 目标文件
        File source = new File(IoParam.BASE_PATH+"fileio-02.png") ;
        File target = new File(IoParam.BASE_PATH+"backup-"+source.getName()) ;
        // 缓冲:输入流 输出流
        InputStream bufInStream = new BufferedInputStream(new FileInputStream(source));
        OutputStream bufOutStream = new BufferedOutputStream(new FileOutputStream(target));
        // 读入 写出
        int readSign ;
        while ((readSign=bufInStream.read()) != -1){
            bufOutStream.write(readSign);
        }
        // 关闭输入、输出流
        bufOutStream.close();
        bufInStream.close();
    }
}

字节流应用场景:数据是文件本身,例如图片,视频,音频等。

3、字符流

API关系图:

字符流基础API:

public class IoChar01 {
    public static void main(String[] args) throws Exception {
        // 读文本 写文本
        File readerFile = new File(IoParam.BASE_PATH+"io-text.txt") ;
        File writerFile = new File(IoParam.BASE_PATH+"copy-"+readerFile.getName()) ;
        // 字符输入输出流
        Reader reader = new FileReader(readerFile) ;
        Writer writer = new FileWriter(writerFile) ;
        // 字符读入和写出
        int readSign ;
        while ((readSign = reader.read()) != -1){
            writer.write(readSign);
        }
        writer.flush();
        // 关闭流
        writer.close();
        reader.close();
    }
}

字符流缓冲API:

public class IoChar02 {
    public static void main(String[] args) throws Exception {
        // 读文本 写文本
        File readerFile = new File(IoParam.BASE_PATH+"io-text.txt") ;
        File writerFile = new File(IoParam.BASE_PATH+"line-"+readerFile.getName()) ;
        // 缓冲字符输入输出流
        BufferedReader bufReader = new BufferedReader(new FileReader(readerFile)) ;
        BufferedWriter bufWriter = new BufferedWriter(new FileWriter(writerFile)) ;
        // 字符读入和写出
        String line;
        while ((line = bufReader.readLine()) != null){
            bufWriter.write(line);
            bufWriter.newLine();
        }
        bufWriter.flush();
        // 关闭流
        bufWriter.close();
        bufReader.close();
    }
}

字符流应用场景:文件作为数据的载体,例如Excel、CSV、TXT等。

4、编码解码

  • 编码:字符转换为字节;
  • 解码:字节转换为字符;
public class EnDeCode {
    public static void main(String[] args) throws Exception {
        String var = "IO流" ;
        // 编码
        byte[] enVar = var.getBytes(StandardCharsets.UTF_8) ;
        for (byte encode:enVar){
            System.out.println(encode);
        }
        // 解码
        String deVar = new String(enVar,StandardCharsets.UTF_8) ;
        System.out.println(deVar);
        // 乱码
        String messyVar = new String(enVar,StandardCharsets.ISO_8859_1) ;
        System.out.println(messyVar);
    }
}

乱码出现的根本原因,就是在编码与解码的两个阶段使用的编码类型不同。

5、序列化

  • 序列化:对象转换为流的过程;
  • 反序列化:流转换为对象的过程;
public class SerEntity implements Serializable {
    private Integer id ;
    private String name ;
}
public class Seriali01 {
    public static void main(String[] args) throws Exception {
        // 序列化对象
        OutputStream outStream = new FileOutputStream("SerEntity.txt") ;
        ObjectOutputStream objOutStream = new ObjectOutputStream(outStream);
        objOutStream.writeObject(new SerEntity(1,"Cicada"));
        objOutStream.close();
        // 反序列化对象
        InputStream inStream = new FileInputStream("SerEntity.txt");
        ObjectInputStream objInStream = new ObjectInputStream(inStream) ;
        SerEntity serEntity = (SerEntity) objInStream.readObject();
        System.out.println(serEntity);
        inStream.close();
    }
}

注意:引用类型的成员对象也必须是可被序列化的,否则会抛出 NotSerializableException 异常。

五、NIO模式

1、基础概念

NIO即(NonBlockingIO),面向数据块的处理机制,同步非阻塞模型,服务端的单个线程可以处理多个客户端请求,对IO流的处理速度有极高的提升,三大核心组件:

  • Buffer(缓冲区):底层维护数组存储数据;
  • Channel(通道):支持读写双向操作;
  • Selector(选择器):提供Channel多注册和轮询能力;

API使用案例

public class IoNew01 {
    public static void main(String[] args) throws Exception {
        // 源文件 目标文件
        File source = new File(IoParam.BASE_PATH+"fileio-02.png") ;
        File target = new File(IoParam.BASE_PATH+"channel-"+source.getName()) ;

        // 输入字节流通道
        FileInputStream inStream = new FileInputStream(source);
        FileChannel inChannel = inStream.getChannel();

        // 输出字节流通道
        FileOutputStream outStream = new FileOutputStream(target);
        FileChannel outChannel = outStream.getChannel();

        // 直接通道复制
        // outChannel.transferFrom(inChannel, 0, inChannel.size());

        // 缓冲区读写机制
        ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
        while (true) {
            // 读取通道中数据到缓冲区
            int in = inChannel.read(buffer);
            if (in == -1) {
                break;
            }
            // 读写切换
            buffer.flip();
            // 写出缓冲区数据
            outChannel.write(buffer);
            // 清空缓冲区
            buffer.clear();
        }
        outChannel.close();
        inChannel.close();
    }
}

上述案例只是NIO最基础的文件复制能力,在网络通信中,NIO模式的发挥空间十分宽广。

2、网络通信

服务端的单线程可以处理多个客户端请求,通过轮询多路复用器查看是否有IO请求,这样一来,服务端的并发能力得到极大的提升,并且显著降低了资源的消耗。

API案例:服务端模拟

public class SecServer {
    public static void main(String[] args) {
        try {
            //启动服务开启监听
            ServerSocketChannel socketChannel = ServerSocketChannel.open();
            socketChannel.socket().bind(new InetSocketAddress("127.0.0.1", 8089));
            // 设置非阻塞,接受客户端
            socketChannel.configureBlocking(false);
            // 打开多路复用器
            Selector selector = Selector.open();
            // 服务端Socket注册到多路复用器,指定兴趣事件
            socketChannel.register(selector, SelectionKey.OP_ACCEPT);
            // 多路复用器轮询
            ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
            while (selector.select() > 0){
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                Iterator<SelectionKey> selectionKeyIter = selectionKeys.iterator();
                while (selectionKeyIter.hasNext()){
                    SelectionKey selectionKey = selectionKeyIter.next() ;
                    selectionKeyIter.remove();
                    if(selectionKey.isAcceptable()) {
                        // 接受新的连接
                        SocketChannel client = socketChannel.accept();
                        // 设置读非阻塞
                        client.configureBlocking(false);
                        // 注册到多路复用器
                        client.register(selector, SelectionKey.OP_READ);
                    } else if (selectionKey.isReadable()) {
                        // 通道可读
                        SocketChannel client = (SocketChannel) selectionKey.channel();
                        int len = client.read(buffer);
                        if (len > 0){
                            buffer.flip();
                            byte[] readArr = new byte[buffer.limit()];
                            buffer.get(readArr);
                            System.out.println(client.socket().getPort() + "端口数据:" + new String(readArr));
                            buffer.clear();
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

API案例:客户端模拟

public class SecClient {
    public static void main(String[] args) {
        try {
            // 连接服务端
            SocketChannel socketChannel = SocketChannel.open();
            socketChannel.connect(new InetSocketAddress("127.0.0.1", 8089));
            ByteBuffer writeBuffer = ByteBuffer.allocate(1024);
            String conVar = "[hello-8089]";
            writeBuffer.put(conVar.getBytes());
            writeBuffer.flip();
            // 每隔5S发送一次数据
            while (true) {
                Thread.sleep(5000);
                writeBuffer.rewind();
                socketChannel.write(writeBuffer);
                writeBuffer.clear();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

SelectionKey绑定Selector和Chanel之间的关联,并且可以获取就绪状态下的Channel集合。

JSSIP实战:5分钟搞定WebRTC电话功能(附完整代码示例) 本文通过JSSIP库实战演示如何在Web应用中快速集成WebRTC电话功能。文章提供了从环境准备、SIP服务器连接到完整代码示例的详细步骤,涵盖用户注册、拨号接听、媒体流处理等核心环节,并针对常见问题给出排查方案,帮助开发者高效实现网页端实时语音通信。 阅读详情

相关推荐

高速PCB设计中串扰的成因、影响与实战控制策略

在高速数字电路与硬件系统设计中,信号完整性是确保系统稳定可靠的核心基础。其核心原理在于,当信号在传输线上传播时,会伴随产生电场与磁场,若相邻导线距离过近,便会通过电磁场耦合产生不期望的能量转移,即串扰。这一现象会直接导致信号波形畸变、时序偏移和噪声裕量降低,严重影响系统性能。从技术价值看,深入理解并有效控制串扰,是提升数据传输速率、保障系统稳定性和降低误码率的关键。其应用场景广泛覆盖了从高速SerDes链路、DDR内存接口到高精度模拟电路等几乎所有现代电子系统。本文聚焦于高速PCB设计中的串扰问题,系统剖析

weixin_27625589的博客 579

Java中IO体系

Java中IO体系

钱辉 534

游戏开发实战:用UE4 Marschner模型打造次世代头发渲染(附Shader代码解析)

本文详细解析了如何在UE4中使用Marschner模型实现次世代头发渲染,包括Shader代码逐行解读与参数调优。通过对比传统Kajiya-Kay模型,展示了Marschner模型在物理精确性和视觉效果上的优势,并提供了性能优化与实战技巧,帮助技术美术师提升游戏角色渲染品质。

weixin_28223453的博客 241

Java的IO体系

而编码和解码转换之间是需要遵循规则的,即编码和解码都遵循同一种规则才能将文字信息正常显示,如果编码跟解码使用了不同的规则,就会出现乱码的情况。这意味着在使用"rws"模式打开文件时,不仅对文件内容的更新会被立即写入,还包括文件的元数据,比如文件属性、修改时间等。不同的是,"rwd"模式只要求对文件内容的更新被立即写入,而元数据可能会被延迟写入,这意味着文件的属性信息等可能不会立即更新到磁盘。它们分别属于不同的编码集。文件内容通常指的是文件中存储的实际数据,即由应用程序创建的、用户需要读取或操作的数据。

落日的博客 1135

保姆级教程:用Python+OpenCV搞定Orbbec Gemini深度与彩色流对齐(附完整代码)

本文提供了一份详细的Orbbec Gemini深度与彩色流对齐教程,涵盖从环境配置到完整代码实现的每一步。通过解析深度流对齐原理,对比不同对齐模式,并提供工业级应用中的问题排查方法,帮助开发者快速掌握Orbbec Gemini相机的使用技巧。文章还包含进阶应用如点云生成与三维重建的实战代码。

weixin_29090917的博客 470

编译zlib库给IOS平台用

在弹出的下面对话框中选择Unix Makefiles ,然后点击(Done)完成。使用 lipo与otool查看库类型为arm64,现在可在ios平台使用该库了。zlib自带CMakeLists.txt 所以用CMake-GUI来生成。修改为与系统当前安装的cmake版本 (如:3.22.1)选择zlib源码目录及输出目录,输入下图的CMAKE参数。点击Configure,在弹出的对话框中选择Yes。cmake --install . 进行安装。cmake --build . 进行编译。

998

java I/O流概念及其体系结构

I和O,分别是Input和Output两个单词的缩写,Input是输入,Output是输出。流:是一种抽象概念,是对数据传输的总称.也就是说数据在设备间的传输称为流,流的本质是数据传输。IO流就是用来处理设备间数据传输问题的。常见的应用: 文件复制、文件上传、 文件下载等。字节流抽象基类: 以字节读写文件InputStream:这个抽象类是表示字节输入流的所有类的超类OutputStream:这个抽象类是表示字节输出流的所有类的超类 根据交互设备的不同,有不同的具体子类。

m0_52363223的博客 488

域适应分类:MCD论文笔记——Maximum Classifier Discrepancy for Unsupervised Domain Adaptation

域适应分类:MCD论文笔记——Maximum Classifier Discrepancy for Unsupervised Domain Adaptation

qq_50001789的博客 1007

Java IO知识体系详解

创建一个好的I/O系统不是一件容易的事,难度似乎来自于需要覆盖所有的可能性。因为不仅存在各种I/O源端(文件、控制台、网络连接等),还需要以多种不同的方式与这些I/O源端(顺序、随机、缓冲、二进制、按字符、按行、按字)进行通信。Java类库的设计者通过创建大量的类来解决这个问题。...

在路上 1475

DSP2837X CLA开发实战教程

摘要: 本文详细解析TI C2000 DSP中CLA协处理器的开发流程,以TMS320F28377D的cla_divide案例为例,展示浮点除法验证的实现方法。从基础配置(消息RAM管理、任务触发)到高级调试(ePWM计时、断点设置),涵盖全流程开发要点。重点分析CLA编程约束(禁用标准库、数学优化)、多任务调度及常见问题解决方案(如死锁、数据同步)。提供FPGA协同加速、电机控制等扩展方向,并推荐官方例程与硬件平台(如创龙TL2837xF-EVM)。开发时需注意.cla文件语法支持及调试技巧,以充分发挥C

6763

YOLOv11 损失函数进阶:Varifocal Loss 让正负样本精度双升

创建self.alpha = alpha # 正样本权重系数self.gamma = gamma # 聚焦系数self.lambda_reg = lambda_reg # 回归损失权重# 分类损失:Varifocal Classification Loss# 正样本权重:基于预测置信度# 计算 BCE 损失并加权cls_loss = cls_loss.sum() / (cls_true.sum() + 1e-6) # 按正样本数归一化。

m0_71589036的博客 443

Java开发中的IO体系

Java IO体系提供了丰富的工具,用于处理各种类型的数据源,支持从字节级别到字符级别的数据操作。通过掌握这些概念和技巧,可以高效、安全地执行各种IO操作,特别是在处理大文件、高并发网络应用时,使用NIO可以显著提升性能。注意资源管理、字符编码、异常处理等细节,将有助于编写健壮的IO代码。

goTsHgo的博客 1386

5、卡尔ibration中Denavit - Hartenberg与Hayati约定的转换

本文详细介绍了机器人运动学中Denavit-Hartenberg(DH)参数与Hayati参数的定义、适用场景及其相互转换方法。重点分析了两种参数在描述关节坐标系变换时的差异,特别是在处理平行或接近平行关节轴时的稳定性问题,并给出了从DH到Hayati及反向转换的具体数学公式与流程图。通过参数转换,可在不改变运动学模型的前提下提升建模精度与计算鲁棒性,适用于机器人标定与运动学分析等应用场景。

h0i1j2k3l的博客 121

Java进阶 | IO流核心模块与基本原理

IO流向源文件->输入流->逻辑处理->输出流->目标文件;流动方向输入流、输出流;流数据类型字节流、字符流;IO流的模式有很多种,相应的API设计也很复杂,通常复杂的API要把握住核心接口与常用的实现类和原理。基础API字节流InputStream输入、OutputStream输出;数据传输的基本单位是字节;read()输入流中读取数据的下一个字节;读数据缓存到字节数组;指定字节写入输出流;数组字节写入输出流;字符流Reader读取、Writer写出;read()...

【积累】,是一个长期持续的过程。 1342

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Java IO流详解

原文 Java IO流详解 1.什么是IO Java中I/O操作主要是指使用Java进行输入,输出操作. Java所有的I/O机制都是基于数据流进行输入输出,这些数据流表示了字符或者字节数据的流动序列。Java的I/O流提供了读写数据的标准方法。任何Java中表示数据源的对象都会提供以数据流的方式读写它的数据的方法。 IO又分为流IO(java.io)和块IO(java.nio) Java.io是大多数面向数据流的输入/输出类的主要软件包。此外,Java也对块传输提供支持,在核心库 java.nio中采用的

ss810540895的博客 1万+

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

java IO流学习总结

https://www.cnblogs.com/hopeyes/p/9736642.html 近期学习了Java的IO流,尝试着总结一下。 java.io 包下的IO流很多: 其中,以Stream结尾的为字节流,以Writer或者Reader结尾的为字符流。所有的输入流都是抽象类IuputStream(字节输入流)或者抽象类Reader(字符输入流)的子类,所有的输出流都是抽象类Outp...

乔志勇笔记 1万+

Java进阶——IO 流

转换流也是处理流的一种。转换流提供了在字节流和字符流之间的转换。lnputStreamReader:将 InputStream 转换为 Reader,字节输入流转换成字符输入流OutputStreamWriter:将 Writer 转换为 OutputStream,字符输出流转换成字节输出流字节流中的数据都是字符时,转成字符流操作更高效。很多时候我们使用转换流来处理文件乱码问题。实现编码和解码的功能。对象流是处理流的一种。

2509_93882485的博客 1899

Java IO 流详解:从分类到体系结构,一篇搞定 IO 流核心

本文系统解析了Java IO流的分类体系和使用逻辑。IO流按数据处理单位分为字节流(InputStream/OutputStream)和字符流(Reader/Writer),按传输方向分为输入流和输出流。Java IO体系以四大抽象基类为核心,通过节点流直接操作数据源,处理流提供缓冲、编码转换等功能增强。选择IO流时应先确定数据类型(非文本用字节流,文本用字符流),再考虑操作方向,最后根据需求选择增强功能。掌握IO流的核心是理解其分类逻辑和体系结构,合理选择适合场景的流类型。

qq_40303030的博客 1303

IO流核心模块与基本原理

基本编码逻辑源文件->输入流->逻辑处理->输出流->目标文件;流动方向输入流、输出流;流数据类型字节流、字符流;IO流的模式有很多种,相应的API设计也很复杂,通常复杂的API要把握住核心接口与常用的实现类和原理。......

weixin_62421895的博客 786

Java进阶——IO流

Java进阶——IO流——IO流体系——字节流知识介绍

2401_84643729的博客 872
上一篇: What‘s JVM- 垃圾收集器与内存分配策略
下一篇: Spring源码编译一次性通过&遇到的坑解决方法
JavaShark
博客等级 码龄4年 184粉丝 438原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值