全面掌握IO(输入/输出流)
File类:
程序中操作文件和目录都可以使用File类来完成即不管是文件还是目录都是使用File类来操作的,File能新建,删除,重命名文件和目录,但File不能访问文件内容本身,如果需要访问文件本身,则需要使用输入/输出流,该类是位于java.io包下的
输入与输出IO:
输入流:只能从中读取数据,而不能向其中写入数据(由InputStream(字节流)和Reader(字符流)作为基类)
输出流:只能向其写入数据,而不能从中读取数据(由OutputStream(字节流)和Writer(字符流)作为基类)
java的io总共涉及40多个类,但都是从这四个抽象基类中派生出来的
InputStream最重要的三个read方法:
Reader中的read方法:
从这两个抽象类提供的方法就可以看出其实功能基本是一样的,只是操作的数据单元不一样而已
由于InputStream与Reader都是抽象类,是不能进行实例化的,我们只能用他们的子类来创建实例,它们分别提供了一个子类用于读取文件的输入流:FileInputStream和
FileReader,这两个子类都是节点流(与处理流相对)-----会直接与指定的文件关联而无包装。下面代码演示FileInputStream使用read(byte[] b):

package xidian.sl.io; import java.io.FileInputStream;
import java.io.FileReader; public class InputStreamTest {
/**
* 使用FileInputStream读取该类本身
* */
public static void FileInputStreamTest() throws Exception{
FileInputStream fis = null;
try{
//创建字节输入流
fis = new FileInputStream("src/xidian/sl/io/InputStreamTest.java");
//创建一个长度为1024的字节数组来存取
byte[] bbuf = new byte[1024];
//用于保存实际读取的字节数
int hasRead = 0;
//使用循环来进行重复读取
while((hasRead = fis.read(bbuf))> 0){
//取出字节,将字节数组转化为字符串输出
System.out.println(new String(bbuf, 0 , hasRead));
}
}finally{
//关闭文件输入流
fis.close();
}
}
/**
* 使用FileReader读取该类本身
* */
public static void FileReaderTest() throws Exception{
FileReader fr = null;
try{
//创建字节输入流
fr = new FileReader("src/xidian/sl/io/InputStreamTest.java");
//创建一个长度为1024的字节数组来存取
char[] bbuf = new char[40];
//用于保存实际读取的字节数
int hasRead = 0;
//使用循环来进行重复读取
while((hasRead = fr.read(bbuf))> 0){
//取出字节,将字节数组转化为字符串输出
System.out.println(new String(bbuf, 0 , hasRead));
}
}finally{
//关闭文件输入流
fr.close();
}
}
public static void main(String[] args) throws Exception{
InputStreamTest.FileInputStreamTest();
InputStreamTest.FileReaderTest();
}
}

可以看到这两个子类的使用方式可以说是完全一样的,不过这里要注意一个问题:字节流FileInputStream是根据字节来读取的,而一个中文是占两个字节的,如果包含很多中文的文件被字节流分多次进行读取,可能会造成乱码,因为有可能会导致刚好将一个中文分两次读取,这样就会乱码了,因此如果中文包含多的话还是使用字符流FileReader比较好,
在字节流与字符流之间选择的规律:如果需要进行输入/输出的内容是文本内容,则应该考虑使用字符流,如果需要进行输入/输出的是二进制内容,则应该考虑使用字节流,因为字节流的功能比字符流强大,计算机中所有的数据都是二进制的,而字节流可以处理所有的二进制文件;
OutputStream中最重要的write方法:
Writer中最重要的write方法:
Writer类中多了两个对字符串的操作类,因此如果是直接输出字符串就选用Writer会比较的方便;
与输入流一样,输出流也有两个文件操作的子类:FileOutputStream和FileWrite

package xidian.sl.io; import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter; public class OutputStreamTest {
/**
* 使用字节流输出
* */
public static void FileOutputStreamTest() throws Exception{
FileInputStream fis = null;
FileOutputStream fos = null;
try{
//创建字节输入流
fis = new FileInputStream("src/xidian/sl/io/InputStreamTest.java");
//创建字节输出流
fos = new FileOutputStream("src/xidian/sl/io/Output.txt");
byte[] bt = new byte[40];
int hasRead = 0;
//循环从输入流中读取数据
while((hasRead = fis.read(bt))> 0){
//每读取一个,即写入文件输出流,读了多少就写多少
fos.write(bt, 0, hasRead);
} }catch (Exception e) {
e.printStackTrace();
}finally{
/**
* 流在关闭时会自动执行flash,将缓冲中的数据flush到物理节点中
* 所以关闭时很重要的
* */
if(fis != null){
fis.close();
}
if(fos != null){
fos.close();
}
}
}
/**
* 使用字符流输出字符串会显得比较的方便
* */
public static void FileWriteTest() throws Exception{
FileWriter fw = null;
try{
//创建字节输出流
fw = new FileWriter("src/xidian/sl/io/Output.txt");
fw.write("温州医学院\r\n");
fw.write("信息与管理专业\r\n");
fw.write("温州医学院\r\n");
fw.write("温州医学院\n");
fw.write("温州医学院");
}catch (Exception e) {
e.printStackTrace();
}finally{
if(fw != null){
fw.close();
}
}
}
public static void main(String[] args) throws Exception{
OutputStreamTest.FileOutputStreamTest();
OutputStreamTest.FileWriteTest();
}
}

