目录
* IO流知识点
1.IO流(输出流)
1.1)IO流:在设备之间进行数据传输的操作!
package com.qianfeng.io_03;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* IO流
* 在设备之间进行数据传输的操作!
*
* 按流的方向划分:
* 输入流
* 输出流
*
* 按流的类型划分
* 字节流
*
* 字节输入流:InputStream
* 字节输出流:OutputStream
* 字符流
* 字符输入流:Reader
* 字符输出流:Writer
*
* 字符流是在字节输入流之后出现的,解决了中文乱码问题!
* 一般情况:针对某个文本文件进行读写复制操作: 优先采用字符流 (使用记事本打开并且能读懂!)
*
* 字节流
*
* 字节输入流:InputStream
* 字节输出流:OutputStream
*
* 两个抽象类,不能直接实例化,提供了一些具体的子类
* XXXInputStream
* XXXOutputStream
* 都是字节输入流和字节输出流的子类
*
* 需求:需要在当前项目下输出文件:fos.txt文件,并同时输出内容:"hello,OutputStream"
*
* FileOuputStream:针对文件操作:文件输出流(文件字节输出流)
* public FileOutputStream(String name):
* public FileOutputStream(File file)
* 推荐使用第一种:直接跟当前的具体路径!
* 使用步骤
* 1)创建OutputStream字节输出流对象,同时指向某个文件路径
* 2)写数据:给文件中写入内容
* 3)关闭相关的系统资源
*/
public class FileOutputStreamDemo {
public static void main(String[] args) throws IOException {
//1)创建OutputStream字节输出流对象,同时指向某个文件路径
// OutputStream out = new FileOutputStream("fos.txt") ;//抽象类多态方式
//创建输出流对象---->调用系统资源:在本地的项目下创建具体文件fos.txt
//流对象---指向文件地址
FileOutputStream fos = new FileOutputStream("fos.txt") ;
//2)写入内容
//通过流对象给文件写入内容(写入的字节数组)
fos.write("hello,outputStream".getBytes());
//3)释放资源
//将输出流对象的系统资源释放掉!
fos.close();
}
}
1.2)字节输出流写数据的功能
package com.qianfeng.io_03;
import java.io.FileOutputStream;
import java.io.IOException;
/**
*
* 字节输出流写数据的功能
* void write(byte[] b) :给指定的文件写入字节数组
* void write(byte[] b, int off, int len) :写入字节数组的一部分
* abstract void write(int b) :写入一个字节
* @author zhangyang
*
*/
public class FileOutputStreamDemo2 {
public static void main(String[] args) throws IOException {
//创建一个文件字节输出流对象
FileOutputStream fos = new FileOutputStream("fos2.txt") ;
// void write(int b) :写入一个字节
//写入97:字节---保存的时候,在ASII码表中找当前字节对应的整数值
//fos.write(97);
//void write(byte[] b) :给指定的文件写入字节数组
//创建字节数组,静态初始化
byte[] bytes = {97,98,99,100,101} ;
//fos.write(bytes);
//void write(byte[] b, int off, int len) :写入字节数组的一部分
fos.write(bytes, 1, 2);
//关闭资源
fos.close();
}
}
1.3)IO流中:字节输出流中加入异常操作
package com.qianfeng.io_03;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* 异常的处理方式
* throws
* try...catch..finally:开发汇中,使用这种格式
*
*IO流中:字节输出流中加入异常操作
* @author zhangyang
*
*/
public class FileOutputStreamDemo3 {
public static void main(String[] args) {
//在当前项目下:输出fos3.txt文件
// 方式1:分别进行try...catch
/*
FileOutputStream fos = null ;
try {
fos = new FileOutputStream("fos3.txt") ;
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//写数据
try {
fos.write("hello,io,i'm coming...".getBytes());
} catch (IOException e) {
e.printStackTrace();
}
//关闭资源
if(fos!=null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
*/
//方式2:try...catch...catch...finally...
//创建字节输出流对象
FileOutputStream fos = null;
try {
fos = new FileOutputStream("fos3.txt");
//写数据
fos.write("hello,io!i'm coming...".getBytes());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
//释放资源
//如果当前流对象不为null,才能够关闭
if(fos!=null) {
//关闭资源
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
1.4)FileOutputStream的构造方法:创建输出流对象
package com.qianfeng.io_03;
import java.io.FileOutputStream;
import java.io.IOException;
/**
*
* FileOutputStream的构造方法
* public FileOutputStream(String name, boolean append):
* 创建输出流对象,并指向文件,将文件内容写入到末尾:第二个参数为:true:写入末尾
*
* 如何进行换行,写一个内容,换一行!
*
* windows操作系统:
* 换行符号:\r\n
*
* @author zhangyang
*
*/
public class FileOutputStreamDemo4 {
public static void main(String[] args) throws IOException {
//public FileOutputStream(String name, boolean append):
//末尾追加内容
FileOutputStream fos = new FileOutputStream("fos4.txt", true) ;
//写入数据
for(int x = 0 ; x <10 ; x ++) {
fos.write(("hello"+x).getBytes());
//写入一个换行符号
fos.write("\r\n".getBytes());
}
//关闭资源
fos.close();
}
}
2.IO流(输入流)
2.1)文件字节输入流:FileInputStream
package com.qianfeng.io_fileinputstream_04;
import java.io.FileInputStream;
import java.io.IOException;
/**
* 文件字节输入流:FileInputStream
*
* 构造方法
* public FileInputStream(String name)throws FileNotFoundException
* 读数据
* public abstract int read():一次读取一个字节
* public int read(byte[] b) throws IOException:一次读取一个字节数组
*
* 使用步骤
* 1)创建FileInputStream对象:指向哪个文件
* 2)读数据 :public abstract int read():读取一个字节
* 展示结果
* 3)关闭资源
*
*
* @author zhangyang
*
*/
public class FileInputStreamDemo {
public static void main(String[] args) throws IOException {
//创建FileInputStream对象
// FileInputStream fis = new FileInputStream("fis.txt") ;
FileInputStream fis = new FileInputStream("DiGuiTest.java") ;
//public abstract int read():一次读取一个字节
/*
//第一次读
int by = fis.read() ;
System.out.println(by);//97--a
System.out.println((char)by);
//第二次读取
by = fis.read() ;
System.out.println(by);//98--b
System.out.println((char)by);
//第三次读取
by = fis.read() ;
System.out.println(by);
System.out.println((char)by);
//第四次读取
by = fis.read();
System.out.println(by);
System.out.println((char) by);
// 第五次读取
by = fis.read();
System.out.println(by);
System.out.println((char) by);
//第六次读取
by = fis.read() ;
System.out.println(by);//-1
System.out.println((char)by);
*/
//上面代码:重复度很高,使用循环:while循环
//结束条件:-1 :当前read():返回值为-1:流对象读取已经到达文件末尾
/*
int by = fis.read() ;
while(by!=-1) {
System.out.print((char)by);
by = fis.read() ;
}
*/
//最终版代码:上面优化
//获取,赋值,判断可以写在一块
//定义一个字节
int by = 0 ;
while((by=fis.read())!=-1) {
//数据没有读取完毕
System.out.print((char)by); //强制转换:造成中文乱码:中文存储的问题
//一个中文:gbk格式:一个中文两个字节,而且第一个字节是负数!
}
//关闭资源
fis.close();
}
}
2.2)对应中文存储
package com.qianfeng.io_fileinputstream_04;
import java.util.Arrays;
/**
* 对应中文存储:第一个字节一定是负数,第二个字节可以是负数,整数...
* @author zhangyang
*
*/
public class StringDemo {
public static void main(String[] args) {
//String s = "中国" ; //平台:GBK格式:一个中文对应两个字节
String s = "我爱你" ;
//String s = "abc" ;
//将它转换成字节数组
byte[] bytes = s.getBytes() ;
//System.out.println(bytes);
//将数组---String:能到里面存储字节数
System.out.println( Arrays.toString(bytes)) ;
//[-42, -48, -71, -6]
//[-50, -46, -80, -82, -60, -29]
}
}
2.3)一次读取一个字节数组
package com.qianfeng.io_fileinputstream_04;
import java.io.FileInputStream;
import java.io.IOException;
/**
* public int read(byte[] b) throws IOException:一次读取一个字节数组
*
* 返回值:描述的是实际读取的字节数
*
* @author zhangyang
*
*/
public class FileInputStreamDemo2 {
public static void main(String[] args) throws IOException {
//创建一个字节文件输入流对象
// FileInputStream fis = new FileInputStream("fis2.txt") ;
FileInputStream fis = new FileInputStream("DiGuiTest.java") ;
//读取数据
//public int read(byte[] b)
/*
//定一个字节数组
byte[] bytes = new byte[5] ;
//第一次读取
int len = fis.read(bytes) ;//返回实际读取的字节数
System.out.println(len);
System.out.println(new String(bytes));//将字节数组--String
//第二次读取
len = fis.read(bytes) ;
System.out.println(len);
System.out.println(new String(bytes));
//第三次读取
len = fis.read(bytes) ;
System.out.println(len);
System.out.println(new String(bytes));
//四次读取
len = fis.read(bytes) ;
System.out.println(len);
System.out.println(new String(bytes));
//五次读取
len = fis.read(bytes);
System.out.println(len);
System.out.println(new String(bytes));
*/
//一般情况:定义字节数组的时候:
//一次读取一个字节数组的最终版代码
//长度:是1024或者1024的整数倍
byte[] bytes = new byte[1024] ;
//赋值,判断
//定义一个实际读取的字节数
int len = 0 ;
while((len=fis.read(bytes))!=-1) {
//没有读完,继续读取
// System.out.println(new String(bytes));
//public String(byte bytes[], int offset, int length)
System.out.println(new String(bytes, 0, len));
//每次从0开始,读取实际字节数
}
//关闭资源
fis.close();
}
}
2.4)读写复制操作(一次读取一个字节&&一次读取一个字节数组)
package com.qianfeng.io_fileinputstream_04;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
*
* 读写复制操作
*
* 在d盘下有一个FileInputStreamDemo.java文件的内容
*
*
* 复制到当前项目路径下:Copy.java文件中
*
* 分析:
* 1)封装d盘的文件FileInputStreamDemo.java ---源文件
* 使用输入流读取FileInputStreamDemo.java文件的内容
*
* 2)封装目标文件:当前项目下:Copy.java
* 使用文件字节输出流写数据,将上面的内容复制进来!
*
* 3)两种方式
* 要么1)一次读取一个字节
* 要么2)一次读取一个字节数组
*
*
* 复制图片文件/视频文件...
*
* @author zhangyang
*
*/
public class CopyFileDemo {
public static void main(String[] args) throws IOException {
//封装d盘的文件FileInputStreamDemo.java ---源文件
//创建字节文件输入流对象
FileInputStream fis = new FileInputStream("d:\\FileInputStreamDemo.java") ;
//封装目标文件:当前项目下:Copy.java
FileOutputStream fos = new FileOutputStream("Copy.java") ;
/*
//读写复制操作
//方式1):1次读取一个字节
int by = 0 ;
while((by=fis.read())!=-1) {
//读一个字节,写一个字节到fos流对象中
fos.write(by);
}
*/
//方式2:一次读取一个字节数组
//定义一个数组
byte[] bytes = new byte[1024] ;
int len = 0 ;
while((len=fis.read(bytes))!=-1) {
//写一个字节数组:从0开始,写入实际字节数
fos.write(bytes, 0, len);
}
//释放资源
fos.close();
fis.close();
}
}
2.5)将指定文件夹的mp4文件复制到当前项目下
package com.qianfeng.io_fileinputstream_04;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
*
* 在d盘:一个mp4文件---将复制到当前项目下:copy.mp4文件中
*D:\JavaEE_2008\day26\avi\02_回顾内容_今日内容.mp4------
*
* 当前目下:Copy.mp4
*
*
*分析:
* 1)源文件:D:\JavaEE_2008\day26\avi\02_回顾内容_今日内容.mp4
* FileInputStream去读取
* 2)目标文件:项目下Copy.mp4
* FileOutputStream:写数据
*
*一次读取一个字节:耗时:240793毫秒 视频文件:17.1M
*一次读取一个字节:耗时:共耗时:343毫秒 视频文件:17.1M
* @author zhangyang
*
*/
public class CopyMp4Demo {
public static void main(String[] args) throws IOException {
//开始时间
long start = System.currentTimeMillis() ;
method("D:\\JavaEE_2008\\day26\\avi\\02_回顾内容_今日内容.mp4","Copy.mp4") ;
//结束时间
long end = System.currentTimeMillis() ;
System.out.println("共耗时:"+(end-start)+"毫秒");
}
//方式1:一次读取一个字节
//方式2:一次读取一个字节数组
private static void method(String srcFile, String destFile) throws IOException {
//封装源文件
FileInputStream fis = new FileInputStream(srcFile) ;
//封装目标文件
FileOutputStream fos = new FileOutputStream(destFile) ;
/*
//读写操作
int by = 0 ;
while((by=fis.read())!=-1) {
//写
fos.write(by);
}*/
//一次读取一个字节数组
byte[] bytes = new byte[1024] ;//缓冲区
int len = 0 ;
while((len=fis.read(bytes))!=-1) {
fos.write(bytes, 0, len);
}
//释放资源
fos.close();
fis.close();
}
}
3.字节缓冲流
3.1)字节缓冲输入流
package com.qianfeng_bufffered_01;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* BufferedInputStream extends InputStream:字节缓冲输入流
*
* 构造方法
* BufferedInputStream(InputStream in)
* @author zhangyang
*
*/
public class BufferedInputStreamDemo {
public static void main(String[] args) throws IOException {
//创建一个BufferedInputStream流对象
BufferedInputStream bis =
new BufferedInputStream(new FileInputStream("bos.txt")) ;
/**
* class BufferedInputStream{
* private static int DEFAULT_BUFFER_SIZE = 8192;
*
* public BufferedInputStream(InpLutStream in){
* this(in,DEFAULT_BUFFER_SIZE) ;
* }
* public BufferedInputStream(InputStream in, int size){
* ..
* }
* }
*/
//一次读取一个字节
/*
int by = 0 ;
while((by=bis.read())!=-1) {
//展示在控制台上
System.out.print((char)by);
}
*/
//一次读取一个字节数组
byte[] bytes = new byte[1024] ;
int len = 0 ;
while((len=bis.read(bytes))!=-1) {
System.out.println(new String(bytes,0,len));
}
//释放资源
bis.close();
}
}
3.2)字节缓冲输出流
package com.qianfeng_bufffered_01;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* BufferedOutputStream extends OutputStream:字节缓冲输出流
* 构造方法
* public BufferedOutputStream(OutputStream out)
* 创建一个缓冲输出流对象,默认缓冲区大小
*
* 目前:当前缓冲流只是在流中提供了byte[] 缓冲区,默认足够大,一般通过带一个参的构造方法创建!
* 只是提供缓冲区,具体文件读写复制操作还是需要用底层流(InputStream/OutputStream)
*
*
*
*
*
* @author zhangyang
*
*/
public class BufferedOutputStreamDemo {
public static void main(String[] args) throws IOException {
//public BufferedOutputStream(OutputStream out)
BufferedOutputStream bos =
new BufferedOutputStream(new FileOutputStream("bos.txt")) ;
/**
* this(out, 8192); 第二个参数:缓冲大小8192
*/
//写数据
bos.write("hello,bufferedOutputStream!".getBytes());
//释放资源
bos.close();
}
}
3.3)四种方式对文件进行读写复制操作
package com.qianfeng_bufffered_01;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
*
* 四种方式对文件进行读写复制操作
*将当前项目下 BufferedInputStreamDemo.java文件复制到项目下的Copy.java文件中
*
*
* FileInputStream/FileOutputStream:一次读取一个字节 共耗时44毫秒
* FileInputStream/FileOutputStream:一次读取一个字节数组
*
*高效的字节流
* BufferedInputStrea/BufferedOutputStream:一次读取一个字节
* BufferedInputStrea/BufferedOutputStream:一次读取一个字节数组
*
*
*
*复制视频文件
*
*
* @author zhangyang
*
*/
public class CopyFile {
public static void main(String[] args) throws IOException{
long start = System.currentTimeMillis() ;
// method1("BufferedInputStreamDemo.java","Copy.java") ;
method2("BufferedInputStreamDemo.java","Copy.java") ;
long end = System.currentTimeMillis() ;
System.out.println("共耗时"+(end-start)+"毫秒") ;
}
// FileInputStream/FileOutputStream:一次读取一个字节数组
private static void method2(String srcFile, String destFile) throws IOException {
//封装源文件和目的地文件
FileInputStream fis = new FileInputStream(srcFile) ;
FileOutputStream fos = new FileOutputStream(destFile) ;
byte[] buf = new byte[1024] ;
int len = 0 ;
while((len=fis.read(buf))!=-1) {
fos.write(buf, 0, len);
}
//释放资源
fis.close();
fos.close();
}
//FileInputStream/FileOutputStream:一次读取一个字节
private static void method1(String srcFile, String destFile) throws IOException {
//封装源文件和目的地文件
FileInputStream fis = new FileInputStream(srcFile) ;
FileOutputStream fos = new FileOutputStream(destFile) ;
int by = 0 ;
while((by=fis.read())!=-1) {
fos.write(by);
}
//释放资源
fis.close();
fos.close();
}
}
4.编码和解码(utf-8…)
package com.qianfeng_reader_and_writer_02;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
/**
* 编码和解码
*
* 编码:就将能够看懂的内容-----转换 "看不懂的内容"
* String byte[]
*
* 解码: 将看不懂的内容----------转换 "能看懂的内容"
* byte[] String
*
* 举例:
* "今天老地方" ----- > 字节数组 :编码
*
*
* 编码格式:
* big-5:大五码 (繁写字体)
* gbk:中国的中文编码表:一个中文对应两个字节
* gbk-2312:中国的中文编码表:一个中文对应两个字节:对上面 的编码扩展
* iso-8859-1:拉丁文码表
* utf-8:一个中文对应三个字节码
* JS:日本中的编码格式
*
*
* utf-8/gbk
*
* 编码和解码的过程必须保证格式统一:否则出现乱码!
*
*
* @author zhangyang
*
*/
public class StringDemo {
public static void main(String[] args) throws UnsupportedEncodingException {
//创建一个字符串
String s = "你好" ;
//String---->Byte[] getBytes():里面空参:平台默认编码集:gbk
//getBytes("utf-8");编码格式:utf-8
//byte[] bytes = s.getBytes() ;//默认gbk:一个中文对应两个字节
byte[] bytes = s.getBytes("utf-8") ;
//使用Arrays将数组---字符串
System.out.println(Arrays.toString(bytes));
//[-60, -29, -70, -61]
//[-28, -67, -96, -27, -91, -67]:utf-8:一个中文对应三个字节数
System.out.println("-----------------------------");
//解码
//byte[]---String :构造方法
// String(byte[] bytes):默认平台字符集解码
//String(byte[] bytes,Charset c):使用指定的字符集进行解码
String str = new String(bytes) ; //默认gbk解码 浣犲ソ(编码utf-8)
//String str = new String(bytes,"utf-8") ;//???乱码
System.out.println(str);//你好
}
}
5.字符流
5.1)字符输出流
package com.qianfeng_reader_and_writer_02;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
/**
* OutputStreamWriter:字符输出流(字符流通向字节流的桥梁):转换流
* 构造方法
* public OutputStreamWriter(OutputStream out):gbk格式 使用默认字符集进行编码的字符输出流
* public OutputStreamWriter(OutputStream out, Charset cs)
* 使用指定的字符集构造出一个字符输出流
*
* 成员方法
* public void write(int c):写入单个字符
* public void write(char[] cbuf):写入字符数组
* public abstract void write(char[] cbuf,int off,int len) 写入字符数组的一部分
* public void write(String str):写入字符串内容
* public void write(String str,int off,int len):写入字符串一部分
*
*
* flush()和close()
* 一个刷新流:将缓冲的数据刷新出来(中文:默认gbk格式:一个中文对两个字节),流刷新之后还可以
* 继续写入数据;
* close()方法:将跟该流相关的系统资源释放掉,
* 不再指向当前操作的文件,关闭之后不能再写入数据否则出现IOException
*
* @author zhangyang
*
*/
public class OutputStreamWriterDemo {
public static void main(String[] args) throws IOException{
// public OutputStreamWriter(OutputStream out, Charset cs)
/*
OutputStreamWriter osw = new OutputStreamWriter
(new FileOutputStream("osw.txt"), "utf-8") ;//编码格式:utf-8
*/
//public OutputStreamWriter(OutputStream out)
OutputStreamWriter osw = new OutputStreamWriter
(new FileOutputStream("osw.txt"));
//写入数据
//public void write(int c)
//osw.write('a');
//osw.write('b');
// public void write(char[] cbuf):写入字符数组
char[] chs = {'我','爱','高','圆','圆'};
// osw.write(chs);
//public abstract void write(char[] cbuf,int off,int len)
//osw.write(chs, 1, 4);
// public void write(String str)
osw.write("今天老地方见");
//关闭之前:先去刷新流
osw.flush();
//释放资源
osw.close();
//osw.write('c');// Stream closed:流已经关闭
}
}
5.2)字符输入流
package com.qianfeng_reader_and_writer_02;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* InputStreamReader:字符输入流 (字符流通向字节流的桥梁)字符转换输入流
*
* 构造方法:
* public InputStreamReader(InputStream in):使用默认字符集进行解码(gbk格式)
* public InputStreamReader(InputStream in, String charsetName)
* 使用指定的字符集进行解码
*
* 成员方法:
* 读的功能
* public int read():读单个字符
* public int read(char[] cbuf):读字符数据
* public int read(char[] cbuf,int offset,int len)读字符数组的一部分
*
* @author zhangyang
*
*/
public class InputStreamReaderDemo {
public static void main(String[] args) throws IOException{
//创建字符转换输入流对象
/*InputStreamReader isr = new InputStreamReader(
new FileInputStream("osw.txt"), "utf-8") ;*/
InputStreamReader isr = new InputStreamReader(
new FileInputStream("osw.txt")) ;//默认gbk格式
//OutputStreamWriter:编码---gbk格式
//InputStreamReader:解码---utf-8格式
//将osw.txt文件内容展示在控制台上
//一次读取一个字符
//public int read():读单个字符
/*
int ch = 0 ;
while((ch=isr.read())!=-1) {
//展示在控制台上
System.out.print((char)ch);
}
*/
//一次读取一个字符数组
char[] chs = new char[1024] ;
int len = 0 ;//实际字符数
while((len=isr.read(chs))!=-1) {
System.out.println(new String(chs,0,len));
}
//关闭资源
isr.close();
}
}
5.3)字符流的读写复制操作
package com.qianfeng_reader_and_writer_02;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
/**
*
* 将当前项目OutputStreamWriterDemo.java文件---复制到D盘下Copy.java
*
* .txt/.java..... 使用记事本打开并能读懂,通常使用的字符流
*
* 分析:
* 1)封装源文件---->InputStreamReader
* 2)封装目的地文件---->D盘下 Copy.java OutputStreamWriter
* 3)读写操作
* 一次读取一个字符
* 一次读取一个字符数组
*
*
*
*
* @author zhangyang
*
*/
public class CopyFile {
public static void main(String[] args) throws IOException {
//1)封装源文件---->InputStreamReader
InputStreamReader isr = new InputStreamReader
(new FileInputStream("OutputStreamWriterDemo.java")) ;
// 2)封装目的地文件---->D盘下 Copy.java OutputStreamWriter
OutputStreamWriter osw = new OutputStreamWriter(
new FileOutputStream("D:\\Copy.java")) ;
//一次读取一个字符
int ch = 0 ;
while((ch=isr.read())!=-1) {
//写
osw.write(ch);
//刷新
osw.flush();
}
//一次读取一个字符数组(自己测试)
//关闭资源
osw.close();
isr.close();
}
}
5.4)字符流的读写复制操作(简化)
package com.qianfeng_reader_and_writer_02;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
/**
* 为了简化字符流读写复制操作:
*
* 提供了字符转换输入流和字符转换输出流的便捷类
* FileReader/FileWriter ---继承自InputStreamReader/OutputStreamWriter
* FileReader(String pathname)
* FileWriter(String pathname)
*/
public class FileReader_andFileWriter_Demo {
public static void main(String[] args) throws IOException {
//封装源文件:OutputStreamWriterDemo.java
FileReader fr = new FileReader("OutputStreamWriterDemo.java") ;
//封装目的文件:当前项目下:Demo.javas
FileWriter fw = new FileWriter("Demo.java") ;
//一次读取一个字符数组
char[] chs = new char[1024] ;
int len = 0 ;
while((len=fr.read(chs))!=-1) {
//写
fw.write(chs, 0, len);
//刷新
fw.flush();
}
//释放资源
fw.close();
fr.close();
}
}
6.字符缓冲流
6.1)字符缓冲输出流
package com.qianfeng_bufferedreader_bufferedwriter_03;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
/**
* BufferedWriter:字符缓冲输出流
* 将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入
* public BufferedWriter(Writer out):构造一个缓冲输出流,默认缓冲区大小
*
* 成员方法
* 特有功能
* public void newLine():写入行的分隔符(换行)
* @author zhangyang
*
*/
public class BufferedWriterDemo {
public static void main(String[] args) throws IOException {
//创建一个缓冲输出流对象
BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt")) ;
/**
* private static int defaultCharBufferSize = 8192;
* public BufferedWriter(Writer out) {
this(out, defaultCharBufferSize);
}
*/
//写数据:
bw.write("hello");
//bw.write("\r\n");
//特有功能
bw.newLine();
bw.write("world");
bw.newLine();
bw.write("Java");
bw.newLine();
//刷新
bw.flush();
//关闭资源
bw.close();
}
}
6.2)字符缓冲输入流
package com.qianfeng_bufferedreader_bufferedwriter_03;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
/**
* BufferedReader:字符缓冲输入流
* 构造方法
* BufferedReader(Reader r):构造一个字符缓冲输入流提供默认缓冲区大小
*
* 特有功能:
* public String readLine():一次读取一行内容,当读取到\n(换行了),就终止!
*
*
*Scanner(InputStream in)
*BufferedReader(Reader r):可以作为键盘录入(使用流的方式)
*
* @author zhangyang
*
*/
public class BufferedReaderDemo {
public static void main(String[] args) throws IOException {
//创建字符缓冲输入流对象
// BufferedReader br = new BufferedReader(new FileReader("bw.txt")) ;
BufferedReader br = new BufferedReader(new FileReader("OutputStreamWriterDemo.java")) ;
/**
* private static int defaultCharBufferSize = 8192;
* public BufferedReader(Reader in) {
this(in, defaultCharBufferSize);
}
*/
//public String readLine():
/*
//第一次读取
String line = br.readLine() ;
System.out.println(line);
//第二次读取
line = br.readLine() ;
System.out.println(line);
//第三次读取
line = br.readLine() ;
System.out.println(line);
//第四次读取
line =br.readLine() ;
System.out.println(line); //返回null:文件读取完毕了
*/
//优化:while循环
String line = null ;
while((line=br.readLine())!=null) {
//没有读完毕
System.out.println(line);
}
//释放资源
br.close();
}
}
6.3)键盘录入(使用流的方式)(readLine():依次读取一行数据)
package com.qianfeng_bufferedreader_bufferedwriter_03;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
/**
*
* 键盘录入:
*
* 1)Scanner(InputStream in)
* 2)BufferedReader(Reader r):可以作为键盘录入(使用流的方式)
* @author zhangyang
*
*/
public class Demo {
public static void main(String[] args) throws IOException {
/*
Scanner sc = new Scanner(System.in) ;
System.out.println("请您输入String数据:");
String str = sc.nextLine() ;
System.out.println(str);
*/
//使用BufferedReader(Reader r):可以作为键盘录入
/*
//分步走
InputStream in = System.in ;
//创建Reader流对象
Reader r = new InputStreamReader(in) ; //字符转换流:通向字节流的桥梁
//创建BufferedReader流对象
BufferedReader br = new BufferedReader(r) ;
*/
//一步走
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in)) ;
System.out.println("请您输入一个数据:"); //"100" 数字字符串
//利用BufferedReader:的readLine()读取一行数据
String line = br.readLine() ; //"100"
//String---int: Integer.parseInt(String str)
int num = Integer.parseInt(line) ;
System.out.println("您录入的字符串是:"+num);
}
}
6.4)使用BufferedReader/BufferedWriter:读写复制操作:文本文件复制
package com.qianfeng_bufferedreader_bufferedwriter_03;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
/**
* 使用BufferedReader/BufferedWriter:读写复制操作:文本文件复制
* 利用特有功能(一种新的方式)
*
* 项目下的Demo.java---复制到D盘下:a.java文件中
* 使用BufferedReader:字符缓冲输入流的readLine():一次读取一行
* 使用BufferedWriter:newLine()可以实现换行
*
* 总结针对文本文件的复制操作:
* InputStreamReader/OutputStreamWriter:一次读取一个字符
* InputStreamReader/OutputStreamWriter:一次读取一个字符数组
* (同上)
* FileReader/FileWriter一次读取一个字符
* FileReader/FileWriter一次读取一个字符数组
*
* BufferdReader/BufferedWriter:一次读取一个字符
* BufferdReader/BufferedWriter:一次读取一个字符数组
* BufferedReader/BufferedWriter:一次读取一行
*
*
*
*/
public class Test {
public static void main(String[] args) throws IOException {
//封装源文件
BufferedReader br = new BufferedReader(new FileReader("Demo.java")) ;
//封装目标文件
BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\a.java")) ;
//读写
String line = null ;
while((line=br.readLine())!=null) {
//读一行,bw写一行
bw.write(line);
bw.newLine();
bw.flush();
}
//释放资源
bw.close();
br.close();
}
}
7.字符打印流&&字节打印流
7.1)字符打印流
package com.qianfeng_other_stream_04;
import java.io.IOException;
import java.io.PrintWriter;
/**
* PrintWriter:字符打印流
* PrintStream:字节打印流
*
* 能够操作直接操作文件地址:String pathname的流有哪些?
* 最基本的字节流
* FileInputStream:字节输入流
* FileOutputStream:字节输出流
*
* FileReader:字符输入流
* FileWriter:字符输出流
*
* PrintWriter:够操作文件(目标文件) -- 字符输出流一种
*
* 构造方法:
* public PrintWriter(Writer out,boolean autoFlush):
* 第二个参数为true:表示开启自动刷新功能
* public PrintWriter(String fileName):可以操作具体文件路径
* 成员方法:
* public void println(XXX x):可以换行
*
* @author zhangyang
*
*/
public class PrintWriterDemo {
public static void main(String[] args) throws IOException {
//创建字符打印流对象
PrintWriter pw = new PrintWriter("pw.txt") ;
//打印数据并可以换行
pw.println("hello");
pw.println("world");
pw.println("java");
//刷新
pw.flush();
//关闭资源
pw.close();
}
}
7.2)文本文件的复制
package com.qianfeng_other_stream_04;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
/**
* 文本文件的复制----优先采用BufferedReader/BufferedWriter
* 图片文件/音频文件/视频文件----采用BufferdInputStrea/BufferedOutputStream
*
* 文本文件的复制
* 当前项目下:BufferedInputStreamDemo.java
* 复制当前项目下:Test.java
*
* 封装源文件:BufferedReader
* 封装目标文件:PrintWriter
*
* @author zhangyang
*
*/
public class CopyFile {
public static void main(String[] args) throws IOException {
//封装源文件
BufferedReader br = new BufferedReader
(new FileReader("BufferedInputStreamDemo.java")) ;
//封装目的地文件
//public PrintWriter(Writer out, boolean autoFlush)
PrintWriter pw = new PrintWriter(new FileWriter("Test.java"),
true) ;//启动自动刷新
//复制
String line = null ;
while((line=br.readLine())!=null) {
//打印数据
pw.println(line);
}
//释放资源
pw.close();
br.close();
}
}
7.3)字符/字节打印流
package com.qianfeng_other_stream_04;
import java.io.IOException;
import java.io.PrintWriter;
/**
* PrintWriter:字符打印流
* PrintStream:字节打印流
*
* 能够操作直接操作文件地址:String pathname的流有哪些?
* 最基本的字节流
* FileInputStream
* FileOutputStream
*
* FileReader
* FileWriter
*
* PrintWriter:能够操作文件(目标文件) -- 字符输出流一种
*
* 构造方法:
* public PrintWriter(Writer out,boolean autoFlush):
* 第二个参数为true:表示开启自动刷新功能
* public PrintWriter(String fileName):可以操作具体文件路径
* 成员方法:
* public void println(XXX x):可以换行
*
* @author zhangyang
*
*/
public class PrintWriterDemo {
public static void main(String[] args) throws IOException {
//创建字符打印流对象
PrintWriter pw = new PrintWriter("pw.txt") ;
//打印数据并可以换行
pw.println("hello");
pw.println("world");
pw.println("java");
//刷新
pw.flush();
//关闭资源
pw.close();
}
}
8.内存操作流
package com.qianfeng_other_stream_04;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
/**
* 内存操作流:操作临时数据
* ByteArrayOutputStream:内存操作输出流
* 构造方法:
* public ByteArrayOutputStream(){}:构造一个默认的缓冲大小的输出流对象
* 成员方法
* public byte[] toByteArray():将内存操作输出流中流对象---数组格式
*
* ByteArrayInputStream:内存操作输入流
* 构造方法:
* public ByteArrayInputStream(byte[] buf):使用指定的字节数组作为缓冲区,构造
* 内存操作输入流
*
* @author zhangyang
*
*/
public class ByteArrayStreamDemo {
private static
ByteArrayOutputStream baos = new ByteArrayOutputStream() ;
public static void main(String[] args) throws IOException {
write(baos) ;
read() ;
}
//将内存操作流
private static void read() throws IOException {
//public ByteArrayInputStream(byte[] buf)
//public byte[] toByteArray()
byte[] bytes = baos.toByteArray() ;
ByteArrayInputStream bais = new ByteArrayInputStream(bytes) ;
//读取数据
//一次读取一个字节/一个字节数组
int by = 0 ;
while((by=bais.read())!=-1) {
//展示
System.out.print((char)by);
}
/**
* public void close() throws IOException {
}
* */
//bais.close();
}
//创建内存操作输出流,写入临时数据
private static void write(ByteArrayOutputStream baos) throws IOException {
//创建ByteArrayOutputStream
//写入数据
for(int x = 0 ; x < 10 ; x ++) {
baos.write(("hello"+x).getBytes());
//字节流换行
//写入\r\n
baos.write("\r\n".getBytes());
}
//System.out.println(baos);
//关闭资源
// baos.close();临时变量---随着方法完毕就消失了
/**
* close没有作任何实现
* public void close() throws IOException {
}
*/
}
}
9.合并流
9.1)将两个流对象合并到一个流中
package com.qianfeng_other_stream_04;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;
/**
* SequenceInputStream extends InputStream:字节输入流
* 合并流:将两个或者两个以上的流对象合并到一个流中
*
*构造方法
*将两个基本输入流合并到当前SequenceInputStream流中
* public SequenceInputStream(InputStream s1,InputStream s2)
* 之前:
* c:\\a.txt----D:\\b.txt
*
* 现在::c:\\a.txt
* c:\\c.txt
*
* 复制到 d:\\b.txt
* 当前项目下的
* Demo.java
OutputStreamWriterDemo.java
*
* 复制到当前项目下的:Copy.java文件中
* @author zhangyang
*
*/
public class SequenceStramDemo {
public static void main(String[] args) throws IOException{
InputStream s1 = new FileInputStream("Demo.java") ;
InputStream s2 = new FileInputStream("OutputStreamWriterDemo.java") ;
//创建合并流对象
SequenceInputStream sis = new SequenceInputStream(s1, s2) ;
//封装目标文件
FileOutputStream fos = new FileOutputStream("Copy.java") ;
//读写复制
// 一次读取一个字节数组
byte[] bytes = new byte[1024] ;
int len = 0 ;
while((len=sis.read(bytes))!=-1) {
fos.write(bytes,0,len);
}
//关闭资源
fos.close();
sis.close();
}
}
9.2)两个以上的文件复制(Vectory集合)
package com.qianfeng_other_stream_04;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;
import java.util.Enumeration;
import java.util.Vector;
/*
public SequenceInputStream(Enumeration<? extends InputStream> e)
* 两个以上的文件复制
*
* 1)创建 Vector<InputStream>集合对象
* 2)给添加多个InputStream对象
* 3)Vector集合中:elements()---->Enumeration<InputStream>
* 4)读写复制
*
*
*
* 需求:
* 将OutputStreamWriterDemo.java/Test.java/CopyFile.java
*
* 三个文件复制到D:\\CopyFileDemo.java
*
*
**/
public class SequenceStreamDemo2 {
public static void main(String[] args) throws IOException{
//public SequenceInputStream(Enumeration<? extends InputStream> e)
//创建Vector集合对象
Vector<InputStream> v = new Vector<InputStream>() ;
//创建三个InputStream对象
InputStream s1 = new FileInputStream("OutputStreamWriterDemo.java") ;
InputStream s2 = new FileInputStream("Test.java") ;
InputStream s3 = new FileInputStream("Copy.java") ;
//添加到集合中
v.add(s1) ;
v.add(s2) ;
v.add(s3) ;
//获取类似于迭代器elements()-----iterator()
Enumeration<InputStream> en = v.elements() ;
//创建合并流对象
SequenceInputStream sis = new SequenceInputStream(en) ;
//封装目标文件
FileOutputStream fos = new FileOutputStream("d:\\CopyFileDemo.java") ;
//一次读取一个字节数组
byte[] bytes = new byte[1024] ;
int len = 0 ;
while((len=sis.read(bytes))!=-1){
//写
fos.write(bytes, 0, len);
}
//关闭
fos.close();
sis.close();
}
}
8.序列化和反序列化
package com.qianfeng_other_stream_05;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
*
* ObjectOutputStream
* public ObjectOutputStream(OutputStream out)
* 序列化:需要将网络中的数据/一些对象转成 "流数据"
* 成员方法:
* public final void writeObject(Object obj):将指定的对象写入到序列化流中
*
* ObjectInputStream
* public ObjectInputStream(InputStream in)
*
* 反序列化:将流数据----还原成Java对象/网络数据
* public final Object readObject():将流数据---还原成对象
*
*
* @author zhangyang
*
*/
public class ObjectStreamDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//序列化
// write() ;
//反序列化
read() ;
}
//将流数据---还原成对象
private static void read() throws IOException, ClassNotFoundException {
//public ObjectInputStream(InputStream in)
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("oos.txt")) ;
//* public final Object readObject()
Object obj = ois.readObject() ;
System.out.println(obj);
//关闭
ois.close();
}
private static void write() throws IOException, IOException {
//public ObjectOutputStream(OutputStream out)
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("oos.txt")) ;
//写数据
Person p = new Person("张钰",23) ;
//public final void writeObject(Object obj)
oos.writeObject(p);
//释放资源
oos.close();
}
}
package com.qianfeng_other_stream_05;
import java.io.Serializable;
import java.lang.annotation.Target;
//java.io.NotSerializableException: com.qianfeng_other_stream_05.Person
//只有实现接口:Serializable接口的类:才能进行序列化
/**
* 序列化接口-----没有字段,连成员方法都没有----标记接口
* 序列化的类----内存中进行编码:内容包含:类---类产生的字节码文件Person.class 类签名:序列化版本ID
* 类的成员:
* 字段(属性)值
*
*
* 改动了当前类的一个成员:
* 直接进行反序列化就出现了一个异常:
* java.io.InvalidClassException: com.qianfeng_other_stream_05.Person;
* local class incompatible: stream classdesc serialVersionUID = 6374026048563988155,
* local class serialVersionUID = 7013884605889541932
*
* 类似于:每一个类在内存中进行序列化的时候,会产生xxx.class文件产生一个
* serialVersionUID:序列化版本ID = 100
*
* 反序列化的时候:将类的成员信息改动了----产生一个新的serialVersionUID = 200
* 前后类的签名不一致,就会出现异常!
* 当前某个成员:transient:不会参与序列化和反序列化
*
* 让当前这个类在序列化和反序列化的时候:产生的版本ID是一个固定值
* 在类上有黄色警告线---点击--- 产生一个固定的版本Id值即可!
*
* @author zhangyang
*
*/
public class Person implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private String name ;
//private int age ;
transient int age ; //让某一个变量不会参与序列化
public Person() {
super();
// TODO Auto-generated constructor stub
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
9.Properties类
9.1)Map集合的遍历
package com.qianfeng_other_stream_06;
import java.util.Properties;
import java.util.Set;
/**
* Properties 类表示了一个持久的属性集 ,没有泛型(属性列表中的键和值都是String)
* 它继承自Hashtable<K,V> implements Map<K,V>
*
* Map集合的遍历:
* 通用的方式
* keySet()---->Set<K>
* get(K key)---->V value
*
* @author zhangyang
*
*/
public class PropertiesDemo {
public static void main(String[] args) {
//Properties属性集合类中的基本遍历功能
//创建属性集合类对象
Properties prop = new Properties() ;
//添加数据
prop.put("it001", "马云") ;
prop.put("it002", "刘强东") ;
prop.put("it003", "罗永浩") ;
prop.put("it004", "张冲") ;
prop.put("it001", "张冲2") ;
//遍历
Set<Object> set = prop.keySet() ;
for(Object obj :set) {
//在通过键获取值
Object value = prop.get(obj) ;
System.out.println(obj+"---"+value);
}
}
}
9.2)特有功能
package com.qianfeng_other_stream_06;
import java.util.Properties;
import java.util.Set;
/**
* Properites属性集合类的特有功能
* public Object setProperty(String key, String value):添加键和值
* public Set<String> stringPropertyNames():获取属性列表中的所有的键的集合
* public String getProperty(String key):通过键获取值
*
* public void load(Reader reader):将一些配置文件中的数据加载到属性集合类中
*
* public void store(Writer writer, String comments)
* 将属性集合类中数据保存到指定的文件中
* @author zhangyang
*
*/
public class PropertiesDemo2 {
public static void main(String[] args) {
//创建属性集合类对象
Properties prop = new Properties() ;
//* public Object setProperty(String key, String value):添加键和值
prop.setProperty("杨玉环", "27") ;
prop.setProperty("西施", "25") ;
prop.setProperty("王昭君", "22") ;
prop.setProperty("貂蝉", "20") ;
System.out.println(prop);
//获取所有的键的集合
//public Set<String> stringPropertyNames()
Set<String> set = prop.stringPropertyNames() ;
for(String key:set) {
//public String getProperty(String key)
Object value = prop.get(key) ;
System.out.println(key+"---"+value);
}
}
}
9.3)将一些配置文件中的数据加载到属性集合类中
package com.qianfeng_other_stream_06;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.util.Properties;
/**
* public void load(Reader reader):将一些配置文件中的数据加载到属性集合类中
*
* public void store(Writer writer, String comments)
* 将属性集合类中数据保存到指定的文件中
*
*
*需求:
* 在当前项目下user.txt文件 ,如果当前文件中lisi这个键,将它的值改为
* 78,然后重新将值写入到user.txt文件(既要用到load(Reader r),
* 还要用到store(Writer w,String comments))
*
*
* @author zhangyang
*
*/
public class PropertiesTest {
public static void main(String[] args) throws IOException {
// myStore() ;
myLoad() ;
}
//将某个文件中的内容加载到属性集合列表中
private static void myLoad() throws IOException {
//创建属性集合类对象
Properties prop = new Properties() ;
Reader r = new FileReader("user.txt") ;
prop.load(r);
//关闭资源
r.close();
System.out.println(prop);
}
//需要将属性列表中的数据保存到某个文件:当前项目下的name.txt中
private static void myStore() throws IOException {
//创建属性集合类对象
Properties prop = new Properties() ;
//添加数据
prop.setProperty("张三", "30") ;
prop.setProperty("李四", "40") ;
prop.setProperty("王五", "50") ;
//public void store(Writer writer, String comments)
prop.store(new FileWriter("names.txt"), "name's list");
System.out.println(prop);
}
}