IO流学习

1.文件

1.1文件相关的基本概念

  • 什么是文件?(文件是放在磁盘上面的)
  • 文件是保存数据的地方,可以是声音可以是视频和图片
  • 文件流是什么?
  • 文件在程序中以流的形式进行操作
  • 输出流的定义?
  • 从java内存到文件磁盘上面我们定义为输出流
  • 输入流的定义
  • 从文件磁盘到java程序内存当中,我们将其叫做输入流

1.2常用的文件操作(创建文件)

  • new File(String pathname)//根据路径构建一个File对象
  • new File(File parent,String child)//根据父目录文件+子路径构建
  • new File(String parent,String child)//根据父目录+子路径构建
  • 代码实现
    创建文件的基本操作
    注意File file = new File(路径);//只是在java当中创建了一个对象,只有执行了create才是在磁盘上面进行操作
package com.lk.File0822;
import java.io.File;
import java.io.IOException;
public class FileCreate {
	public static void main(String[] args) {
		FileCreate fc1 = new FileCreate();
		fc1.create01();
		fc1.create02();
	}
	public void create01() 
	{
		String filePath = "G:\\news1.txt";
		File file = new File(filePath);
		try {
			file.createNewFile();
			System.out.println("文件创建成功");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	//方式2 :new File(File parent,String child)
	//G:\\news2.txt
	public void create02() 
	{
		File parentfile = new File("G:\\");
		String fileName = "news2.txt";
		//这个动作,创建了一个File了以后只是相当于在内存里面创建了一个File对象,只有file.createFile()以后才能在硬盘当中显示出来
		//这个只是一个java对象而已,只有执行了createNewFile方法,才会真正在磁盘创建文件
		File file = new File(parentfile,fileName);
		try {
			file.createNewFile();
			System.out.println("文件创建成功");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public void create03() 
	{
		String parentPath = "e:\\";
		String fileName = "news3.txt";
		File file = new File(parentPath,fileName);
		
		try {
			file.createNewFile();
			System.out.println("文件创建成功");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
}

1.3常用的文件操作(获取文件的信息)

package com.lk.File0822;

import java.io.File;

public class FileInformation {
	public static void main(String[] args) {
		FileInformation fif = new FileInformation();
		fif.info();
	}
	//获取文件的信息
	public void info() 
	{
		//先闯进文件对象
		File file = new File("G:news1.txt");
		//调用对应的方法,得到对应的信息
		System.out.println("文件名字="+file.getName());
		System.out.println("文件的绝对路径"+file.getAbsolutePath());
		System.out.println("文件的父级目录"+file.getParent());
		System.out.println("文件大小(字节)"+file.length());
		//一个英文字符一个字节
		//一个汉字三个字节
		//文件是否存在
		System.out.println("文件是否存在"+file.exists());//T
		System.out.println("是不是一个文件"+file.isFile());//T
		System.out.println("是不是一个目录"+file.isDirectory());//F
		
	}
}

在这里插入图片描述

1.4目录的操作和文件删除

这里需要注意 mkdir只能创建一级目录,mkdirs可以创建主目录下面的多级目录

package com.lk.File0822;

import java.io.File;

public class Directory {
	public static void main(String[] args) {
		Directory dit = new Directory();
		dit.m1();
		dit.m2();
		dit.m3();
	}
	//判断 d:\\news1.txt是否存在,如果存在就删除
	public void m1() 
	{
		String filePath = "G:\\news1.txt";
		File file = new File(filePath);
		if(file.exists()) 
		{
			if(file.delete()) 
			{
				System.out.println("删除成功");
			}else 
			{
				System.out.println("删除失败");
			}
		}else {
			System.out.println("文件不存在");
		}
	}
	//在java当中目录也是被当做是文件对待的
	public void m2() 
	{
		String filePath = "G:\\demo2";
		File file = new File(filePath);
		if(file.exists()) 
		{
			if(file.delete()) 
			{
				System.out.println("删除成功");
			}else 
			{
				System.out.println("删除失败");
			}
		}else {
			System.out.println("该目录不存在");
		}
	}
	//第三个要求 判断G:\\demo\\a\\b\\c 目录是否存在,如果存在就提示已经存在,如果不存在就创建
	public void m3() 
	{
		String directoryPath = "G:\\demo2\\a\\b\\c";
		File file = new File(directoryPath);
		if(file.exists()) 
		{
			System.out.println(directoryPath+"存在..");
		}else {
			if(file.mkdirs()) //创建多级目录,必须使用mkdirs的方法,如果只是创建一级目录 file.mkdir()则是正确的
			{
				System.out.println("创建成功");
			}else {
				System.out.println("创建失败");}
			}
	}
}

2.IO流

2.1IO流的原理以及分类

IO流用于数据处理,网络通信等等
流的分类

  • 按照操作数据的单位分为:字节流(8bit),字符流(按照字符为单位来操作)字符流的效率更高(文本文件用字符流最好),字节流的好处(二进制文件操作的时候是无损的操作,不会对文件造成太大的损失)

  • 按照数据的流向分为:输出流和输入流

  • 按照流的角色分为:节点流,处理流(包装流)
    字节流的输入流:InputStream 顶级父类 输出流:OutputStream
    字符流的输入流:Reader 字节流的输出流:Writer
    InputStream,OutputStream这两个类是抽象类
    Reader,Writer也是抽象类 由四个父类衍生出来的都是以父类作为的后缀

  • 注意流和文件的关系的解释?

  • 流是承载运输文件的工具(可以将文件看成物品,外卖小哥看成流,用户看成人)

2.2InputStream字节输入流的常见子类使用以及其用法

FileInputStream
ObjectInputStream
BufferedInputStream
FilterInputStream

  • FileInputStream
    .read()函数是当读到文件最后的下面一位的时候返回-1
    (readlen = file.read(buf)))!= -1 将读取的字节放在字节数组当中,返回的是读取的个数,当读到末尾没法在读取的时候返回-1
package com.lk.FileInputStream;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
//debug的方式,走eclipse的方法
//字节输入流  文件-》程序当中
public class FileInputStreamtext {
	public static void main(String[] args) {
		FileInputStreamtext fist = new FileInputStreamtext();
		// fist.readFile01();
		
		fist.readFile02();
	}
	// 读取文件的操作
	public void readFile01() {
		String filepath = "G:\\hello.txt";
		FileInputStream file = null;
		int readData = 0; 
		try {
			// 创建FileInputStream对象 ,用于读取文件
			file = new FileInputStream(filepath);
			while ((readData = file.read()) != -1) // .read()函数是当读到文件最后的下面一位的时候返回-1
			{ // 汉字是三个字节组成的,当你的文件里面是汉字的时候,每次读一个字节,就将其转换为char当执行的时候就会看到乱码的现象
				// 因此如果读取文本文件的话最好用字符流
				System.out.print((char) readData);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			// 关闭文件流释放资源
			try {
				file.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
	}

	public void readFile02() {
		String filepath = "G:\\hello.txt";
		FileInputStream file = null;
		int readData = 0;
		byte[] buf = new byte[8];// 一次读取八个字节,一个字符是一个字节
		int readlen = 0;
		try {
			file = new FileInputStream(filepath);
			// file,读取正常的话返回的是实际读取的字节数目
			// 如果不够8个就返回时间的个数
			while ((readlen = file.read(buf)) != -1) {
				System.out.println(new String(buf, 0, readlen));

			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			try {
				file.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}

2.3FileOutputStream文件字节输出流的使用以及方法

  • FileOutputStream
    //这里需要注意几个地方
    //fos = new FileOutputStream(file, true);当有true的时候,代表向文件的末尾进行添加
    //当创建输出流的时候,没有true的时候,代表覆盖文件写入的操作
  •   	//写入一个字节
      	//fos.write('a');//char->自动装换为int
      	写入有三种方法,第一个是直接写入一个字节
      	fos.write(str.getBytes());将字符串转换为字节数组写入文件当中
      	fos.write(str.getBytes(),0,str.length());将字节数组,从下标多少写入多少的数据
    
package com.lk.FileInputStream;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

//debug的方式运行一下循环
//要求在a.txt文件当中写入,hello,world。如果文件不存在的话会重新的创建这个文件
public class FileOutputStreamtext { 
	public static void main(String[] args) {
		FileOutputStreamtext text = new FileOutputStreamtext();
		text.writeFile();//如果没有该文件的话会自动创建文件
	}
	public void writeFile() {
		//创建FileOutputStream
		FileOutputStream fos = null;
		File file = new File("G:\\a.txt");
		
		try {
			fos = new FileOutputStream(file, true);//true代表的是不覆盖,如果没有true的话代表的是覆盖写入
			//写入一个字节
			//fos.write('a');//char->自动装换为int
			//说明细节:
			//1.new FileOutputStream(filepath)创建的方式的覆盖式的覆盖方式
			String str = "lk,wrold";
			//str.getBytes可以将字符串转换成为字节数组
			//fos.write(str.getBytes());//这个是覆盖写入
			fos.write(str.getBytes(),1,1);//从字节数组的索引1,写一个字节进去
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			try {
				fos.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
	}
}

2.4文件拷贝的操作

将一个地方的文件(图片),拷贝到另一个路径下面的操作
注意: os.write(buf)这样吧写入的话,写入可能造成文件损失,因为这里是将数组全部写入,如果当我们读取到最后的时候1024个位置,只有五百多个读取到数据了,剩下的在写入图片的话容易造成图片的乱码

package com.lk.FileInputStream;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileCopy {
	//首先利用java程序从某个路径读取文件
	//然后再把读取到的文件数据在输入到某个位置即可
	//在完成程序时,应该是读取部分数据就写入到指定的文件,使用循环的操作
	public static void main(String[] args) {
		FileCopy fc = new FileCopy();
		fc.copy();
	}
	public void copy() {
		FileInputStream is = null;
		FileOutputStream os = null;
		String pathsource = "G:\\1.jpg";//c盘的目录下面容易错误是因为需要管理员的权限
		String pathaim = "G:\\IO流\\2.jpg";
		
		try {
			is = new FileInputStream(pathsource);
			os = new FileOutputStream(pathaim);
			//定义一个字节数组提高读取的效率
			byte[] buf = new byte[1024];
			int readlen = 0;
			while((readlen=is.read(buf))!=-1){
				//读取到后就写入到文件当中,不要一次性读完,一边读取一边写入
				os.write(buf, 0, readlen);
				//os.write(buf)这样吧写入的话,写入可能造成文件损失
			}
		System.out.println("拷贝成功");
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			if(is!=null) {
				try {
					is.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(os!=null) {
				try {
					os.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}

2.5文件字符流

FileReader继承于InputStreamReader,InputStreamReader继承于Reader
FileWriter继承于OutputStreamWriter,OutputStreamWriter继承于FileWriter
FileReader相关方法

  • 1)new FileReader(File/String)
  • 2)read:每次读取单个字符,返回该字符,如果到文件末尾返回-1;
  • 3)read(char[]):批量读取多个字符到数组,返回读取的长度
  • FileWriter相关方法:
  • new FileWriter(File/String):覆盖模式
  • new FileWriter(File/String,true):追加模式
  • 注意:FileWriter使用后,必须关闭或者刷新,否则不能写入到指定的文件当中去
    代码
  • FileReader
package com.lk.Reader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class FileReadertext {
	//1.创建FileReader对象
	public static void main(String[] args) {
		FileReadertext frt = new FileReadertext();
		//frt.ReaderText1();
		frt.ReaderText2();
	}
	//单个字符读取文件
	public void ReaderText1() {
		String filepath = "G:\\IO流\\pig.txt";
		FileReader fileReader = null;
		int data = 0;
		char[] buf = new char[8];
		try {
			fileReader = new FileReader(filepath);
			//单个字符的读取
			//因为中文字符是三个字节,而我们读取打印是一个一个字节答应的,所以执行到中文的时候会报错
			while((data = fileReader.read()) != -1) {
				System.out.print((char)data);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			if(fileReader!=null) {
				try {
					fileReader.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
	}
	public void ReaderText2() {
		System.out.println("file02");
		String filepath = "G:\\IO流\\pig.txt";
		FileReader fileReader = null;
		int readlen = 0;
		char[] buf = new char[8];
		try {
			fileReader = new FileReader(filepath);
			//单个字符的读取
			//因为中文字符是三个字节,而我们读取打印是一个一个字节答应的,所以执行到中文的时候会报错
			//返回的是实际读取到的字符数,如果返回-1,说明文件结束了
			while((readlen = fileReader.read(buf))!=-1) {
				System.out.print(new String(buf,0,readlen));//不太明白为什么打出来的中文还是乱码
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			if(fileReader!=null) {
				try {
					fileReader.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
	}
	
}

  • FileWriter
  • //注意FileWriter使用后,必须关闭或者flush,否则数据写入不到想要的地方去
package com.lk.Reader;

import java.io.FileWriter;
import java.io.IOException;


public class FileWritertext {
	public static void main(String[] args) {
		FileWritertext fwt = new FileWritertext();
		fwt.text1();
	}
	public void text1() {
		String path = "G:\\IO流\\note.txt";
		FileWriter fw = null;
		char[] chars = {'a','b','c'};
		try {
			fw = new FileWriter(path);//默认是覆盖写入的方法的
			//write(int) 写入单个字符
			fw.write('H');
			//write(char[]):写入指定的数组
			fw.write(chars);//同一个对象执行的代码,所以指针一直在末尾,当我们重新运行的时候,重新创建了filewriter指针会移动到最前面去
			
			//write(char[],off,len):写入指定数组的指定的部分
			fw.write("LKhhhh".toCharArray(), 0, 2);
			//write(String):写入整个字符串
			fw.write("Hello,CDC");
			//write(String,off,len):写入字符串指定部分
			fw.write("北京上海", 0, 2);//从0的位置开始,写入计数为2个的字符
			//在数据量大的情况下,可以使用循环操作
			fw.write("努力过后定见彩虹");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			//对于FileWriter,一定要关闭流,或者刷新filewriter
			try {
				//关闭文件流,等价与flush+关闭的行为
				fw.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		System.out.println("程序结束");
	}
}

2.6节点流和处理流联系和相关概念

  • 节点流:底层的数据流,从特定的数据源读取数据,直接读取(节点流具有单一操作数据源的局限性)
  • 处理流(包装流):对节点流进行包装,使得这个流的功能更加的强大
  • BufferedReader/BufferedWriter BufferedReader类当中,有属性Reader,即可以封装一个节点流。该节点流可以是任意的,只要是Reader的子类就可以。包装流就实现了功能的强大,可以操作文件,数组,字符串等等
  • 包装流:并不局限一种数据源(修饰器模式:这是一种设计模式来完成这种功能的)
  • 数据源:就是存放数据的地方,数据源可以是文件是数组,是管道
    节点流和处理流的区别和联系:
    1.节点流是底层的,直接跟数据源相连接
    2.处理流(包装流)包装节点流,可以消除不同节点流之间的差异
    3.使用了修饰器设计模式,
    处理流的功能体现:
    1.性能提高,缓冲的实现
    2.操作更加的便捷,可以一次性输出大量的数据,可以多次的读取字符串或者多次的读取文件

2.7BufferedReader和BufferedWriter的使用和进行复制操作

  • 这里需要注意的是:br.readline()使用的时候是不会读取到换行的符号的,因此如果是一行一行的读取,在一行一行的写入的时候要写入一个换行的符号才行
    BufferedReader的使用
package com.lk.Buffered0824;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class bufferedReader {
	public static void main(String[] args) {
		bufferedReader br = new bufferedReader();
		try {
			br.read();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public void read() throws IOException {
		String filepath = "G:\\IO流\\pig.txt";
		BufferedReader br = new BufferedReader(new FileReader(filepath));
		String line;
		//这个方法是按行读取文件,当返回的是空的时候代表读取完毕(如果到达流的末尾就返回空)
		line = br.readLine();
		System.out.println("line:"+line);
		while((line = br.readLine())!=null) {
			System.out.println(line);
		}
		//只需要关闭外层流就行了,因为会自动的关闭底层的结点流
		br.close();
	}
}

BufferedWriter的使用

package com.lk.Buffered0824;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class bufferedWriter0824 {
	public static void main(String[] args) throws IOException {
		String filepath = "G:\\IO流\\ok.txt";
		//创建BufferedWriter
		//这里也是覆盖写入,如果是追加
		BufferedWriter bw = new BufferedWriter(new FileWriter(filepath,true));//FileWriter这个创建时候是否添加true,就是代表是否要追加的选项
		bw.write("hello,Leo1");
		bw.newLine();
		bw.write("hello,Leo2");
		bw.newLine();
		bw.write("hello,Leo3");
		bw.newLine();
		//这里没有存在覆盖的问题,是因为缓冲区,当close的时候或者flush的时候才写入的,只写入一次不会覆盖
		bw.close();
	}
}

使用BufferedWriter和BufferedReader来实现文件的拷贝工作

package com.lk.Buffered0824;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
//使用缓冲流拷贝文件
public class Copy {
	public static void main(String[] args) {
		Copy cp = new Copy();
		cp.copy();
	}
//说明:BufferedReader 和 BufferedWriter 是字符操作
//不能进行字节的操作,字节操作可能会造成文件的损坏
//问问原因:中文的复制操作为什么会损坏文件相关的数据

	public void copy() {
		String Sourcepath = "G:\\IO流\\pig.txt";
		String Aimpath = "G:\\IO流\\pig2.txt";
		BufferedReader br = null;
		BufferedWriter bw = null;
		String line = ""; 
		try {
			br = new BufferedReader(new FileReader(Sourcepath));
			bw = new BufferedWriter(new FileWriter(Aimpath));
			//说明:readLine 读取一行的内容,但是没有读取到换行的符号
			while((line = br.readLine()) != null){
				//所以当我们每次读取一行就将其写入其中
				bw.write(line);
				//插入一个换行符
				bw.newLine();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			if(br != null) {
				try {
					br.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(bw != null) {
				try {
					bw.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}

	}
}

//完善两个项目:仿照qq的通信 //坦克大战(多线程编程一两周类完成)

2.8对象流

ObjectInputStream和ObjectOutputStream
需求

  • 保存对象的时候,我们还想将对象的数据类型保存下来

  • 保存值和数据类型的这个需求

  • 序列化的定义:当我们保存数据的时候,保存了它的值和它的数据类型

  • 反序列化定义:当我们恢复数据的时候,将其值和数据类型恢复了出来,我们将其称之为反序列化
    -为了要让一个类是可序列化的,必须要实现两个接口当中的一个(Serializable //这是一个可序列化标记,没有方法)
    Externalizable//该接口有方法需要实现,因此一般实现Serializable接口

  • 注意事项和细节说明

  • 1.读写的顺序要一致

  • 2.要求序列化和反序列化的对象要实现 Serializable接口

  • 3.序列化对象的时候,默认将里面的所有属性都进行了序列化操作,除了static或transient修饰的成员,在保存的时候,当我们读入的时候,static和transient成员读取的是空的值

  • 4.序列化对象的时候,要求里面属性的类型也需要实现序列化的接口才行,当我们要序列化的时候,要求里面所有属性都要序列化才行*******

  • 5.序列化是可继承的,是可以传递下来的

  • Dog类用来验证对象流

package com.lk.object0825;

import java.io.Serializable;

//如果需要序列化某个类的对象,需要实现序列化的接口
class Dog implements Serializable{
	private String name;
	private int age;
	private Master master = new Master();//当我们dog去序列化的时候会去报错,当
	//serialVersionUID可以提高版本的兼容性
	private static final long serialVersionUID = 1L;
	private static String nation;
	private transient String color;//transient 短暂的,转瞬即逝的
	public Dog(String name,int age,String nation,String color) {
		this.name = name;
		this.age = age;
		this.nation = nation;
		this.color = color;
	} 
	
	@Override
	public String toString() {
		return "Dog [name=" + name + ", age=" + age + ", color=" + color + "]"+nation;
	}

	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;
	}
	
	
}
  • Master类用来验证序列化对象里面的属性必须全部序列化
package com.lk.object0825;

import java.io.Serializable;

public class Master implements Serializable{

}

  • objectOutputStream
package com.lk.object0825;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class objextOutText {
	
	public static void main(String[] args) throws Exception, IOException {
		//序列化了以后,保存的文件格式,不是纯文本的,是按照他的格式来保存的
		String filepath = "G:\\IO流\\data.dat";
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filepath));
		oos.writeInt(100);//int -》integer   int在底层会自动转型为integer  integer是可序列化的
		oos.writeBoolean(true); //boolean->Boolean  实现了Serializable
		oos.writeChar('a');
		oos.writeDouble(9.66);
		oos.writeUTF("Leo,Hello");
		oos.writeObject(new Dog("旺财dog",10,"China","white"));
		//在读取将数据保存在文件的时候:Static 和 transinet属性不会序列化
		//易错点:因为序列化的时候,Dog信息的保存也保存了其包的信息
		//在反序列化的时候,要注意将Dog(传递的类),放在双方都可以引用的位置才行
		oos.close();
		System.out.println("数据保存完毕(序列化形式完毕)");
	}
}

  • ObjetcInputSream
package com.lk.object0825;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;

public class objextInText {
	public static void main(String[] args) throws Exception, IOException {
		String filepath = "G:\\IO流\\data.dat";
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filepath));
		
		//读取
		//1.读取(反序列化)的顺序需要和你保存数据(序列化)的顺序一致才行
		//2.重要的细节
		System.out.println(ois.readInt());
		System.out.println(ois.readBoolean());
		System.out.println(ois.readChar());
		System.out.println(ois.readDouble());
		System.out.println(ois.readUTF());
		//dog的编译类型是 Object ,dog的运行类型需要向下转型
		Object dog = ois.readObject();
		System.out.println("运行类型="+dog.getClass());
		System.out.println("dog信息="+dog);
		
		//重点细节
		//如果我们希望调用Dog的方法
		//向下转型,需要我们将类拷贝到可以引用的位置
		Dog dog2 =(Dog)dog;
		System.out.println(dog2.getName());
		//关闭流,关闭外层流就可以了
		ois.close();
	}
}

2.9标准输入输出流

System.in 标准输入 对于这个输入对象的监听在于键盘上面
System.out 标准输出 对于这个输出对象的监听在于显示器上面

package com.lk.standard;

import java.util.Scanner;

import jdk.nashorn.internal.runtime.regexp.joni.ScanEnvironment;

public class InputAndOutput {
	//其实System.in和System.out都是一种输入输出流
	public static void main(String[] args) {
		//System.in  编译类型是 InputStream
		//System.in  运行类型是 BufferedInputStream
		//标准输入是键盘
		System.out.println(System.in.getClass());
		//编译类型是 PrintStream
		//运行类型是 PrintStream
		//标准输出是显示器
		System.out.println(System.out.getClass());
		//我们经常使用的Out和in方法都是输入,输出
		//new Scanner(System.in) 
		Scanner scan = new Scanner(System.in);
		System.out.println("请输入内容");
		
	}
}

2.10字节流转换为字符流(转换流)

InputStreamReader,OutputStreamWriter

  • 原因:字节流转换为字符流,可以设置自己想要读取文本文件的格式以及写入文本文件的格式,防止中文乱码的问题
package com.lk.transformation0825;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;

//转换流解决中文乱码问题,将字节流FileInputStream转成字符流,指定编码utf-8
public class InputStreamReadertext {
	public static void main(String[] args) throws Exception {
		String filepath = "G:\\a.txt";
		//将字节流转换成了字符,并且指定了编码,必须指定读取文件的格式不然就容易造成乱码的问题
		InputStreamReader isr = new InputStreamReader(new FileInputStream(filepath),"utf-8");
		//我们想用的是bufferedReader处理流来读取文本文件效率更高
		BufferedReader br = new BufferedReader(isr);//处理流的效率更高,底层还是用的节点流
		String s = br.readLine();
		System.out.println("读取到的内容="+s);
		//关闭外层流即可
		br.close();  
	}
}

package com.lk.transformation0825;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;

//指定处理的编码的形式 gbk/utf-8
public class OutputStreamReaderText {
	public static void main(String[] args) throws Exception, FileNotFoundException {
		String filepath = "G:\\b.txt";
		String charset = "utf-8";
		//转换流最大的作用是指定读取和写入文本的编辑模式,可以防止乱码的情况
		OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(filepath),charset);
		osw.write("Leo,加油才行啊");
		osw.close();
		System.out.println("按照gbk的编码方式保存文本文件的方式");
		//现在的编码方式是gbk
	}
}

3.打印流

打印流只有输出流没有输入流

  • PrintStream是OutputStream的一个子类
  • 打印流不仅仅可以将信息输出到屏幕上面,也可以将信息输出到文件中来
  • PrintWriter是Writer的子类
  • PrintStream
package com.lk.Print;

import java.io.IOException;
import java.io.PrintStream;

public class PrintStreamtext {
	public static void main(String[] args) throws IOException {
		PrintStream out = System.out;
		//在默认的情况下 ,PrintStream输出数据的位置是标准输出即就是显示器
		//可不可以修改打印的位置呢
		//真正的打印用的是 write方法,也可以直接调用打印来打印
		out.println("Leo,hello");
		//其本质上面是一样的
		out.write("Leo,hello".getBytes());
		//因此也可以修改打印流输出的位置和设备
		//将打印的位置修改为G:\\c.txt
		//日志文件的实现方式 
		out.close();
		System.setOut(new PrintStream("G:\\c.txt"));
		//这个输出语句就会打印在改路径下面的文件当中
		System.out.println("Leo,hello");
	}
}

package com.lk.Print;

import java.io.FileNotFoundException;
import java.io.PrintWriter;

//演示PrintWriterd的使用方法
//字符打印流的实现
public class PrintWritertext {
	public static void main(String[] args) throws Exception {
		
		PrintWriter pw = new PrintWriter(System.out);
		pw.print("hello,leo");
		pw.close();
		PrintWriter pw2 = new PrintWriter("G:\\d1.txt");
		//注意 pw2没有close的时候,是没法向文件当中写入内容的 
		pw2.print("hello,跳跳虎");
		pw2.close();
		
	}
}

4.配置文件的处理

xx.properties配置文件
程序读取配置文件,然后如果要更改配置文件,就要在程序当中改变,然后再写入到其中
比如:程序当中要有读取,写入,更改配置文件功能的作用。这样的话才能在不改变源码的基础下面,转变对于数据库的更改
Properties类
基本介绍:

  • 专门用于读写配置文件的集合类
    配置文件的格式:
    键=值
    键=值
    注意:键值对不需要有空格,值不要用引号括起来,默认其值是String对象

  • 常见的方法有哪些
    load:加载配置文件的键值对到Properties对象
    list:将数据显示到设备上面
    getProperty(key)
    setProperty(key,value) 对key对应的值进行修改
    store:将创建一个配置文件,如果id里面有中文,不会将中文存成汉字,会储存为unicode码

  • 想要读取配置文件的普通的操作

package com.lk.Properties0825;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
//想要读取配置文件的普通的操作
public class Properties01 {
	public static void main(String[] args) throws Exception {
		//读取mysql.properties ,并得到相应的ip,user和pwd
		BufferedReader br = new BufferedReader(new FileReader("mysql.properties"));
		String line = null;
		while((line = br.readLine())!= null) {//虚幻读取
			String[] split = line.split("=");
			System.out.println(split[0]+"值是:"+split[1]);
		}
		br.close();
	}
}

  • 利用properties类来实现配置文件的读取和修改的操作
package com.lk.Properties0825;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;

//使用Properties类来读取我们的配置文件
public class Properties02 {
	public static void main(String[] args) throws IOException, IOException {
		//1.创建一个properties对象
		Properties pp = new Properties();
		//2.加载指定的配置文件,将对应的内容加载到pp对象当中
		pp.load(new FileReader("mysql.properties"));//pp.load代表的含义是将括号里面的数据加载到pp对象当中去
		//3.把键值对显示到控制台上面
		pp.list(System.out);
		//4.根据key获取对应的值
		String user = pp.getProperty("user");
		System.out.println("用户名=" + user);
		String pwd = pp.getProperty("pwd");
		System.out.println("密码是="+pwd);
	}
}

package com.lk.Properties0825;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

//使用Properties来创建配置文件,修改配置文件的内容
public class Properties03 {
	public static void main(String[] args) throws IOException {
		Properties pp = new Properties();
		//创建
		pp.setProperty("charset", "utf8");
		pp.setProperty("user", "汤姆");
		pp.setProperty("pwd", "abc111");
		pp.setProperty("pwd", "88888");
		
		//将k-v 储存到文件当中
		pp.store(new FileOutputStream("mysql2.properties"), null);
		//修改一个键值对
		//如果该文件没有这个key就是创建,如果该文件有这个key就是替换修改
		System.out.println("保存配置文件成功了");
	}
}

6.综合运用

例1:
1)判断G盘下面是否有文件夹mytemp,如果没有就创建mytemp
2) 在G:\mytemp目录下面创建文件 hello.txt
3)如果hello.txt已经存在,提示该文件已经存在了,就不要在重复创建了
例2:
1)使用BufferedReader读取一个文本文件,为每行加上引号,在连同内容一并输出到屏幕上面
例3:编写一个dog.properties name=xx age=xx color=xx 编写Dog类创建一个dog对象,读取dog.properties相应的内容并且完成属性的初始化,并且能够输出出来

  • Text1
    例题1的解决
package com.lk.IOhomework;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;


public class Text1 {
	public static void main(String[] args) throws IOException {
		Text1 t1 = new Text1();
		t1.method2();
	}
	public void method1() throws IOException {
		String filepath = "G:\\mytemp";
		File file = new File(filepath);
		FileWriter fw = null;
		//创建目录
		if(file.exists()) {
			System.out.println("该目录已经存在");
		}else {
			file.mkdirs();//创建慕了
		}
		//创建目录下面的文件
		String filepath2 = "G:\\mytemp\\hello.txt";
		File file2 = new File(filepath2);
		if(file2.exists()) {
			System.out.println("文件已经存在,不必重复创建");
		}else {
			fw = new FileWriter(file2);
			fw.write("hello,world--");
			fw.flush();
		}
		fw.close();
	}
	public void method2() throws IOException {
		String filepath = "G:\\mytemp";
		File file = new File(filepath);
		if(!file.exists()) {
			if(file.mkdirs()) {
				System.out.println("创建成功");
			}else {
				System.out.println("创建失败");
			}
		}else {
			System.out.println("目录已经存在不必重复创建");
		}
		String filepath2 = "G:\\mytemp\\hello.txt";
		File file2 = new File(filepath2);
		if(!file2.exists()) {
			if(file2.createNewFile()) {
				System.out.println("文件创建成功");
				FileWriter fw = new FileWriter(file2);
				fw.write("Hello,Leo----");
				fw.close();
			}else {
				System.out.println("文件创建失败");
			}
		}else {
			System.out.println("文件已经存在");
		}
		
	}
	
}

  • Text2
    //第二个任务的解决
package com.lk.IOhomework;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Text2 {
	//当我们出现了打印的中文是错误的时候,用转换流指定读取的文件的格式即可以解决这个问题
	public static void main(String[] args) throws IOException {
		Text2 t2 = new Text2();
		t2.method2();
	}
	//method1是自己写的
	public void method1() throws IOException{
		String filepath = "G:\\IO流\\pig.txt";
		File file = new File(filepath);
		InputStreamReader isr = new InputStreamReader(new FileInputStream(file),"utf-8");
		BufferedReader br = new BufferedReader(isr);
		String content = "";
		while((content=br.readLine())!=null) {
			System.out.println(content);
		}
	}
	//method2是标准的写法
	//记住一定要将流给关闭即可
	public void method2() throws IOException {
		String filepath = "G:\\IO流\\pig.txt";
		File file = new File(filepath);
		String line = "";
		InputStreamReader isr = new InputStreamReader(new FileInputStream(file),"utf-8");
		BufferedReader br = null;
		int lineNum = 0;
		try {
			br = new BufferedReader(isr);
			while((line=br.readLine())!=null){
				System.out.println(++lineNum + line);
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			if(br!=null) {
				br.close();
			}
		}
	}
}

  • Text3
  • 第三个任务的解决
package com.lk.IOhomework;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;

public class Text3 {
	public static void main(String[] args) throws IOException {
		Text3 t3 = new Text3();
		t3.method1();
	}
	//自己写的方法
	public void method1() throws IOException{
		Properties pp = new Properties();
		pp.load(new FileReader("dog.properties"));
		String name = pp.getProperty("name");
		String age = pp.getProperty("age");
		String color = pp.getProperty("color");
		Dog dog = new Dog(name,age,color);
		//并且要输出dog里面的内容
		System.out.println("name:"+dog.getName());
		System.out.println("age:"+dog.getAge());
		System.out.println("color:"+dog.getColor());
	}
}


  • dog类相关的代码
package com.lk.IOhomework;

public class Dog {
	private String name;
	private String age;
	private String color;
	public Dog(String name,String age,String color) {
		this.name = name;
		this.age = age;
		this.color = color;
	}
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return super.toString();
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getAge() {
		return age;
	}
	public void setAge(String age) {
		this.age = age;
	}
	public String getColor() {
		return color;
	}
	public void setColor(String color) {
		this.color = color;
	}
	
}

7.感悟

学习是不断的过程,是永远不要放弃的精神,不断的学习,就要不断的回顾以及不断的输出。只有通过不断的输出,不断的去先去做难的事情,在回过头来追求细节,这样对于细节的理解,和基础的理解会有不同的感触

名言警句:经过云端的道路,只亲吻攀登者的足迹

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值