上面是节点流的基本使用,下面将了解处理流的使用,处理流会显得更加的高效
区分节点流于处理流的方法是:只要流的构造器的参数不是一个物理节点,而是已存在的流,那这个流一定是处理流,因为所有的节点流都是直接以物理io节点作为构造器的参数、
(如file)。
举例:PrintStream处理流来封装FileOutputStream节点流,进行输出,由于PrintStream类的输出功能非常的强大,因此我们需要输出文本内容一般都会将输出流包装成PrintStream后输出

package xidian.sl.io; import java.io.FileOutputStream;
import java.io.PrintStream; public class PrintStreamTest {
public static void main(String[] args){
PrintStream ps = null;
try{
//创建一个节点输出流
FileOutputStream fos = new FileOutputStream("src/xidian/sl/io/Output.txt");
//以PrintStream处理流来包装FileOutputStream节点流
ps = new PrintStream(fos);
ps.println("普通字符串");
ps.println(new PrintStreamTest());
}catch (Exception e) {
e.printStackTrace();
}finally{
ps.close();
}
}
}

其实我们一直使用的标准输出System.out的类型都是PrintStream:
从上面的实例就可以看出将节点流封装成处理流很简单,只需调用处理流的构造方法来传入节点流就可以了;而且看到上面流的关闭只是关闭了处理流而未去关闭节点流,这样做是完全正确的,以后我们在关闭流的时候只需要关闭最上层的处理流即可;
字符流中有两个特别的流来处理字符串的:StringReader和StringWriter,
可以看到使用时实例化只需要传入一个字符串即可:例子:

package xidian.sl.io; import java.io.StringReader;
import java.io.StringWriter; public class StringNodeTest { /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String src = "你是个神";
StringReader sr = new StringReader(src);
char[] chars = new char[40];
int hasRead = 0;
try{
//采用循环的方式
while((hasRead = sr.read(chars))>0){
System.out.println(new String(chars, 0, hasRead));
}
}catch (Exception e) {
e.printStackTrace();
}finally{
sr.close();
}
//创建StringWriter
StringWriter sw = new StringWriter(40);
sw.write("你是一个大神");
sw.write("你也是一个大神");
System.out.println(sw.toString()); } }

io系统提供的两个转换流:InputStreamReader和OutputStreamWriter,都是将字节流转化为字符流
在java中是使用System.in来提供键盘输入的,但这个标准输入流是InputStream类的实例:
而前面讲到了当处理的是文本内容时,使用字符流会显得比较方便,正好键盘输入就是文本的操作,因此我们有必须将System.in转换为字符流:

