【Java】IO流

一.IO流 概述

1. 定义

从【程序】到【文件/数据库/网络】两端,数据的输入和输出

二.文件IO

操作步骤:

  1. 创建文件(接收器)
  2. (选择)IO流(抽象类与实现类)
  3. 选择I/O操作(读/写)
  4. 关闭流
1. 创建文件(接收器)

java.io.File

  1. 首先:创建文件对象,才能通过对象使用相关功能
  2. 创建文件
File file=new File("D:\\IOTest.txt");
file.createNewFile();
file.renameTo(new File("D:\\IOTest2.txt"));
  1. 创建文件夹
File  f= new File("d://a//b//c");
f.mkdir();
创建此抽象路径名指定的目录。例如如果上述文件中已有d://a//b文件夹,则在此基础上,再建一个子文件夹c;如果没有d://a//b,则不报错但创建失败
f.mkdirs();
创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。不管d://a//b是否存在,都会创建d://a//b//c文件夹

注:File 类的实例是不可变的;也就是说,一旦创建,File 对象表示的抽象路径名将永不改变
文件默认false自动覆盖,new File(“d://c.txt”),true)进行续写

  1. 代码示例
package java_20191208;
import java.io.File;
import java.io.IOException;
public class TestFile {
	public static void main(String[] args) throws IOException {
		//构造方法,在改路径进行声明,此时在D盘并未真正创建
		File file=new File("D:\\IOTest.txt");
//		File file=new File("d://IOTest.txt");		这样也可以
//		File file=new File("d:"+File.separator+"c.txt");
		if(!file.exists()) {
//			通过此对象方法,在系统创建该文件
			file.createNewFile();
			System.out.println("创建成功");
		}
		else {
//			删除将该文件对象:"D:\\IOTest.txt"-删除
//			file.delete();
//			重命名已存在文件夹
			file.renameTo(new File("D:\\IOTest2.txt"));
			System.out.println("该文件已存在,新创建了D:\\IOTest2.txt");
		}
		File  f= new File("d://a//b//c");
		f.mkdirs();
	}
}
2.(选择)IO流—抽象类
  1. IO流分类
    (1)按方向分 :输入流,输出流
    Input和Read
    Output和Write
    (2)按传输单位分 : 字节流 ,字符流
    Input、Output
    Write、Read
    (3)按功能分: 节点流, 处理流
    Input、Output
    Buffer、Change、Data、Object、Print
  2. JDK提供的4大抽象流
    (抽象类不能实例化,他们底层还需实现类构造对象)
    (1)OutputStream/InputStream
    此抽象类是表示输入/输出字节流的所有类的超类。输入/输出流接受输入/输出字节并将这些字节发送到某个接收器。
    (2)Writer/Reader
    写入/读出字符流的抽象类。Writer子类必须实现的方法仅有 write(char[], int, int)、flush() 和 close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能。

read()&write()

write(1)//	实例代码:向文件夹中写26个字母
	//	for(int i=97;i<123;i++) {
	//  指定要写入字符的 int值
	//	os.write(i);
	//	}
write(2):
	//	将事先声明好的byte数组写入构造os对象的File文件
	//  byte[] b= {1,2,3};
	//	os.write(b);
	
read(1):无参的read方法返回值为类型,表示【从输入流读取一个数据字节,返回int类型变量】
	//	实例代码:向系统写回26个字母
	//	for(int j=0;j<f.length();j++){
	//		int i=is.read();
	//		System.out.println((char)i+" ");
	//	}
read(2):int read(byte[] bs)方法返回值表示【读入缓冲区的字节总数,如到达文件末尾则返回 -1】,参数表示【存储读取数据的缓冲区】
	//	byte[] b=new byte[5];
	//	int i=is.read(b);
	//	System.out.println((char)b[0]);   //输出第一个:a!!
	//	System.out.println(i);		//输出数组大小:5
3.(选择)IO流—实现类

1. 文件字节流:FileOutputStream&FileInputStream

package java_20191208;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class IOputStream {
	public static void main(String[] args) throws IOException {
		//1.创建文件
		File f=new File("D://a.txt");
		//2.选择IO流
//		OutputStream os=new OutputStream(f);  Error:抽象类不能直接创建对象
//		注:如果文件不存在:向文件写内容时,系统会自动创建;但读文件时,系统会报异常
		OutputStream os=null;
		InputStream is=null;
		try {
		//3.创建输出流实现类对象,并进行写操作
			os=new FileOutputStream(f);
			//向文件夹中写26个字母
			for(int i=97;i<123;i++) {
				os.write(i);
			}
		}catch (IOException e) {
			e.printStackTrace();
		}finally {
		//4.关闭输出流
			os.close();
		}
		
		try {
		//3.创建输入流实现类对象,并进行写操作
			is=new FileInputStream(f);
			//向系统写回26个字母
			for(int j=0;j<f.length();j++){
				//read():如果已达文件末尾,则返回-1,可用于循环判断条件
				int i=is.read();
				System.out.println((char)i+" ");
			}
		}catch (IOException e) {
			e.printStackTrace();
		}finally {
		//4.关闭输入流
			is.close();
		}
	}
}

2. 文件字符流:FileWriter&FileReader

package java_20191208;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.Math;

public class IOFileWR {
	public static void main(String[] args) throws IOException {
		File f=new File("D://IOFileWR.txt"); 
		FileWriter fw=new FileWriter(f);
		for(int i=0;i<5;i++) {
			fw.write((int) (Math.random()*50+10));
			//刷新字符流缓冲,所有字符流类写入后必须调用此方法
			fw.flush();
		}
		
		FileReader fr=new FileReader(f);
		int n=0;
		while((n=fr.read())!=-1) {
			System.out.println(n);
		}
		fw.close();
		fr.close();
	}
	//控制台输出五个10~60的随机数
}

3.缓冲流: BufferedWriter&BufferedReader

package java_20191208;

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

public class IOBuffer {
	public static void main(String[] args) throws IOException {
		//Buffered流:面向行的输入输出
		//将文本写入字符输出流,缓冲区暂存字符/字节,达到一定量再进行传输
		//缓冲区大小可以指定,但一般默认的就足够使用
		FileWriter f=null;
		BufferedWriter bw=null;
		FileReader r=null;
		BufferedReader br=null;
		try {
			f=new FileWriter("D://IOBuffer.txt"); 
			bw=new BufferedWriter(f);
			//跨平台换行
			bw.newLine();
			bw.write("从明天起,做一个幸福的人");
			bw.newLine();
			bw.write("喂马,劈柴,周游世界");
			bw.newLine();
			bw.write("从明天起,关心粮食和蔬菜");
			bw.newLine();
			bw.write("我有一所房子,面朝大海,春暖花开");
			//刷新字符流缓冲,所有字符流类写入后必须调用此方法
			bw.flush();
		} catch (Exception e) {
			e.printStackTrace();
		}
		finally {
			bw.close();
		}
		
		try {
			r=new FileReader("D://IOBuffer.txt"); 
			br=new BufferedReader(r);
			while(true){
				String s;
				s=br.readLine();
				if(s==null)	break;
				System.out.println(s);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		finally {
			br.close();
		}
	}
}

4. 数据流:DataOutputStream&DataInputStream

package java_20191208;

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

public class IODate {
	public static void main(String[] args) throws IOException {
//		Date流:输入,输出 字节流  
//		特点: 能够读写——java的基本数据类型
		DataOutputStream dop=null;
		DataInputStream dip=null;
		try {
			//装饰模式声明流对象
			dop=new DataOutputStream(new FileOutputStream(new File("D://IODate.txt"),true)); //续写
			dop.writeInt(1234);
			dop.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			dop.close();
		}
		
		try {
			dip=new DataInputStream(new FileInputStream(new File("D://IODate.txt")));
			int i=dip.readInt();
			System.out.println(i);
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			dip.close();
		}
	}
}

5. 对象流:ObjectOutputStream&ObjectInputStream

package java_20191208;

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

public class IOObject {
	public static void main(String[] args) {
//		Object流:输入输出对象
//		对象必须被序列化
		Student  stu =new Student();
		stu.name="jim";
		stu.age=10;
		stu.num=101;
		ObjectOutputStream  os =null;
		// 装饰模式
		try {
			os =new ObjectOutputStream(new FileOutputStream(new File("d://c.txt")));
			os.writeObject(stu);
			os.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			try {
				os.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
				 
	}
}

//Serializable接口:将类实例对象序列化
class Student implements Serializable{
	String name;
	int age;
	// 不想写在文件里面的属性:transient
	transient int num;
}

6. 转换流:OutputStreamWriter&InputStreamReader

package java_20191208;

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

public class IOChange {
	 public static void main(String[] args) {
//		OutputStreamWriter:转换流
//		提供字符到字节的转换
// 		可以改变编码
		 
// 		确定自己电脑编码
		System.out.println(System.getProperty("file.encoding"));
		String  str="2020年马上到来";
		System.out.println(str);
		// 改变编码
		byte[] b=str.getBytes();
		try {
			String str1=new String(b,"Big5");
			System.out.println(str1);
		} catch (UnsupportedEncodingException e) {
		 	e.printStackTrace();
		}
		 changeIO();
	}
	 
	public static void changeIO(){
		OutputStreamWriter  os =null;
		try {
			os =new OutputStreamWriter(new FileOutputStream(new File("d://c.txt"),true));
		    os.write("我爱你中国");
		    os.flush();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			try {
				os.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	 }
}

7. 单向输出流:PrintStream

package java_20191208;

import java.io.FileNotFoundException;
import java.io.PrintStream;

public class IOPrint {
	public static void main(String[] args) {
		PrintStream ps = null;
		try {
			System.out.println("1.输出到控制台");
			ps = new PrintStream("D://IOPrint");
			ps.print("2.输出到文件");
			System.out.println("3.输出到控制台");
			// 系统重定向方法setOut,重新分配默认输出位置
			System.setOut(ps);
			System.out.println("4.输出到文件");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} finally {
			ps.close();
		}
	}
}
4.关闭流

三.代码实例

1.用指定的编码格式,将文章输入文件夹
package java_20191208_homeWork;

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

public class Poem_BufferedWriter {
	public static void main(String[] args) throws IOException {
		//创建面向行输出的IO流对象
		BufferedWriter bw=new BufferedWriter(new FileWriter("d://test.txt"));
		//先输出原文件编码格式
		System.out.println(System.getProperty("file.encoding"));
		//用字符串存储一行数据
		String s1= "床前明月光";
		//将字符串转换为字节,存入数组
		byte[] b1=s1.getBytes();
		//创建字符串对象,并使用GBK编码方式
		String str1=new String(b1,"GBK");
		String s2= "疑是地上霜";
		byte[] b2=s2.getBytes();
		String str2=new String(b2,"GBK");
		String s3= "举头望明月";
		byte[] b3=s3.getBytes();
		String str3=new String(b3,"GBK");
		String s4= "低头思故乡";
		byte[] b4=s4.getBytes();
		String str4=new String(b4,"GBK");
		//将编码方式规定好的字符串一行一行写入
		bw.write(str1);
		//跨平台换行
		bw.newLine();
		bw.write(str2);
		bw.newLine();
		bw.write(str3);
		bw.newLine();
		bw.write(str4);
		bw.newLine();
		//刷新流,关闭流
		bw.flush();
		bw.close();
	}
}
2.将上述输入的文章,反向输出出来
package java_20191208_homeWork;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Stack;

public class Poem_ChangeInputStream {
	public static void main(String[] args) throws IOException {
		//创建对象行的字符流对象,可实现字符与字节的转换,以及行IO
		BufferedReader br=null;
		BufferedWriter bw=null;
		//反向输出,我们使用栈进行存储,先入后出
		Stack<String> stack=null;
		try {
			br=new BufferedReader(new InputStreamReader(new FileInputStream(new File("d://test.txt"))));
			bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File("d://test2.txt"))));
			stack=new Stack<String>();
			//此处我们刚开始使用的是while(br.readLint!=null)
			//此方法结果正好读一半的数据,因为在判断时就读取了一行数据,但并未写入文件
			//采用这种循环方式,我们就避免了这种情况
			while(true) {
				String s=br.readLine();
				if(s==null) 	break;
				//将读取到的数据行,用一个字符串对象存储,并压入栈
				stack.push(s);
			}
			//刷新缓冲流
			bw.flush();
			//此处我们在控制台检验一下栈是否读入了数据
			System.out.println(stack);
			//循环:如果堆栈非空
			while(!stack.empty()) {
				//取出堆栈数据,每次一个,写进新的文件
				bw.write(stack.pop());
				//跨平台换行
				bw.newLine();
			}
		} catch (IOException e) {
			e.printStackTrace();	
		}finally {
			//关闭流
			br.close();
			bw.close();
		}
	}
}
3.利用字节流,输入文件语句,并输出出来
package java_20191208_homeWork;

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

public class FileIOS {
	public static void main(String[] args) throws IOException {
		File f=null;
		FileOutputStream fos=null;
		FileInputStream fis=null;
		//创建字节流,字节对应ASCII码字母为:Hello World
		byte[] b= {72,101,108,108,111,32,87,111,114,108,100};
		try {
			//新建文件test3
			f=new File("d://test3.txt");
			//如果文件不存在,则创建文件夹
			if(!f.exists()) {
				f.createNewFile();
				fos=new FileOutputStream((f));
				System.out.println("文件创建成功");
			}
			//如果文件存在,则对原文件续写
			else {
				fos=new FileOutputStream((f),true);
				System.out.println("文件已经存在,继续续写");
			}
			//将字节数组写入文件
			fos.write(b);
			
		} catch (Exception e) {
			e.getStackTrace();
		} finally {
			fos.close();
		}
		
		try {
			fis=new FileInputStream((f));
			//读取文件中字节总长度的数据,即全部数据
			for(int j=0;j<b.length;j++){
				//将数据读入,并存储为int变量,然后转换为char字符串,输出出来
				int i=fis.read();
				System.out.print((char)i+" ");
			}
		} catch (Exception e) {
			e.getStackTrace();
		} finally {
			fis.close();
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值