12、IO流

IO流

File类

file是文件的意思,所以他是一个可以获取磁盘上的文件的信息,比如说文件的大小(字节单位),文件的相对路径,绝对路径,可读可写,删除文件,获得文件名等操作。

构造方法:

File(String name);// "d:/text.txt"

File(URI uri);

File(目录,子目录);

方法:

方法名称 说 明
boolean exists( ) 判断文件或目录是否存在
boolean isFile( ) 判断是否是文件
boolean isDirectory( ) 判断是否是目录
String getPath( ) 返回此对象表示的文件的相对路径名
String getAbsolutePath( ) 返回此对象表示的文件的绝对路径名
String getName( ) 返回此对象表示的文件或目录的名称
boolean delete( ) 删除此对象指定的文件或目录
boolean createNewFile( ) 创建名称的空文件,不创建文件夹
long length() 返回文件的长度,单位为字节****, 如果文件不存在,则返回 0L
public class Test{
	main{
		File file = new File("d:/test/text.txt");//创建文件对象
		if(!file.exists){//判断是否存在,有目录的时候就不会自动 创建,取反了
			file.mkdir();创建目录,只会创建一层目录,如果有多层则不会创建。
			file.mkdirs();创建目录,有多层就会创建多层。
		}
		file.getName();获取文件的名字。
		file.delect();删除file的整个文件
		file.geAbsolutePath();获得绝对路径。
		file.getPath();获得相对路径。
		file.createNewFile();创建一个文件
		file.toURI();获得浏览器可以访问的路径。
		file.length();获取文件名的长度,不存在返回0L
	}
}

InputStream:输入流 和 OutputStream:输出流

两者是字节的输入输出流,也叫节点流。直接跟磁盘链接,每次读写都是一个字节。磁盘的存储单位是字节。

对于输入输出的概念:我们是以当前程序作为参照物,从磁盘向程序中读数据,是输入。从程序写到磁盘上为输出流。

是一个抽象类,用子类来进行对磁盘的操作。

FileInputStream 和 FileOutputStream:

FileInputStream 文件的输入流,主要是对文件的内容进行读取。

FileOutputStream 文件的输出流,主要是将内容从程序写到磁盘上

package file;

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

public class Demo {
	public static void main(String[] args) throws IOException {
		FileInputStream fis = new FileInputStream("D:\\我的青春我做主.txt");//创建输入流对象,括号里面是一个文件的对象
		/**
		*同过byte[]数组进行读取,每次都读byte数组那么多次效率就高了,
		*而不是每次只读取一个,效率极低
		*/
		byte[] bs = new byte[500];
		int len = fis.read(bs);
		//创建文件对象,获取到磁盘上的文件
		File fl = new File("E:\\myFile");
		fl.mkdirs();//已经判断了是否存在,如果不存在会自动创建一个
		File file = new File(fl,"myPrime.txt");
		if(!file.exists()) {
			System.out.println("....");
			file.createNewFile();
		}
		System.out.println(file.getAbsolutePath());
		System.out.println(file.getName());
		//创建文件的输出流,将内容写进file里面。
		FileOutputStream fos = new FileOutputStream(file);
		fos.write(bs,0,len);//也是通过byte数组进行写入,0是从byte数组的0个位置写入len的字节数
//到最后不要忘记关闭流,不关闭流会导致占用内存,倒着关
		fos.close();
		fis.close();
	}
}

Reader:读 和 Writer:写

每次读取的是一个字符(两个字节的结合),也是直接跟数据源进行传输的,可以称为节点流,

但是从数据源传输到程序的时候将两个字符结合成一个字符了,存在缓冲区,而写的时候是将一个字符先变成两个字节在传输到磁盘上,所以也可以称为处理流。

因为存在缓冲区,所以在写的时候需要通过flush()将缓冲区的内容提交到磁盘上,不然等程序运行结束的时候,因为内容还存在缓冲区中还没进行写入缓冲区的时候进释放内存了。

也可以通过close()关闭流的时候也会提交一次。

FileReader 和 FileWriter

二者的基类是 InuputStreamReader 和 OutputStreamWriter

是文件的字符输入输出流,每次读取的是一个字符。

package demo;

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

public class Demo {
	public static void main(String[] args) throws IOException {
		FileReader fr = new FileReader("e:/my.txt");//创建一个读的对象
		char[] ch = new char[1024];//通过一个字符数组来传输,每次可以读1024个
		int len = 0;//接收读到了多少个字符
		while((len = fr.read(ch)) != -1) {//读取的字符数,如果已到达流的末尾,则返回 -1 
			System.out.println(new String(ch,0,len));//输出在控制台
		}
		FileWriter fw = new FileWriter("e:/my.txt");//创建一个写的流
		fw.write("我和我的祖国");//写进缓冲区,也可以将一个字符数组写进去
		fw.flush();//不调用这个方法就不会从缓冲区写进磁盘,
		//关闭流
		fw.close();
		fr.close();
	}
}

