Java IO相关使用
date: 2020-06-14 14:42:22
updated: 2020-08-21 17:35:45
Java IO相关使用
1. 文件
创建 File 对象的三种方式
- 一个路径名:
File(String pathname) - 一个父路径名和子路径名:
File(File parent, String child)或File(String parent, String child) - 一个URI (统一资源标识符):
File(URI uri)
有文件时覆盖,无文件时创建。
通过 f.getAbsolutePath() 和 f.getCanonicalPath() 可获取文件的绝对路径和规范路径
f.delete() 会立即删除文件,而 f.deleteOnExit() 会延迟删除,直到JVM调用该方法
File 对象不可变,始终表示文件的路径名。文件经过创建、删除后,File 对象依旧是原始的路径名,并不代表实际的文件。
2. 输入字节流
抽象基类是 InputStream 类,结构关系如下:
InputStream
|
+--FileInputStream
|
+--ByteArrayInputStream
|
+--PipedInputStream
|
+--FilterInputStream
|
+--BufferedInputStream
|
+--PushbackInputStream
|
+--DataInputStream
|
+--ObjectInputStream
基类的基本方法如下:
| 方法 | 描述 |
|---|---|
| read() | 读取一个字节并将读取的字节作为int返回。当到达输入流的结尾时,它返回-1。 |
| read(byte[] buffer) | 读取最大值直到指定缓冲区的长度。它返回在缓冲区中读取的字节数。如果到达输入流的结尾,则返回-1。 |
| read(byte[] buffer,int offset, int length) | 读取最大值到指定长度字节。数据从偏移索引开始写入缓冲区。它返回读取的字节数,如果到达输入流的结束它返回-1。 |
| close() | 关闭输入流 |
| available() | 返回可以从此输入流读取但不阻塞的估计字节数。 |
2.1 BufferedInputStream
通过缓冲数据向输入流添加功能。维护一个内部缓冲区以存储从底层输入流读取的字节。
import java.io.*;
public static void main(String[] args) throws IOException {
String filePath = "/Users/mxxct/Desktop/md_meter.java";
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filePath));
byte[] buffer = new byte[1024]; // 长度为1024个字节的缓冲区
int len = -1; // 偏移量,或本次读取的字节数
StringBuilder content = null;
// 此次读取的字节数赋值给 len,如果等于 -1 说明已经读完了
while((len = bis.read(buffer)) != -1){
content.append(new String(buffer, 0, len));
}
System.out.println(content);
bis.close();
}
3. 输出字节流
FileOutputStream fos = new FileOutputStream(destFile); 创建一个 FileOutputStream 对象,如果文件不存在,会尝试创建文件,但必须处理异常 FileNotFoundException,需要放在 try-catch 里面。
如果文件包含数据,数据会被覆盖。如果要追加,需要添加一个第二个参数,true 表示追加。
fos.write(int b)
fos.write(byte[] b)
fos.write(byte[] b, int off, int len)
由于输出的是字节流,所以只能 write int 或 byte[],如果是字符串的话,通过 getBytes() 方法可以返回字节数组
通过 fos.flush() 方法刷新输出流:将 write 里的字节缓存清出,写入到目标处。
4. 管道
管道IO基于生产者--消费者模式,PipedOutputStream 负责把数据写入到管道里,相当于生产者, PipedInputStream 负责读取管道里的数据
两种连接管道的方式
PipedInputStream pis = new PipedInputStream();
PipedOutputStream pos = new PipedOutputStream();
pis.connect(pos); /* Connect the two ends */
PipedInputStream pis = new PipedInputStream();
PipedOutputStream pos = new PipedOutputStream(pis, 2048); // 缓冲区容量为2048字节
当创建管道时,可以设置管道容量。 如果管道的缓冲区已满,则尝试在管道上写入将会被阻止。
5. 字符输入流
Reader是所有的输入字符流的父类,它是一个抽象类
FilterReader是所有自定义具体装饰流的父类,其子类PushbackReader对Reader对象进行装饰,会增加一个行号
InputStreamReader是一个连接字节流和字符流的桥梁,它将字节流转变为字符流。FileReader可以说是一个达到此功能、常用的工具类,在其源代码中明显使用了将FileInputStream转变为Reader的方法。我们可以从这个类中得到一定的技巧。Reader中各个类的用途和使用方法基本和InputStream中的类使用一致。后面会有Reader与InputStream的对应关系。
BufferedReader reader = new BufferedReader(new FileReader(filePath));
String str;
while((str=reader.readLine())!=null){
System.out.println(str);
}
6. 字符输出流
问:字节流与字符流有什么区别?
答:计算机中的一切最终都是以二进制字节形式存在的,对于我们经常操作的字符串,在写入时其实都是先将字符转成对应的字节,然后将字节写入到输出流,在读取时其实都是先读到的是字节,然后将字节直接使用或者转换为字符给我们使用。由于对于字节和字符两种操作的需求比较广泛,所以 Java 专门提供了字符流与字节流相关IO类。
对于程序运行的底层设备来说永远都只接受字节数据,所以当我们往设备写数据时无论是字节还是字符最终都是写的字节流。字符流是字节流的包装类,所以当我们将字符流向字节流转换时要注意编码问题(因为字符串转成字节数组的实质是转成该字符串的某种字节编码)。
字符流和字节流的使用非常相似,但是实际上字节流的操作不会经过缓冲区(内存)而是直接操作文本本身的,而字符流的操作会先经过缓冲区(内存)然后通过缓冲区再操作文件。
1、字节流在操作的时候本身是不会用到缓冲区(内存)的,是与文件本身直接操作的,而字符流在操作的时候是使用到缓冲区的
2、字节流在操作文件时,即使不关闭资源(close方法),文件也能输出,但是如果字符流不使用close方法的话,则不会输出任何内容,说明字符流用的是缓冲区,并且可以使用flush方法强制进行刷新缓冲区,这时才能在不close的情况下输出内容
3、Reader类的read()方法返回类型为int :作为整数读取的字符(占两个字节共16位),范围在 0 到 65535 之间 (0x00-0xffff),如果已到达流的末尾,则返回 -1
inputStream的read()虽然也返回int,但由于此类是面向字节流的,一个字节占8个位,所以返回 0 到 255 范围内的 int 字节值。如果因为已经到达流末尾而没有可用的字节,则返回值 -1。因此对于不能用0-255来表示的值就得用字符流来读取!比如说汉字.
4、字节流与字符流主要的区别是他们的的处理方式
字节流:处理字节和字节数组或二进制对象;
字符流:处理字符、字符数组或字符串。
问:什么是缓冲区?有什么作用?
答:缓冲区就是一段特殊的内存区域,很多情况下当程序需要频繁地操作一个资源(如文件或数据库)则性能会很低,所以为了提升性能就可以将一部分数据暂时读写到缓存区,以后直接从此区域中读写数据即可,这样就显著提升了性能。
对于 Java 字符流的操作都是在缓冲区操作的,所以如果我们想在字符流操作中主动将缓冲区刷新到文件则可以使用 flush() 方法操作。
问:如何选择字节流和字符流?
答:如果是文本文件通常使用字符流,而像视频,图片,音频等文件都是二进制数据使用字节流。当然文本文件也可以使用字节流来操作,字节流更通用。
如果只是复制纯文本文件不做显示操作,哪个流都可以,如果要显示纯文本就用字符流。
问:为什么对于字符流中都有flush方法,但是字节流中没有?
字节流的操作不会经过缓冲区(内存)而是直接操作文本本身的,而字符流的操作会先经过缓冲区(内存)然后通过缓冲区再操作文件。
Java IO相关使用的更多相关文章
- Java IO入门
目录 一. 数据源(流) 二. 数据传输 三. 总结 我们从两个方面来理解Java IO,数据源(流).数据传输,即IO的核心就是对数据源产生的数据进行读写并高效传输的过程. 一. 数据源(流) 数据 ...
- 文件IO 相关的包:java.io文件——API
文件IO 相关的包:java.io文件——API 1.Java.io.File类的使用(1)两种路径绝对路径:相对于当前路径:当前为 “工程名”(2)File类创建,对象为一个文件/目录,可能存在或不 ...
- java IO流详解
流的概念和作用 学习Java IO,不得不提到的就是JavaIO流. 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...
- Java IO流学习总结
Java流操作有关的类或接口: Java流类图结构: 流的概念和作用 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...
- java.lang.IndexOutOfBoundsException at java.io.FileOutputStream.writeBytes(Native Method)
ss available : /usr/linkapp/data/linkapp/ddn_1440639847758_temp java.lang.IndexOutOfBoundsException ...
- java IO流 之 字节流
一.file类的常用操作 File file=new File("E:\\test\\javaIo"); System.out.println(file.isDirectory() ...
- [Java IO]02_字节流
概要 字节流有两个核心抽象类:InputStream 和 OutputStream.所有的字节流类都继承自这两个抽象类. InputStream 负责输入,OutputStream 负责输出. 字节流 ...
- 【转】java NIO 相关知识
原文地址:http://www.iteye.com/magazines/132-Java-NIO Java NIO(New IO)是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的 ...
- Java IO设计模式彻底分析 (转载)
一.引子(概括地介绍Java的IO) 无论是哪种编程语言,输入跟输出都是重要的一部分,Java也不例外,而且Java将输入/输出的功能和使用范畴做了很大的扩充.它采用了流的 机制来实现输入/输出,所谓 ...
随机推荐
- Java List 常用集合 ArrayList、LinkedList、Vector
Java 中的 List 是非常常用的数据类型.List 是有序的 Collection,Java List 一共有三个实现类,分别是:ArrayList.Vector.LinkedList 本文分析 ...
- powershell中使用Get-FileHash计算文件的hash值
今天在公司一台windows服务器上.需要对两个文件进行比对,笔者首先就想到了可以使用md5校验 但是公司服务器上又不可以随意安装软件,于是笔者想到了可以试试windows自带的powershell中 ...
- Redis中set集合(无序)操作命令
set集合(无序) set是一个无序的不重复元素的集合 增 sadd 往集合内部添加元素 127.0.0.1:6379> sadd set1 a b c d (integer) 4 127.0. ...
- Oracle学习(八)RECORD(自定义结构)
一.定义 记录数据类型的一种,将几个相关的.分离的.基本数据类型的变量组成一个类似于整体表结构的对象,即RECORD复合数据类型. 在使用记录数据类型变量时,需要在声明部分先定义记录的组成.记录的变量 ...
- JAVA MD5加密算法实现与原理解析
public static String md5Encode(String inputStr) { MessageDigest md5 = null; try { md5 = MessageDiges ...
- 基础Web漏洞-SQL注入入门(手工注入篇)
一.什么是SQL注入 SQL是操作数据库数据的结构化查询语言,网页的应用数据和后台数据库中的数据进行交互时会采用SQL.而SQL注入是将Web页面的原URL.表单域或数据包输入的参数,修改拼接成SQ ...
- GTA5整合版
GTA5mod整合版游戏介绍 GTA5mod整合版游戏是一款完美破解的游戏,玩家能够在游戏中享受最爽快的角色动作扮演玩法,在这里你将是一名强大的黑帮分子,在这个都市中,你将体验最真实的黑帮社会玩法.G ...
- Python-序列常用方法 + * += extend append方法区别
+ 两边都是相同序列类型.拼接成一个新的序列 print((1, 2, 3) + (4, 6)) print("beimenchuixue" + "ximenchuife ...
- Python练习题 022:用递归函数反转字符串
[Python练习题 022] 利用递归函数调用方式,将所输入的5个字符,以相反顺序打印出来. --------------------------------------- 又来一个递归题!不过,有 ...
- go分库分表 主从分离例子
网上有很多介绍分库分表的文章,方法很多: 分区表切分 垂直切分 水平切分 区间切分 取模切分 这里不细说 分库分表简单,但后期会带来一系列的难题: 事务 Join 分页 数据库: master和sla ...