一、字节流
a.可以用来操作文本,还可以操作图片,音频等
例题:使用字节的输出输入流进行文件的复制
public class Demo{
public static void main(String [] args){
//这里获取系统时间,来进行执行效率
long start = System.currentTimeMillis();
//读取文件内容
FileInputStream fis = null;
//向文件中写入内容
FileOutputStream fos = null;
try{
//这里我们进行路径的传入
//传入程序要读取的文件路径
fis = new FileInputStream("/Users/lanou/Desktop/Test 2/1.jpg")
//这里传入的是程序向哪个文件路径写入
fos = new FileOutputStream("/Users/lanou/Desktop/Test 2/111.jpg");
//方法1.使用read();这个读取的方法是每次只读取一个数据字节
int len = 0;
while((len = fos.read())!= -1){
//这里我们读取了一个字节(我们所读取的字节都是ASCII码的形式,也就是int形式),就将该字节在写入到,我们定义的输出路径文件下
fos.write(len);
}
//方法2.使用字节数组的方法读写
//read(byte[]b) 从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。
byte [] b = new byte [1024];
int len = 0;
while((len = fis.read(b))!=-1){
fos.write(b,0,len);
}
}catch (FileNotFoundException e) {
throw new RuntimeException("文件找不到");
} catch (IOException e) {
throw new RuntimeException("文件复制失败");
}
finally {
//这是读入和写入,都完事了,先关闭哪个都行
try {
if (fis != null) {
fis.close();
}
} catch (IOException e) {
throw new RuntimeException("关闭资源失败");
}
finally {
//写一起,如果第一个报了异常,第二个流,会无法关闭
try {
if (fos != null) {
fos.close();
}
} catch (IOException e) {
throw new RuntimeException("关闭资源失败");
}
}
}
//获取结束的时间
long end = System.currentTimeMillis();
System.out.println(end-start);
}
}
例题2.
将一个文件夹复制到另一个文件夹
public class Demo02 {
public static void main(String[] args) throws IOException {
// 测试
File src = new File("/Users/lanou/Desktop/tes");
File dest = new File("/Users/lanou/Desktop/xtes");
copyDir(src, dest);
}
public static void copyDir(File src,File dest)throws IOException{
File newDir = new File (dest,src.getName());
newDir.mkdir();
}
//复制文件夹方法-a:src原文件(要被复制的文件)b:dest 目标文件夹(要把原文件夹复制进去)
public static void copyDir(File src,File dest) throws IOException{
//在目标文件夹下创建新的文件夹,名字和原文件夹一样
//这里我们创建一个文件对象实例,以dest为根目录路径,src.getName()为子路径
File newDir = new File(dest,src.getName());
newDir.mkdir();
//复制文件过程:a.找到文件 b.边读边写 c.找到文件夹 d.继续调用本方法
//遍历文件夹
File[] listFiles = src.listFiles();
for(File subFile : listFiles){
//判断是否是文件,是就进行读写
if(subFile.isFile()){
FileInputStream fis = new FileInputStream(subFils);
//新建所遍历的文件的最终文件对象实例,用于传入输出流参数中,作为写入文件内容的路径地址
File tempFile = new File (newDir,subFile.getName);
//输出写入文件中
FileOutStream fos = new FileOutputStream(temFile);
int len = 0;
byte [] b = new byte [1024];
while((len = fis.read(b))!=-1){
fos.write(new String(b,0,len));
}
fis.close;
fos.close;
}else{
//是文件夹,就继续执行方法,遍历
copyDir(subFile,newDir);
}
}
}
二、字符流
字节的输出流的write('a');直接写入字符的方法,里面传入的是ASCALL码,而字符的输出流里面有,write(String name);直接传入一个字符串,写入到文件里面
注:字符流只能用来操作文本,不能用来操作图片音频等
a.Writer:是所有字符输出流的父类--抽象类
b.FileWriter 用来向文件中写字符类
c.FileWriter(String fileName);参数是,路径的字符地址,写在哪个文件里的路径--一个一个字符的写入
d.一个中文:
1)Mac系统是3个字节,默认使用UTF-8编码表
2)Windows是2个字节,默认使用GBK编码表
e.例题1
public class Demo04 {
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("/Users/lanou/Desktop/Test 3/haha.txt");
fw.write(100);
//字符输出流,在写入的时候,需要调用刷新方法
//建议,每次写完,就要刷新一次
fw.flush();
//关闭资源前,会刷新
//使用字符数组写
char [] c = {'d','p','y','g','h'};
fw.write(c);
fw.flush();
fw.write(c, 1, 3);
fw.flush();
//使用字符串直接写进
fw.write("床前明月光 \n 大家解答\n");
fw.flush();
fw.write("白日依山尽", 1, 2);
fw.flush();
fw.close();
}
}
三、转换流
1.OutputStreamWriter--字符流转向字节流
作用:可以根据不同编码格式写入
需要使用:FileOuteStream 输出流
2.InputStreamWriter--字节流转向字符流
作用:可以读取不同编码格式的文件
需要使用:FileInputStream 输入流
public class Demo07 {
public static void main(String[] args) throws IOException {
getUTF8();
getGBK();
readerUTF8();
readerGBK();
}
//以UTF-8读取
public static void readerUTF8() throws IOException {
InputStream fis = new FileInputStream("/Users/lanou/Desktop/Test 2/utf8.txt");
InputStreamReader isr = new InputStreamReader(fis);
char [] cs = new char[1024];
int len = 0;
while((len = isr.read(cs))!=-1) {
System.out.println(new String(cs, 0, len));
}
}
public static void readerGBK() throws IOException {
InputStream fis = new FileInputStream("/Users/lanou/Desktop/Test 2/gbk.txt");
InputStreamReader isr = new InputStreamReader(fis,"gbk");
char [] cs = new char[1024];
int len = 0;
while((len = isr.read(cs))!=-1) {
System.out.println(new String(cs, 0, len));
}
}
//利用转换流,写文件 OutP
public static void getUTF8() throws IOException {
//字符流转向字节流
FileOutputStream fos = null;
FileInputStream fis = null;
fos = new FileOutputStream("/Users/lanou/Desktop/Test 2/utf8.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos);
//写文件
osw.write("丁鹏");
//只关闭外层的流就行了
osw.close();
}
//利用转换流使用GBK写入文件
public static void getGBK() throws IOException {
FileOutputStream fos = new FileOutputStream("/Users/lanou/Desktop/Test 2/gbk.txt");
//构建转换流,传入编码格式 (编码格式忽略大小写)
OutputStreamWriter osw = new OutputStreamWriter(fos, "GBK");
osw.write("丁鹏");
osw.close();
}
}
一、BufferedOutputStream(缓冲输出字节流)和BufferedInputStream(缓冲输入字节流)
1.构造方法:
BufferedOutputStream(OutputStream out)
参数:字节输出流的父类FileOutputStream,就是想对哪个输出流高效,就把该这字节输出流当做参数传进去
2.例题
public class Demo01 {
public static void main(String[] args) throws IOException {
//fun1();
FileInputStream fis = new FileInputStream("/Users/lanou/Desktop/tes/ppp.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
int len = 0;
byte [] bs = new byte [1024];
while((len = bis.read(bs))!=-1) {
System.out.println(new String(bs));
}
bis.close();
}
public static void fun1() throws FileNotFoundException, IOException {
FileOutputStream fos = new FileOutputStream("/Users/lanou/Desktop/tes/ppp.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
bos.write("HelloWorld".getBytes());
bos.flush();
bos.close();
}
}
例题2:测试高效率重复文件的快慢
public class Demo02 {
public static void main(String[] args) throws IOException {
MyCopy1 myCopy1 = new MyCopy1();
myCopy1.printTime();
System.out.println("------");
MyCopy2 myCopy2 = new MyCopy2();
myCopy2.printTime();
}
}
//14742
abstract class TestTime {
//原文件
public String src ="/Users/lanou/Desktop/tes/dp.png";
//目的文件
public String dest ="/Users/lanou/Desktop/tes/dp1.png";
public void printTime() throws IOException {
long start = System.currentTimeMillis();
//调用方法
copyFile();
long end = System.currentTimeMillis();
System.out.println(end - start);
}
//复制文件的方法,子类要抛出异常,父类也要抛出异常
public abstract void copyFile() throws IOException;
}
//实现类
class MyCopy1 extends TestTime{
//字节输出流,单个字节形式,复制文件
//数组形式,复制文件
//缓冲流输出流,当个字节形式,复制文件
//数组形式,复制文件
@Override
public void copyFile() throws IOException {
FileOutputStream fos = new FileOutputStream(dest);
FileInputStream fis = new FileInputStream(src);
//单个字节,复制文件
int len = 0;
byte [] bs = new byte [1024];
while((len = fis.read(bs)) !=-1) {
fos.write(len);
}
}
}
//217
class MyCopy2 extends TestTime{
@Override
public void copyFile() throws IOException {
FileOutputStream fos = new FileOutputStream(dest);
FileInputStream fis = new FileInputStream(src);
//缓冲流的,单个字节复制
BufferedOutputStream bos = new BufferedOutputStream(fos);
BufferedInputStream bis = new BufferedInputStream(fis);
int len = 0;
byte [] bs = new byte [1024];
while((len = bis.read(bs))!= -1) {
bos.write(len);
}
}
}
二、BufferedWriter(缓冲字符输出流)和BufferedReader(缓冲字符输入流)
1.构造方法
参数Writer--父类,可以传入FileWriter和OutputStreamWriter
2.特有方法:
newLine();无关平台性的
3.例题:
public class Demo03 {
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("/Users/lanou/Desktop/tes/ppp.txt");
BufferedWriter bw = new BufferedWriter(fw);
bw.write("哪个蓝月好看吗");
bw.newLine();
bw.flush();
bw.write("大搞好,我洗渣渣会");
bw.flush();
bw.close();
}
}
例题2:
public class Demo04 {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("/Users/lanou/Desktop/tes/ppp.txt");
BufferedReader br = new BufferedReader(fr);
//读取按行读,是不能把换行读出来的
//要跟原文本一样,需要自己加上换行来打印
String string ="";
while((string = br.readLine())!=null) {
System.out.println(string);
}
br.close();
}
}
例题3:文件复制
public class Demo05 {
public static void main(String[] args) throws IOException {
copy();
}
public static void copy() throws IOException {
FileReader fr = new FileReader("/Users/lanou/Desktop/tes/ppp.txt");
FileWriter fw = new FileWriter("/Users/lanou/Desktop/tes/ppp1.txt");
//
BufferedReader br = new BufferedReader(fr);
BufferedWriter bw = new BufferedWriter(fw);
String string = "";
//读不出来,需要自己加
while((string = br.readLine())!=null) {
bw.write(string);
bw.newLine();
bw.flush();
}
br.close();
bw.close();
}
}
三、流程总结
流总结:
1.明确要做什么操作,
a.数据源
InputStream,Read 写到数据目的地
OutputStream,Writer
2.明确要操作的是什么内容
文本,音频,图片等。---使用字节流
文本--字符流(按什么编码格式书写)
3.明确你的流,要在什么设备上运用
文本 网络,聊天进行了流的交换
4是否需要提高效率
缓冲流 Buffered
四、双列集合
1.Properties集合(双列集合)父类是Hashtable
2.作用:Properties是集合中唯一能和IO流配合的类
3.读取和写入时,传入的参数是字符流可以,字节流也可以
4.例题1
public static void fun1(){
Properties properties = new Properties();
System.out.println(properties);
Set<String> set = properties.stringPropertyNames();
for(String key :set){
String value = properties.getProperty(key);
System.out.println(key+"="+value);
}
}
例题2
public static void fun2() throws FileNotFountException,IOException{
Properties properties = new Properties();
FileReader fr = new FileReader("/Users/"
+ "lanou/Desktop/tes/pp.properties");
properties.load(fr);
System.out.println(properties);
fr.close();
}
五、序列化
1.序列化流与反序列化流
a.广义:压缩和解压缩
b.序列化:把对象写进文件中
ObjectOutputStream类----序列化流
反序列化:把对象从文件中给读出来
ObjectInputStream类 ----反序列化流
注意:静态的成员变量是不能进行序列化的,因为序列化的是对象,静态的成员变量时属于类的
2.例题
public class Demo{
public static void main(String [] args)throws IOException,ClassNotFoundException{
//进行序列化,向文件里写入
writeObject
//进行反序列化,读取出来
}
public static void writeObject() throws IOException{
//注:我们如果要将我们所定义的对象作为参数,必须实现Seralizable接口--序列化接口。这个接口是--标记型接口(就是可以实现序列化的标识,没有就无法实现序列化)
//我们如果写对象,都是用字节流类来实现
FileOutputStream fos = new FileOutputStream("/Users/lanou/Desktop/tes/person.txt");
//对象输出流
ObjectOutputStream oos = new ObjectOutputStream(fos);
//写入方法
oos.writeObject(new Person("dp",15));
oos.close();
}
public static void readObject() throws FileNotFoundException, IOException, ClassNotFoundException {
//读取序列化文件-反序列化
//在进行反序列化(读取)的时候,需要依赖你的编译文件.class文件,来进行读取的
FileInputStream fis = new FileInputStream("/Users/lanou/Desktop/tes/person.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
Object object = ois.readObject();
System.out.println(object);
ois.close();
}
}