------- http://www.itheima.com" target="blank">android培训、http://www.itheima.com"target="blank">java培训、期待与您交流!
一、IO流:
1.字节流:
1).输出流:OutputStream:写入的方法:三种:写入一个字节;写入一个字节数组;写入一个字节数组的一部分
2).输入流:InputStream:读取的方法:两种:读取一个字节;读取一个字节数组;
2.字符流:
1).输出流:Writer:写入的方法:五种:写入一个字符;写入一个字符数组;写入一个字符数组的一部分;写入一个字符串;写入一个字符串的一部分
OutputStreamWriter(转换流):是字符流通向字节流的桥梁
2).输入流:Reader:读取的方法:两种:读取一个字符;读取一个字符数组;
InputStreamReader(转换流):是字节流通向字符流的桥梁
3.数据输入输出流:可以读写Java中基本数据类型,当写入文本时,是按各种数据类型相应的字节数写入的;
DataInputStream: DataOutputStream:
4.内存操作流(byte[]数组的缓存区流):它类似于StringBuffer
ByteArrayOutputStream: ByteArrayInputStream:
5.打印流:
分类:1).字节流:PrintStream: (System.out) 2).字符流:PrintWriter:
特点:1).只能操作目的地,不能操作数据。 2).可以操作任意类型的数据。 3).如果启动了自动刷新,能够自动刷新。4).可以操作文件的流
6.三种方式实现接收控制台数据:Scanner; main()方法形参; System.in: System.in --> 转换流 --> 带缓冲的字符流
7.随机访问流:RandomAccessFile:
1).获取文件指针:getFilePointer();
2).设置文件指针:seek();
8.序列化流:
1)序列化流:ObjectOutputStream;2)反序列化流:ObjectInputStream; 3).注意:需要被序列化的类,必须实现接口:Serializable;4).为了控制版本号,建议定义成员变量:serialVersionUID设定版本号;5).使用transient关键字声明不需要序列化的成员变量;
9.Properties类:1).它本质上是一个Map集合,直接继承自:Hashtable;2).它结合IO流,可以读写配置文件中的属性信息; 3).读取配置文件:load(Reader reader);4).写入配置文件:store(Writer out,String str):
10.JDK7的NIO:Path:与平台无关的路径。Paths:包含了返回Path的静态方法。
public static Path get(URI uri):根据给定的URI来确定文件路径。
Files:操作文件的工具类。提供了大量的方法,简单了解如下方法
public static long copy(Path source, OutputStream out) :复制文件
public static Path write(Path path, Iterable<? extends CharSequence> lines, Charset cs, OpenOption... options):把集合的数据写到文件。
二、通过一些案例来深入了解IO流:
<span style="font-family:Microsoft YaHei;font-size:18px;">package cn.itcaast;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
/*
* 由于我们常见的操作都是使用本地默认编码,所以,不用指定编码。
* 而转换流的名称有点长,所以,Java就提供了其子类供我们使用。
* OutputStreamWriter = FileOutputStream + 编码表(GBK)
* FileWriter = FileOutputStream + 编码表(GBK)
* InputStreamReader = FileInputStream + 编码表(GBK)
* FileReader = FileInputStream + 编码表(GBK
*
* OutputStreamWriter(OutputStream out):根据默认编码把字节流的数据转换为字符流
* OutputStreamWriter(OutputStream out,String charsetName):根据指定编码把字节流数据转换为字符流
* 把字节流转换为字符流。
* 字符流 = 字节流 +编码表。
*/
public class OutputStreamWriter_Reader {
public static void main(String[] args) throws IOException {
//封装数据源
FileReader fr = new FileReader("ycn.txt");
//封装目的地
FileWriter fw = new FileWriter("jdj.txt");
//复制
/*int ch = 0;
while((fr.read())!=-1){
fw.write(ch);
}*/
char[] ch = new char[1024];
int len = 0;
while((len = fr.read(ch))!=-1){//读取一个数组长度
fw.write(ch,0,len);
fw.flush();
}
//释放资源
fr.close();
fw.close();
}
}
</span>
<span style="font-family:Microsoft YaHei;font-size:18px;">package cn.itcaast;
import java.io.IOException;
/*
* IO流的分类:
* 1.按流向分:输出流(写出数据) ,输入流(读取数据)
* 2.按数据类型分:字节流 InputStream/OutputStream
* 字符流 Reader/Writer
* 字节输出流操作步骤:
* A.创建字节输出流对象 B.调用write()方法 C.释放资源
* 如何实现数据的换行?(不同的操作系统针对不同的换行标识符是不一样的)
* windows:\r\n linux:\n mac:\r
* 如何实现数据的追加写入:用构造方法带第二个参数是true的情况就可。
*/
import java.io.FileOutputStream;
public class FileOutputStreamDemo {
public static void main(String[] args) throws IOException {
// 创建字节流对象(调用系统功能去创建文件;创建fos对象;把fos对象指向该文件)
FileOutputStream fos = new FileOutputStream("yu.txt");
// 写数据
fos.write("Hello,IO".getBytes());
fos.write("\r\n".getBytes());
fos.write("java".getBytes());
// 释放资源(关闭此文件输出流并释放与此流有关的所有系统资源)
fos.close();
/*
* 使用close():1.让流对象变成垃圾,这样就可以被垃圾回收器回收了
* 2.通知系统去释放该文件相关的资源
*/
//创建字节流输出对象
//OutputStream os = new FileOutputStream("zhi.txt"); //多态
FileOutputStream fo = new FileOutputStream("zhi.txt");
//调用write()方法,写入数据
//public void Write(int)输出一个字节
fo.write(104);
fo.write("\r\n".getBytes());
//public void write(byte[] b)输出一个字节数组
byte[] b = {98,104,102,99};
fo.write(b);
fo.write("\r\n".getBytes());
//public void write(byte[], int off,int len)输出一个字节数组的一部分
fo.write(b,1,3);
fo.write("\r\n".getBytes());
//释放资源
fo.close();
//创建一个向具有指定name的文件中写入数据的输出文件流。如果第二个参数为true,则将字节写入文件末尾处
FileOutputStream f = new FileOutputStream("po.txt",true);
//写数据
for(int i = 0;i<10;i++){
f.write(("hello"+i).getBytes());
f.write("\r\n".getBytes());
}
//释放资源
f.close();
}
}
</span>
<span style="font-family:Microsoft YaHei;font-size:18px;">package cn.itcaast;
import java.io.FileInputStream;
import java.io.IOException;
/*
* 字节输入流操作步骤:1.创建字节流输入对象 2.调用read()方法读取数据,并把数据显示在数据台 3.释放资源
* 读取数据的方式:1.int read():一次读取一个字节 2.int read(byte[] b):一次读取一个字节数组
*/
public class FileIntputStrreamDemo {
public static void main(String[] args) throws IOException {
// 创建字节流输入对象
FileInputStream fis = new FileInputStream("E:\\Code\\day2\\DDD.java");
// 调用read()方法读取数据,并把数据显示在数据台
int i = 0;
// 读取,赋值,判断(因每次读取只能读取一个字节,为了简化代码,使用循环结构;当i==-1时,说明文件解析到末尾)
while ((i = fis.read()) != -1) {
System.out.print((char) i);
}
// 释放资源
fis.close();
// 创建字节输入流对象
FileInputStream fi = new FileInputStream(
"E:\\Code\\day5\\Code\\Demo.java");
// 读取字节数组
byte[] bys = new byte[1024];
int len = 0;
while ((len = fi.read(bys)) != -1) {
System.out.print(new String(bys, 0, len));
}
/*int len = 0;
while ((len = fi.read(new byte[1024])) != -1) {
// String str = new String[byte[] bytes, int offset, int length];
System.out.print(new String(new byte[1024], 0, len));
}*/
fi.close();
}
}
</span>
<span style="font-family:Microsoft YaHei;font-size:18px;">package cn.itcaast;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* 缓冲区类(高效类)
* 写数据:BufferedOutputStream
* 读数据:BufferedInputStream
* 为什么缓冲区流类不构造方法不传递一个具体的文件或者文件路径,而是传递一个OutputStream对象呢?
* 因为字节缓冲区流仅仅提供缓冲区,为高效而设计的;但是真正的读写操作还得靠基本流对象实现。
*/
public class BufferedInput_OutputStreamDemo {
public static void main(String[] args) throws IOException {
// 封装原数据流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
"demo\\t.doc"));
// 封装目的数据流
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("demo1\\b.doc"));
// 读取数据
/*
* int by = 0; while((by=bis.read())!=-1){ System.out.println((char)by);
* }
*/
//写数据
// bos.write("jkshkdj".getBytes());//括号内将字符串转换成字节数组
byte[] by = new byte[1024];
int len = 0;
while ((len = bis.read(by)) != -1) {
// System.out.println(new String(by,0,len));
bos.write(by, 0, len);
}
// 释放资源
bis.close();
bos.close();
}
}
</span>
<span style="font-family:Microsoft YaHei;font-size:18px;">package cn.itcaast;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
/*
* BufferedReader:
* 从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
* 可以指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值就足够大了。
* BufferedWriter:字符缓冲输出流
* 将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。
* 可以指定缓冲区的大小,或者接受默认的大小。在大多数情况下,默认值就足够大了。
*
* 字符缓冲流的特殊方法:
* BufferedWriter:
* public void newLine():根据系统来决定换行符
* BufferedReader:
* public String readLine():一次读取一行数据
* 包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null
*
* 面试题:close()和flush()的区别?
* A:close()关闭流对象,但是先刷新一次缓冲区。关闭之后,流对象不可以继续再使用了。
* B:flush()仅仅刷新缓冲区,刷新之后,流对象还可以继续使用。
*
* 需求:把当前项目目录下的a.txt内容复制到当前项目目录下的b.txt中
*/
public class BufferedReader_Writer {
public static void main(String[] args) throws IOException {
//封装数据源
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
//封装目的地
BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));
//读取数据
/*int by = 0;
while((by=br.read())!=-1){
System.out.println((char)by);
}*/
/*char[] chs = new char[1024];//数组方式
int len = 0;
while((len = br.read(chs))!=-1){
bw.write(chs, 0, len);
bw.flush();
}*/
String line = null;//特有的读取一行功能
while((line = br.readLine())!=null){
bw.write(line);
bw.newLine();
bw.flush();
}
/*
* bw.write("Hello");
* bw.write("true");
* bw.flush();
*/
//释放资源
br.close();
bw.close();
}
}
</span>
<span style="font-family:Microsoft YaHei;font-size:18px;">package cn.itcaast;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* 1.复制某盘中的MV项目到当前目录下的copy.flv中
* 分析:读取原文件中数据FileInputStream;写出读取的数据到目标文件FileOutputStream
* 2.复制某盘内容到当前目录下
* 3.计算机中中文的存储分两个字节:第一个字节肯定是负数;第二个字节常见的是负数,可能是正数。
* 如:String s = "abcd"; ----->[97,98,99,100]
* String s = "我们";------>[-50,-65,-45,34]
* byte[] bys = s.getBytes();
* System.out.println(Arrays.toString(bys));
*/
public class CopyMVDemo {
public static void main(String[] args) throws IOException {
// 封装数据源
FileInputStream fis = new FileInputStream(
"E:\\PhotoShop CS6基础培训教程\\003 什么是adobe bridge.flv");
// 封装目的地
FileOutputStream fos = new FileOutputStream("copy.flv");
// 复制数据
byte[] b = new byte[1024];// 创建一个1024个字节的容器
int len = 0;// 数据初始化
while ((len = fis.read(b)) != -1) {
fos.write(b, 0, len);
}
// 释放资源
fis.close();
fos.close();
System.out.println("复制完毕!");
//这些复制操作在复制的过程中将文件的名字也改变了
//封装数据源
FileInputStream fi = new FileInputStream("E\\Demo\\day01\\Demo.java");
//封装目的地
FileOutputStream fo = new FileOutputStream("Demo.java");
//复制数据
/*
* int len = 0;
* while((len=fi.read())!=-1){
* fo.write(len);
* }
*/
byte[] by = new byte[1024];
int lenth = 0;//必须初始化为0
while((lenth=fi.read(by))!=-1){
fo.write(by,0,lenth);
}
//释放资源
fi.close();
fo.close();
/*
* public int read(byte[] b,int off,int len)
* throws IOException从此输入流中将最多 len 个字节的数据读入一个 byte 数组中。
* 如果 len 不为 0,则在输入可用之前,该方法将阻塞;否则,不读取任何字节并返回 0。
*/
}
}
</span>
<span style="font-family:Microsoft YaHei;font-size:18px;">package cn.itcaast;
import java.io.IOException;
import java.io.RandomAccessFile;
/*
* 构造方法:
* RandomAccessFile(File file,String mode) 创建并从中读取和向其中写入(可选)的随机访问
* 文件流,该文件由File参数指定。
* RandomAccessFile(String name,String mode) 创建从中读取和向其中写入(可选)的随机访
* 问文件流,该文件具有指定名称。
*
* mode:
* "r"以只读方式打开,调用结果对象的任何write方法都将导致IOException。
* "rw"打开以便读取和写入,如果该文件尚不存在,则尝试创建该文件。
*
* 成员方法:
* 获取文件指针:
* getFilePointer():获取当前的文件指针
* seek():设置当前文件指针
*/
public class Demo_随机访问流_RondomAccessFile {
public static void main(String[] args) {
try {
write();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
read();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static void write() throws IOException {
RandomAccessFile out = new RandomAccessFile("demo.txt", "rw");
out.writeInt(120);
out.writeBoolean(true);
out.writeShort(20);
out.writeUTF("你好");
out.close();
System.out.println("写入完毕!");
}
private static void read() throws IOException {
RandomAccessFile in = new RandomAccessFile("demo.txt", "r");
System.out.println("文件指针位置:" + in.getFilePointer());
int val1 = in.readInt();
System.out.println("读取int后,指针位置:" + in.getFilePointer());
boolean val2 = in.readBoolean();
System.out.println("读取boolean后,指针位置:" + in.getFilePointer());
short val3 = in.readShort();
System.out.println("读取short后,指针位置:" + in.getFilePointer());
String val4 = in.readUTF();
System.out.println("读取UTF后,指针位置:" + in.getFilePointer());
// 将指针移到boolean位置,重新读取boolean
in.seek(4);
boolean val5 = in.readBoolean();
in.close();
System.out.println(val1);
System.out.println(val2);
System.out.println(val3);
System.out.println(val4);
System.out.println(val5);
System.out.println("数据读取完毕!");
}
}
</span>
package cn.itcaast;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/*
* 1.复制某盘中的MV项目到当前目录下的copy.flv中
* 分析:读取原文件中数据FileInputStream;写出读取的数据到目标文件FileOutputStream
* 2.复制某盘内容到当前目录下
* 3.计算机中中文的存储分两个字节:第一个字节肯定是负数;第二个字节常见的是负数,可能是正数。
* 如:String s = "abcd"; ----->[97,98,99,100]
* String s = "我们";------>[-50,-65,-45,34]
* byte[] bys = s.getBytes();
* System.out.println(Arrays.toString(bys));
*/
public class CopyMVDemo {
public static void main(String[] args) throws IOException {
// 封装数据源
FileInputStream fis = new FileInputStream(
"E:\\PhotoShop CS6基础培训教程\\003 什么是adobe bridge.flv");
// 封装目的地
FileOutputStream fos = new FileOutputStream("copy.flv");
// 复制数据
byte[] b = new byte[1024];// 创建一个1024个字节的容器
int len = 0;// 数据初始化
while ((len = fis.read(b)) != -1) {
fos.write(b, 0, len);
}
// 释放资源
fis.close();
fos.close();
System.out.println("复制完毕!");
//这些复制操作在复制的过程中将文件的名字也改变了
//封装数据源
FileInputStream fi = new FileInputStream("E\\Demo\\day01\\Demo.java");
//封装目的地
FileOutputStream fo = new FileOutputStream("Demo.java");
//复制数据
/*
* int len = 0;
* while((len=fi.read())!=-1){
* fo.write(len);
* }
*/
byte[] by = new byte[1024];
int lenth = 0;//必须初始化为0
while((lenth=fi.read(by))!=-1){
fo.write(by,0,lenth);
}
//释放资源
fi.close();
fo.close();
/*
* public int read(byte[] b,int off,int len)
* throws IOException从此输入流中将最多 len 个字节的数据读入一个 byte 数组中。
* 如果 len 不为 0,则在输入可用之前,该方法将阻塞;否则,不读取任何字节并返回 0。
*/
}
}