BufferedReader 和 BufferedWriter

创建一个字符的缓冲区,是为了提高读和写的效率。

是一个处理流来的。

package demo;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Demo07 {
	public static void main(String[] args) throws IOException {
		File file = new File("e:/my.txt");
		if(!file.exists()) {
			file.createNewFile();
		}
		FileWriter fw = new FileWriter(file);
		
		//通过writer来创建字符缓冲区对象
		BufferedWriter bw = new BufferedWriter(fw);
		String str = "《虞美人》-春花秋月何时了? -往事知多少。- 小楼昨夜又东风,"
				+ "-故国不堪回首月明中。-雕栏玉砌应犹在,- 只是朱颜改。-"
				+ "问君能有几多愁?-恰似一江春水向东流。";
		String [] strs = str.split("-");
		for (String string : strs) {
			bw.write(string);//每次写一行进去
			bw.newLine();//换行,到下一行
			bw.flush();//刷新缓冲区,放在这里的原因是每次写完一行进从缓冲取里提交一次,就不会造成缓冲区的扩充,而在然后面再去写进磁盘,大大提高效率。
		}
		//bw.flush();
		fw.close();
		FileReader fr = new FileReader("e:/my.txt");
		
		//通过Reader来创建字符缓冲区对象
		BufferedReader br = new BufferedReader(fr);
		String strRead = null;
		while((strRead = br.readLine()) != null) {//判断是否为null,如果为null说明没有内容可读了。
			System.out.println(strRead);
		}
		br.close();
		fr.close();
	}
}

/**
*【1】创建User类,包含以下属性name:String,age:int
                  ,gender String,重写toString方法显示对象的信息
【2】使用BufferedWriter写入文件以“,”分隔
【3】使用BufferedReader读取信息并进行分割,还原成对象,调用
对象的toString方法输出对象的信息
*/
package demo;

public class User {
	private String name;
	private int age;
	private String gender;
	public User() {
		super();
		// TODO Auto-generated constructor stub
	}
	public User(String name, int age, String gender) {
		super();
		this.name = name;
		this.age = age;
		this.gender = gender;
	}
	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;
	}
	public String getGender() {
		return gender;
	}
	public void setGender(String gender) {
		this.gender = gender;
	}
	@Override
	public String toString() {
		return "User [name=" + name + ", age=" + age + ", gender=" + gender + "]";
	}
	
}
/////////////////////////////////////////////////////////////////////////////////////
package demo;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class Demo08 {
	public static void main(String[] args) throws IOException {
		File file = new File("e:/user.txt");
		if(file.exists()) {
			file.delete();
		}
		file.createNewFile();
		FileWriter fw = new FileWriter(file);
		BufferedWriter bw = new BufferedWriter(fw);
		User[] users = {new User("张三",18,"男"),
						new User("李四",22,"男"),
						new User("王五",16,"女"),
						new User("赵六",15,"男"),
						new User("秦阿琪",20,"女")};
		for (User user : users) {
			bw.write(user.getName()+","+user.getAge()+","+user.getGender());
			bw.newLine();
			bw.flush();
		}
		bw.close();
		fw.close();
		FileReader fr = new FileReader(file);
		BufferedReader br = new BufferedReader(fr);
		String read = null;
		while((read=br.readLine()) != null) {
			User user = new User();
			String[] str = read.split(",");
			user.setName(str[0]);
			user.setAge(Integer.parseInt(str[1]));
			user.setGender(str[2]);
			System.out.println(user);
		}
		br.close();
		fr.close();
	}
}


InputStreamReader 和 OutputStreamWriter

获得当前开发环境的字符编码方式
System.out.println(System.getProperty("file.encoding"));

涉及到的类:
读:FileReader (File file)
写:FileWriter(File file)
加入缓冲区的读:BufferedReader(Reader fr)
加入缓冲区的写:BufferedWriter(Writer bw)

当我们系统存储的编码格式和我们读写的格式不一致的时候,此时读写就会产生乱码。

构造方法:

Charset ===> 通过API可以知道,Charset.forName("编码名称");

//InputStreamReader
package demo;

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