package xidian.sl.io; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader; public class KeyinTest {
public static void main(String[] args){
BufferedReader br = null;
try{
//将System.in对象转化为Reader对象
InputStreamReader isr = new InputStreamReader(System.in);
//将节点流包装为处理流
br = new BufferedReader(isr);
String buffer = null;
//采用循环的方式一行一行读取
while((buffer = br.readLine()) != null){
System.out.print("输入的内容 = "+ buffer);
}
}catch (Exception e) {
e.printStackTrace();
}finally{
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

PrintStream是有强大的输出功能,而BufferReader有强大的输入(即读取),因此在操作读取文本内容时尽可能将其转化为BufferReader,可以方便的使用readLine()方法
接下来最为强大的文件操作类RandomAccessFile来了,这个类既可以向文件输入数据,也可以输出数据,并且他与不同的流最大的不同就是“支持文件任意位置的访问”,即程序可以控制读取文件哪个位置的内容;
从构造方法上可以看出,除了提供一个文件或文件名外还需要提供一个String参数mode,mode规定了RandomAccessFile类访问文件的模式:
1. “r”:以只读的方式打开指定文件
2. “rw”:以读取,写入方式打开指定文件,并且文件不存在会自动进行创建
3.“rws”与“rwd”:与“rw”类似,只是要求文件内容或元数据的每个更新都同步写入底层存储设备
全面掌握IO(输入/输出流)的更多相关文章
- java.IO输入输出流:过滤流:buffer流和data流
java.io使用了适配器模式装饰模式等设计模式来解决字符流的套接和输入输出问题. 字节流只能一次处理一个字节,为了更方便的操作数据,便加入了套接流. 问题引入:缓冲流为什么比普通的文件字节流效率高? ...
- IO输入输出流
在Java中进行文件的读写,Java IO流是必备的知识. IO流指 的是输入输出流,用来处理设备上的数据.这里的设备指硬盘,内存,键盘录入,网络传输等. 按处理数据类型来分:字节流和字符流. 按流的 ...
- c++中IO输入输出流总结<二>
1 文件的打开和关闭 1.1 定义流对象 ifsteam iflie;//文件输入流对象 ifsteam iflie;//文件输出流对象 fsteam iflie;//文件输入输出流对象 1.2 打开 ...
- java IO输入输出流中的各种字节流,字符流类
字节流字节流主要是操作byte类型数据,也byte数组为准,主要操作类就是·字节输出流:OutputStream·字节输入流:InputStream字符流在程序中一个字符等于2个字节,那么java提供 ...
- java io 输入输出流
数据流分类: 流序列中的数据既可以是未经加工的原始二进制数据, 也可以是经一定编码处理后符合某种格式规定的特定数据. 因此Java中的流分为两种: 1) 字节流:数据流中最小的数据单元是字节 2) 字 ...
- 1、IO输入&输出流 简介
IO流的分类: * 流向: * 输入流 读取数据 * 输出流 写出数据 * 数据类型: * 字节流 * 字节输入流 读取数据 InputStream * 字节输出流 写出数据 OutputStream ...
- c++中IO输入输出流总结<一>
1 io类图关系 1.1 简化形式 1.1.2补充 iostream: istream:从流中读取 ostream:写入到流 iosteram:读写流 fstream: ifstream:从文件读 o ...
- Java IO 输入输出流 详解 (一)***
首先看个图: 这是Javaio 比较基本的一些处理流,除此之外我们还会提到一些比较深入的基于io的处理类,比如console类,SteamTokenzier,Externalizable接口,Seri ...
- 详解Java中的IO输入输出流!
目录 本片要点 基本分类 发展史 文件字符流 输出的基本结构 流中的异常处理 异常处理新方式 读取的基本结构 运用输入与输出完成复制效果 文件字节流 缓冲流 字符缓冲流 装饰设计模式 转换流(适配器) ...
随机推荐
- Python基础一数据类型之数字类型
摘要: python基础一中提到了数据类型,这里主要讲解的是数字类型. 数字类型: 1,整型 2,长整型 3,浮点型 4,复数型 1,整型(int) 定义a = 1 通过type函数查看数据类型,整型 ...
- 分享一个基于小米 soar 的开源 sql 分析与优化的 WEB 图形化工具
soar-web 基于小米 soar 的开源 sql 分析与优化的 WEB 图形化工具,支持 soar 配置的添加.修改.复制,多配置切换,配置的导出.导入与导入功能. 环境需求 python3.xF ...
- 搭建企业级NFS网络文件共享服务
NFS服务简介 NFS是Network File System(网络文件系统).主要功能是通过网络让不同的服务器之间可以共享文件或者目录.NFS客户端一般是应用服务器(比如web,负载均衡等),可以 ...
- Windows API串口编程详解
(一)Windows API串口通信编程概述 Windows环境下的串口编程与DOS环境下的串口编程有很大不同.Windows环境下的编程的最大特征之一就是设备无关性,它通过设备驱动程序将Window ...
- vc MFC 通过IDispatch调用默认成员函数
CComPtr<IDispatch> spDisp(IDispatch *); if(!spDisp) return; DISPPARAMS dispParam={0}; //没有参数 V ...
- ES6标准入门之变量的解构赋值简单解说
首先我们来看一看解构的概念,在ES6标准下,允许按照一定模式从数组和对象中提取值,然后对变量进行赋值,这被称作解构,简而言之粗糙的理解就是变相赋值. 解构赋值的规则是,只要等号右边的值不是对象或者数组 ...
- POJ 3415 Common Substrings 【长度不小于 K 的公共子串的个数】
传送门:http://poj.org/problem?id=3415 题意:给定两个串,求长度不小于 k 的公共子串的个数 解题思路: 常用技巧,通过在中间添加特殊标记符连接两个串,把两个串的问题转换 ...
- docker swarm英文文档学习-2-关键概念
参考https://docs.docker.com/engine/swarm/key-concepts/ Swarm mode key concepts集群模式关键概念 本主题介绍Docker Eng ...
- OpenCV——阈值化
上述五种结合CV_THRESH_OTSU(自适应阈值),写成:THRESH_BINARY | CV_THRESH_OTSU
- OpenCV——颜色缩减、计时函数、访问像素
//颜色空间缩减 //src:源图片 //dst:目标图片 //divideWith:缩减宽度 void ColorSpaceReduction(Mat src,int divideWith,Mat& ...