Java基础梳理之-IO操作 精选 原创 sbp810050504 2019-01-29 22:53:38 博主文章分类:java ©著作权 文章标签 Java基础 IO 文章分类 Java 后端开发 ©著作权归作者所有:来自51CTO博客作者sbp810050504的原创作品,请联系作者获取转载授权,否则将追究法律责任 回想最开始学习Java IO相关的操作时, 被各种Reader/Stream绕晕。 现在再回头梳理这一块的知识点,感觉清晰了很多。 Java作为编程语言, 大部分东西都是从系统层面带来的, 所以学习的知识点虽然在Java, 但是背后的答案却在操作系统层面。 首先理解核心概念:IO, 究竟什么是IO? 所谓IO就是内存与外设相关的数据传输。常用的外设有硬盘,网卡,打印机, 鼠标... 我们接触最频繁的IO操作是硬盘上文件的读写,所以学习IO基本上都是以文件操作为例子。IO作为操作系统的核心,知识点相当庞杂,如果没有合适的切入点,容易迷失其中。 如果一定要找一个切入点,学习的先后顺序,个人建议如下: RandomAccessFile 对于文件的操作,最适合是RandomAccessFile: 它能读能写能定位。 使用RandomAccessFile, 就是把文件当作一个数组,只不过这个数组是在硬盘上而已。读写文件就像操作数组一样。更难能可贵的是, RandomAccessFile封装了Java所有的基础类型, 可以说基本满足操作单个文件的使用需求了。 public static void main(String[] args) throws IOException { RandomAccessFile bigArray = new RandomAccessFile(new File("/home/shgy/a.txt"),"rw"); // 写 bigArray.seek(10); bigArray.writeUTF("hello,world"); System.out.println("filePointer at " + bigArray.getFilePointer()); // 读 bigArray.seek(10); System.out.println(bigArray.readUTF()); bigArray.close(); } RandomAccessFile类有14个写的方法,17个读的方法,2个定位方法,2个长度相关操作,1个获取当前文件游标getFilePointer()的方法, 1个关闭文件释放系统资源的方法。 剩下的两个方法getChannel() 和 getFD()。getChannel() 跟NIO相关,getFD()是系统文件描述符,就本文所要总结的内容而言,已经超出三界之外,不在五行之中,暂时略过不提。 当文件数量多了以后,必然面临管理的问题。无论是windows还是Linux都采用层级管理,最后形成目录树。这带来一个新的问题就是文件的路径以及文件的归类。 面对这样的需求,Java提供了Files类来解决。通过了解Files类提供的API, 可以看出,其功能特点在于粗粒度的文件读写及文件属性的管理。 使用Files来读写文件更简单: public static void main(String[] args) throws IOException { Files.write("hello world", new File("/home/shgy/a.txt"),Charset.defaultCharset()); System.out.println(Files.readLines(new File("/home/shgy/a.txt"), Charset.defaultCharset())); } Files 可以读写文件,可以重命名文件,可以读取设置文件属性,简直是瑞士×××般的存在。这里涉及了更多文件相关的知识点,如果有学习过《鸟哥的Linux私房菜》第七章,再学习代码操作文件,就不会那么困惑了。 使用Files操纵文件引出了一个新的知识点Charset, 即字符集。字符集产生的原因很简单: 人类语言是字符形式,计算机只能以字节的方式存储数据,字符跟字节之间得有个映射关系。比如上例中存储的hello world, 实际上存储的内容可以使用vim的xdd命令查看: // vim + %!xdd 命令即可 00000000: 6865 6c6c 6f20 776f 726c 640a hello world. 关于字符集的知识,可以参考阮一峰的《字符编码笔记:ASCII,Unicode 和 UTF-8》。 理解了字符集,再进入Java的IO模块,才顺理成章。前面已经说过,所谓IO,就是内存与计算机外设的数据传输。Java从语言层面对IO进行了抽象, 这个抽象就是Steam, 数据流。这样的话,无论数据来源是文件,网页,内存块还是其他,都以一种统一的视角和处理方式看待。 所以Java定义了InputStream和OutputStream。 InputStream用于将数据读入内存, 对应的操作是read; OutputStream用于将数据写入外设,对应的操作是write。InputStream和OutputStream操纵的数据只能是字节或者字节数组, 这样就不用关心数据是文本,图片,音频,视频了,毕竟不管什么类型的数据,最终的呈现形式就是字节流。 这样,文件的操作就相当繁琐了: public static void main(String[] args) throws IOException { // 读取文件 FileInputStream fis = new FileInputStream(new File("/home/shgy/a.txt")); byte[] bytes = new byte[1024]; int n = fis.read(bytes); if(n>0){ System.out.println(new String(bytes,0,n)); } fis.close(); // 写文件 FileOutputStream fos = new FileOutputStream(new File("/home/shgy/a.txt")); fos.write("hello, world".getBytes()); fos.close(); } 鉴于我们处理的文件,绝大部分都是字符类型的文件,而且以字节的方式操纵字符确实过于原始,于是Java也定义了字符IO, 即Reader/Writer。 public static void main(String[] args) throws IOException { // 读取文件 FileReader fr = new FileReader(new File("/home/shgy/a.txt")); char[] buf = new char[1024]; int n = fr.read(buf); System.out.println(new String(buf,0,n)); fr.close(); FileWriter fw = new FileWriter(new File("/home/shgy/a.txt")); fw.write("hello, world"); fw.close(); } 由于计算机本质是处理字节,所以字符和字节之间需要一个桥梁,这个就是InputStreamReader/OutputStreamWriter. 为了应对各种字符集和字节之间的编码解码,所以定义了StreamEncoder/StreamDecoder。 对于文件的读写,由于是需要操作硬盘或者网卡;考虑到安全性, 在系统层面需要系统调用,由用户态切入内核态。这个操作代价较高, 所以又添加了一层缓冲,将原来需要多次请求的IO合并到一起,即BufferedInputStream/BufferedOutputStream 和 BufferedReader/BufferedWriter。 整个IO操作在InputStream/OutputStream和Reader/Writer基础之上丰富多彩起来。 由于外设,比如硬盘和网络数据的传输效率相比CPU的处理效率相差太远, 在《性能之颠》中有这样一个让人影响深刻的对比: 1个CPU周期为0.3ns, 1次机械磁盘IO周期为1~10ms, 1次从旧金山到纽约的互联网传输需要40ms; 由于时间单位太小,我们没有概念。 我们放大一下,假如: 1个CPU周期为1s, 则一次机械磁盘IO周期为1~12个月,1次从旧金山到纽约的互联网传输需要4年。 在这样一个差距面前,如何提高IO的效率,就显得尤为重要, 这就是NIO的由来。 在《UNIX网络编程卷1:套接字联网API》一书中总结了5种IO模型: 阻塞,非阻塞,IO复用,信号驱动,异步IO。Java的NIO是采用了IO复用(select)模型。 NIO处理数据,方式跟Stream有所不同。 Stream比较碎,以字节为最小粒度; NIO以数据块为最小粒度。所以可以避免数据的反复搬运,更高效,操作起来就更繁琐一些。 // 使用NIO写数据到文件 public static void main(String[] args) throws IOException { FileOutputStream fos = new FileOutputStream(new File("/home/shgy/a.txt")); FileChannel fc = fos.getChannel(); ByteBuffer buf = ByteBuffer.allocate(1024); buf.put("hello,world".getBytes()); buf.flip(); fc.write(buf); System.out.println("file channel position is " + fc.position()); fos.close(); } NIO有如下的几个优点: channel是支持读写的,所以相比Stream更灵活。 buffer可以分配堆外内存,这个对于IO来说,避免了数据从堆内存中倒腾一边,也避免了Java的GC, 性能自然有提升。 对于网络IO, NIO可以在同一个线程同时监听多个端口,避免了创建多个线程和线程管理的开销。 由于IO这一块的知识点过于庞杂,不是一篇博客能说清楚的,这里只是简单梳理一下学习思路。 赞 收藏 评论 分享 举报 上一篇:ES学习笔记之--ES的集群是如何组建起来的 下一篇:Java基础学习之-多线程学习知识点的学习 提问和评论都可以,用心的回复会被更多人看到 评论 发布评论 全部评论 () 最热 最新 相关文章 Java基础梳理 [不全面,后续更新...] Java基础梳理,帮助刚入坑的小伙伴快速学习和提升。 Java 集合 面向对象 编程 Java基础 JAVA list基础操作 list基本操作 System List Test Java IO - 源码: InputStream 本文主要从JDK 11 源码角度分析InputStream。 Java IO/NIO/AIO Java基础IO操作 IO操作 File类概述和构造方法File类的概述 文件和目录路径名的抽象表示形式构造方法 public import public parent Java IO基础操作 ,例如,把文件从磁盘读取到内存,从网络读取数据到内存等等。Output指把数据从内存输出到外部,例如,把数据从内存写入到文件,把数据从内存输出到网络等等。为什么要把数据读 java iostream 数据 数组 序列化 IO流的基础知识梳理 一.IO流的介绍 1.什么是IO流? I:inputo:output流:像流水一样传输数据2.IO流的分类输入和输出是相对于程序来说的简单来理解就是:输入是从文本读到程序,用read输出是从程序到文本,用write字节流:可以操作所有类型的文件字符流:只能操作纯文本文件这里的InputStream,OutputStream,Reader,Writer都是抽象类,不能直接创建他们的对象, 创建对象 数据 释放资源 IO基础之JAVA IO演进之路 echo编辑整理JAVA IO是什么?在JAVA中I/O是以流为基础进行数据的输入输出操作,I最典型的代表有:InputStream,O最典型的代表有:outputStream。所有的数据被串行化写入流,并输出就是我们的IO操作,通俗一点讲就是将数据以流的方式从磁盘读到内存,或者将数据从内存写入磁盘。IO分为两种阻塞式非阻塞式阻塞式模型非阻塞式模型IO开始演进,异步IO异步IO比较简单, IO JAVA NIO BIO AIO Java IO 之File操作 一. Java Java之IO操作1 import java.io.*;import java.util.Date;public class Lesson2{ public static void main(String[] args) { File f = new File("1.txt"); if (f.exists()) { f.delete(); } else { try { f.createNewFile(); ... java java的io流梳理 java的io流分类以及其之间的关系 字节流 字符流 父类 正则表达式 缓存 杭州Java基础学习之枚举知识梳理 枚举是JDK1.5引入了的新类型,其实质依旧是一个类,而每个被枚举的成员实质就是一个枚举类型的实例。枚举规范了参数的形式,这样我们就可以不用考虑类型的不匹配以及int型参数可能带来的模糊概念。接下来的杭州Java基础学习课中,就给大家简单梳理一下枚举相关知识点。枚举类是一种特殊的类,它的对象是有限而且固定的。注意,定义枚举类的关键字是enum,而不是Enum,所有关键字都是小写的!其中FRONT、 杭州Java基础学习之枚举知识梳理 杭州Java Java编程基础之IO流 IO流IO流基类InputStream输入流基类readOutputStream输出流基类writeIO流分类流向分 java 字节流 数组 Java 文件 IO 操作之 DirectIO 在前文《文件IO操作的一些最佳实践》中,我介绍了一些 Java 中常见的文件操作的接口,并且就 PageCache 和 DIrect IO 进行了探讨,最近封装了一个 Direct IO 的库,趁着这个机会,谈谈 Java 中 Direct IO 的意义,以及简单介绍下这个轮子。Java 中的 Direct IO如果你阅读过我之前的文章,应该已经了解 Java 中常用的文件操作接口为:FileCh java Java基础之IO&NIO操作文件流 一、简介1.1 IO(BIO)—阻塞式IO起源于JDK1.0java.io 包几乎包含了所有操作输入、输出需要的类。所有这些流类代表了输入源和输出目标。java.io 包中的流支持很多种格式 java nio desktop 复制文件 Java语法基础梳理! Java 概述1991 年Sun公司的James Gosling(詹姆斯·高斯林)等人开始开发名称为 Oak 的语言,希望用于控制嵌入在有线电视交换盒、PDA等的微处理器;1994年将Oak语言更名为Java;基本概念JDKJava Development Kit,java的开发和运行环境,包括:java的开发工具和jreJREJava Runtime Environm... java 数据 变量名 数据类型 保留字 杭州Java基础学习之for循环相关知识梳理 for循环是编程语言中一种循环语句,是Java程序员日常工作中的重要组成部分。循环语句由循环体及循环的判定条件两部分组成,其表达式为:for(单次表达式;条件表达式;末尾循环体){中间循环体;}。合理使用for循环可以让我们事半功倍,接下来就给大家分享for循环相关的知识。在Java程序中,要“逐一处理”――或者说,“遍历”――某一个数组或Collection中的元素的时候,一般会使用一个for循 杭州Java基础学习之for循环相关知 杭州Java基础 Java基础之IO File类 File类构造方法 public File(String pathname) public File(String parent, String child) public File(File parent, String child) File类常用方法之get public Stri ... 文件目录 创建文件 常用方法 输出流 字符流 java之IO操作 IO操作 定义 IO 输入/输出流,来自java.io.* I,input指的是接收数据 O,Output指的是发送数据 文件IO:I是读文件,O是写文件 网络IO:I是接收数据,O是发送数据 核心组成 一个类(File) 一个接口(SeriaIizable) 四个抽象类(InputStr) Fil ... java 文件路径 数据 源文件 字节数 JAVA 基础之 IO复习 一、文件:在IO包中唯一与文件相关的类就是 File类。File类中经常使用的常量和方法1、创建文件:指定路径和将要创建的文件名称字以及类型;然后调用 createNewFile()方法File file = new File("D:"+File.separator+"M java 字符串 数据 指定位置 构造方法 Java 基础之详解 Java IO 外边读数据到自己这里就用输入(InputStream/Reader), 向外边写数据就用输出(OutputStream/Writer)。 Stream:Java 中将数 java IO 数据 字节流 字符流 java