public class Demo02 {
	public static void main(String[] args) throws IOException {
		File file = new File("e:/my.txt");
		FileInputStream is = new FileInputStream(file);
		//通过InputStream创建对象,还可以指定编码格式。
		InputStreamReader isr = new InputStreamReader(is,"UTF-8");
		
		char[] ch = new char[1024];
		int len = 0;
		while((len = isr.read(ch))!=-1) {//如果返回-1则没有内容可读了
			System.out.println(new String(ch,0,len));//每次读ch个
		}
		isr.close();
		is.close();
	}
}

//OutputStreamWriter
package demo;

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

public class Demo03 {
	public static void main(String[] args) throws IOException {
		File file = new File("e:/my.txt");
		FileOutputStream fos = new FileOutputStream(file);
		//通过OutputStream的对象来创建对象,还可以指定写入的编码格式。
		OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");
		osw.write("我和你");//写入
		osw.flush();//刷新缓冲区,从缓冲区写入程序
		osw.close();
		fos.close();
	}
}

Scanner的底层原理

package systemin;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.Scanner;

public class Demo {
	public static void main(String[] args) throws IOException {
		//System.in的一个变量就是从键盘录入的数据源
//		InputStream is = System.in;
//		InputStreamReader isr = new InputStreamReader(is);
//		BufferedReader br = new BufferedReader(isr);
//		BufferedWriter bw = new BufferedWriter(new FileWriter("d:/t.txt"));
//		String str = "";
//		while(!"-1".equals(str = br.readLine())) {
//			bw.write(str);
//			bw.newLine();
//			bw.flush();
//		}
		Scanner sc = new Scanner(new File("d:/t.txt"));
		//System.out就是从文件写入到控制台
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		while(sc.hasNextLine()) {
			bw.write(sc.nextLine());
			bw.newLine();
			bw.flush();
		}
		sc.close();
		bw.close();
	//	br.close();
	//	System.out.println(str);
		//Scanner sc = new Scanner(str);
		
	}
}

对象输入输出流: ObjectInputStream 和 ObjectOutputStream

写出对象的的时候,必须要实现Serializable接口,不然无法将对象写进磁盘上。出抛出这个异常: java.io.NotSerializableException

write.object();将一个对象写进磁盘,还有许多方法可以将对象的属性等写进出

write.flush();

read.object();将一个对象读出来,如果程序中没有该对象则会报错。

private static final long serialVersionUID = 1L;;声明版本号是为了后期修改对象的时候,读出来的数据会自动兼容。

package test;

import java.io.Serializable;

public class Dog implements Serializable{
	/**
	 * 声明版本号,如果出现成员变量的增加或者减少,读出来的数据会自动兼容
	 */
	private static final long serialVersionUID = 1L;
	private String name;
	/**
	 * transient	如果不需要将这个成员变量序列化到磁盘上,可以加这个关键字
	 */
	private transient int age;
	public Dog() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Dog(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Dog [name=" + name + ", 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;
	}
	
}


///////////////////////////////////////////////


package test;

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

public class Demo {
	public static void main(String[] args) throws IOException {	
	//对象的写入
		File file = new File("e:/1.txt");
		FileOutputStream fos = new FileOutputStream(file);
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		Dog wangcai = new Dog("旺财",15);
		oos.writeObject(wangcai);
		oos.close();
     //对象的读入
     	File file = new File("e:/1.txt");
		FileInputStream fis = new FileInputStream(file);
		ObjectInputStream ois = new ObjectInputStream(fis);
        Object obj = ois.readObject();//会抛出ClassNotFoundException,用Object来接收
		System.out.println(obj);
		ois.close();    
	}
}

基本数据类型的流,输入和输出:DataInputStream 和DataOutputStream

package test;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class DataStream {
	public static void main(String[] args) throws IOException {
		//写
//		File file = new File("e:/1.txt");
//		FileOutputStream fos = new FileOutputStream(file);
//		DataOutputStream dos = new DataOutputStream(fos);
//		dos.writeInt(123);
//		dos.writeChar('a');
//		dos.writeUTF("我和我的祖国");
//		dos.close();
//		fos.close();
		//读
		File file = new File("e:/1.txt");
		FileInputStream fis = new FileInputStream(file);
		DataInputStream dis = new DataInputStream(fis);
		/**
		 * 每次都读相同类型的数据,并且要根据写的顺序来读,
		 * 不然读出来的就会不一样,或者直接报错
		 */
		int n = dis.readInt();
		System.out.println(n);
		char c = dis.readChar();
		System.out.println(c);
		String str = dis.readUTF();
		System.out.println(str);
		dis.close();
		fis.close();
	}
}

posted @ 2022-03-17 20:03  站着说话不腰疼  阅读(65)  评论(0)    收藏  举报