IO流的基本操作(字节流和字符流)

IO流

1.基本概念

IO流就是使用java技术将文件内容读取到java程序中,将程序中的内容保存到java文件中 ,简单来说就是java程序和文件交互的过程。
在这里插入图片描述

2.分类

  • IO流一定要站在程序的角度,在计算机中,所有的文件都是使用字节来表示大小的。
    在这里插入图片描述

一.字节流

  • Java中所有的IO流的底层全部都是字节流.

1.字节输入流 InputStream

  • 使用已知实现子类 FileInputStream
    在这里插入图片描述

1.1构造方法

  1. FileInputStream(File file) 通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。
  2. FileInputStream(FileDescriptor fdObj) 通过使用文件描述符 fdObj 创建一个 FileInputStream,该文件描述符表示到文件系统中某个实际文件的现有连接。
  3. FileInputStream(String name) 通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。

1.2常用方法

  1. int
    available() 返回此输入流方法的下一个调用方可以不受阻塞地从此输入流读取(或跳过)的字节数。
  2. void
    close() 关闭此输入流并释放与该流关联的所有系统资源。
  3. void
    mark(int readlimit) 在此输入流中标记当前的位置。
  • readlimit - 在标记位置失效前可以读取字节的最大限制。
  1. boolean
    markSupported() 测试此输入流是否支持 mark 和 reset 方法。
  2. abstract int
    read() 从输入流读取下一个数据字节。
  3. int
    read(byte[] b) 从输入流中读取一定数量的字节并将其存储在缓冲区数组 b 中。
  • 参数:b - 读入数据的缓冲区。
  • 返回:读入缓冲区的总字节数,如果由于流末尾已到达而不再有数据,则返回 -1。
  1. int
    read(byte[] b, int off, int len) 将输入流中最多 len 个数据字节读入字节数组。

参数:

  • b - 读入数据的缓冲区。
  • off - 在其处写入数据的数组 b 的初始偏移量。
  • len - 要读取的最大字节数。
  1. void
    reset() 将此流重新定位到对此输入流最后调用 mark 方法时的位置。
  2. long
    skip(long n) 跳过和放弃此输入流中的 n 个数据字节。

基本步骤:

  • 指定要操作的文件
  • 创建输入流,将文件读取到IO流
  • 从IO流中获取内容保存到java程序中
  • 关闭资源:先开的后关,后开的先关

1.2.1基本读取

@Test
	void inputio() {
		//指定要操作的文件,使用file
		File file=new File("demo.txt");
		try {
			//将文件读取到io流中
			InputStream in=new FileInputStream(file);
			//获取文件大小内容
			System.out.println("文件内容的长度是:"+in.available());//文件内容的长度是:14
			//从io流中获取内容保存到java程序中
			//在程序中使用字节数组来保存(要注意数组的长度)
			byte[] bytes=new byte[in.available()];//尽量将数组长度与文件内容长度绑定
			in.read(bytes);
			//使用字符串来显示
			String str=new String(bytes);
			//关闭资源
			in.close();
			System.out.println(str);//hello,world!!!
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

1.2.2每一次读一个字节

基本步骤:

  • 读取文件的位置
  • 创建输入流,将文件读取到io流中
  • 一个一个读取
@Test
	void readone() {
		//读取文件的位置
		File file=new File("demo.txt");
		try {
			//创建输入流,将文件读取到io流中
			InputStream in=new FileInputStream(file);
			//读取第一个字符
			int read = in.read();
			//得到第一个字符的unicode编码
			System.out.println(read);
			//将所得到的unicode强转为字符类型
			System.out.println((char)read);
			//全部读取到,如果读到最后一个之后返回-1
			//已经读取过的不会再次进行读取
			int c=-1;
			while((c=in.read())!=-1) {
				System.out.print((char)c);
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	
	}

2.字节输出流 OutputStream

  • 使用已知实现子类FileOutputStream
    在这里插入图片描述

2.1构造方法

  1. FileOutputStream(File file) 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
  2. FileOutputStream(File file, boolean append) 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
  3. FileOutputStream(FileDescriptor fdObj) 创建一个向指定文件描述符处写入数据的输出文件流,该文件描述符表示一个到文件系统中的某个实际文件的现有连接。
  4. FileOutputStream(String name) 创建一个向具有指定名称的文件中写入数据的输出文件流。
  5. FileOutputStream(String name, boolean append) 创建一个向具有指定 name 的文件中写入数据的输出文件流。

2.2常用方法

  1. void
    close() 关闭此输出流并释放与此流有关的所有系统资源。
  2. void
    flush() 刷新此输出流并强制写出所有缓冲的输出字节。
  3. void
    write(byte[] b) 将 b.length 个字节从指定的字节数组写入此输出流。
  4. void
    write(byte[] b, int off, int len) 将指定字节数组中从偏移量 off 开始的 len 个字节写入此输出流。
  5. abstract void
    write(int b) 将指定的字节写入此输出流。

基本步骤:

  • 要写出去的文件内容
  • 写出去的目标文件
  • 往出写(创建输出流)
  • 关闭资源 (关闭资源前一定要进行先flush在close. )

2.2.1直接创建到根目录

@Test
	void outputio() {
		//要写出去的内容
		String message="世界美好与你环环相扣";
		//写出去的目标文件,使用file(文件不存在时会自动创建到根目录下)
		File outfile=new File("out.txt");
		//往出写,将数据保存到byte数组中
		byte[] bytes=message.getBytes();
		try {
			//创建输出流
			OutputStream out=new FileOutputStream(outfile);
			out.write(bytes);
			//关闭资源,关闭资源前要先进行刷新资源
			out.flush();//将io流中的信息刷新到文件中
			out.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
	}

2.2.2创建到其他文件夹

@Test
	void outputio01() {
		//要写出去的内容
		String message="世界美好与你环环相扣";
		//写出去的目标文件,使用file,若不想让文件处于根目录
		//检查路径是否存在,如果不存在,先创建目录,写出文件的时候不会自动创建目录
		File outfile=new File("file\\out.txt");
		System.out.println("文件是否存在:"+outfile.exists());
		//查看父路径是否存在
		File parentFile = outfile.getParentFile();
		//创建目录
		parentFile.mkdirs();
		System.out.println("文件是否存在:"+outfile.exists());
		try {
			//若没有创建
			outfile.createNewFile();
			//往出写,将数据保存到byte数组中
			byte[] bytes=message.getBytes();
			//创建输出流
			OutputStream out=new FileOutputStream(outfile);
			out.write(bytes);
			//关闭资源,关闭资源前要先进行刷新资源
			out.flush();//将io流中的信息刷新到文件中
			out.close();
		}catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
	}

2.2.3写出操作,追加写出

  • \r:回车符,返回到这一行的开头,return的意思。
  • \n:换行符,到下一行的同一位置,纵坐标相同。
  • \t:制表符,为了在不使用表格的情况下,上下对齐。
  • Enter 相当于\n\r,所以Enter的标识为往下,再往前,\n\r等价于\r\n。
@Test
	void outfile() {
		//指定目标位置
		File file=new File("out.txt");
		//创建写出内容
		String mess="\r\n"+"所念皆星河";
		//创建输出流
		try {
			//覆盖写法
			//FileOutputStream fos=new FileOutputStream(file);
			//追加写法
			FileOutputStream fos=new FileOutputStream(file,true);
			//写出去
			fos.write(mess.getBytes());
			//关闭资源
			fos.flush();
			fos.close();
			System.out.println("文件写出成功");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

3.使用字节流实现文件的拷贝

3.1先读取完在写出去

基本步骤

  • 指定源文件位置
  • 目标文件位置
  • 创建读取流和写出流
  • 创建数组容器
  • 使用输入流,将源文件内容保存到数组中
  • 将数组中的内容写出到目标文件中
  • 关闭资源
	@Test
	void copy01() {
		//指定源文件位置
		File sfile=new File("D:\\Java1\\Workspace1\\java02\\src1\\com\\xingyun\\Demo\\StaticTest.java");	
		//目标文件位置
		File dfile=new File("D:\\Java1\\Workspace1\\java02\\src1\\com\\xingyun\\Demo\\newStaticTest.java");
		try {
			//创建读取流和写出流
			FileInputStream fis=new FileInputStream(sfile);
			FileOutputStream fos=new FileOutputStream(dfile);
			//创建数组容器
			byte[] bytes=new byte[fis.available()];
			//使用输入流,将源文件内容保存到数组中
			fis.read(bytes);
			//将数组中的内容写出到目标文件中
			fos.write(bytes);
			//关闭资源
			fos.flush();
			fos.close();
			fis.close();
			System.out.println("文件拷贝成功");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

3.2一边读取一边写(一个字节一个字节的读取)

@Test
	void copy02() {
		//指定源文件位置
		File sfile=new File("D:\\Java1\\Workspace1\\java02\\src1\\com\\xingyun\\Demo\\StaticTest.java");	
		//目标文件位置
		File dfile=new File("D:\\Java1\\Workspace1\\java02\\src1\\com\\xingyun\\Demo\\newStaticTest.java");
		//创建读取流  写出流
		try {
			//创建读取流  写出流
			FileInputStream fis=new FileInputStream(sfile);
			FileOutputStream fos=new FileOutputStream(dfile);
			//创建数组容器
			byte[] bytes=new byte[fis.available()];
			int bt=0;//当前读取的字节数
			//循环读出写出
			while((bt=fis.read(bytes))!=-1) {
				//写出去
				fos.write(bytes);
			}
			//关闭资源
			fos.flush();
			fos.close();
			fis.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

3.3使用数组缓冲区的方式

@Test
	void copy05() {
		//指定源文件位置
				File sfile=new File("D:\\java笔记\\hello.txt");	
				//目标文件位置
				File dfile=new File("D:\\java笔记\\newhello.txt");
				//创建读取流  写出流
				try {
					//创建读取流  写出流
					FileInputStream fis=new FileInputStream(sfile);
					FileOutputStream fos=new FileOutputStream(dfile);
					//创建数组容器
					byte[] bytes=new byte[fis.available()];
					int bt=0;//当前读取的字节数
					//循环读出写出
					while((bt=fis.read(bytes))!=-1) {
					//写出去,只写有效数据
					fos.write(bytes,0,bt);
					}
					//关闭资源
					fos.flush();
					fos.close();
					fis.close();
					System.out.println("文件拷贝成功");
				} catch (FileNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

小例子1

  • 根据输入的源文件,来拷贝一份新的文件,文件类型要一致,新文件的名字是源文件的名字+当前时间
@Test
	void copy04() {
		Scanner input=new Scanner(System.in);
		System.out.println("请输入源文件的路径");
		String filepath=input.next();
		//指定源文件
		File sfile=new File(filepath);
		//获取源文件的名字
		String name=sfile.getName();
		System.out.println(name);
		//使用.将得到的文件名分隔开
		String[] split = name.split("\\.");
		System.out.println(split.length);
		//获取当前时间
		LocalDate lt=LocalDate.now();
		System.out.println(lt);
		//结果为文件名时间.后缀
		String destfile=split[0]+lt+"."+split[1];
		File dfile=new File("D:\\java笔记",destfile);
		System.out.println(dfile.getName());
		try {
			//创建读取流和写出流
			FileInputStream fis=new FileInputStream(sfile);
			FileOutputStream fos=new FileOutputStream(dfile);
			//创建数组容器
			byte[] bytes=new byte[fis.available()];
			//使用输入流,将源文件内容保存到数组中
			fis.read(bytes);
			//将数组中的内容写出到目标文件中
			fos.write(bytes);
			//关闭资源
			fos.flush();
			fos.close();
			fis.close();
			System.out.println("文件拷贝成功");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
}

小例子2

  • 输入要上传的文件名.后缀,将该文件上传到项目的file文件夹下面。
//文件上传
		@Test
		void copy03() {
			//指定要查看的文件位置
			File file=new File("D:\\Java1\\Workspace1\\java02\\src1\\com\\xingyun\\Demo");
			//请输入你要上传的文件名
			String name="1111.jpg";
			File loadfile=null;
			//遍历 
			File[] listFiles = file.listFiles();
			for (File file2 : listFiles) {
				//判断是否是个文件,如果是,则输出文件名
				if(file2.isFile()) {
					System.out.println(file2.getName());
					//得到要上传的文件对象
					if(file2.getName().equals(name)) {
						loadfile=file2;
					}
				}
			}
			//指定上传的位置
			File loadpath=new File("file",name);
			//创建file
			if(!loadpath.getParentFile().exists()) {
				loadpath.getParentFile().mkdirs();
			}
			//创建读入写出流
			try {
				FileInputStream fis=new FileInputStream(loadfile);
				FileOutputStream fos=new FileOutputStream(loadpath);
				//进行上传 
				int len=-1;
				while((len=fis.read())!=-1) {
					fos.write(len);
				}
				//关闭资源
				fos.flush();
				fos.close();
				fis.close();
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

二.字符流

  • 每一次操作最小单位是一个字符,字符流只能用来进行文本文件的操作。

1.Reader

  • 使用已知实现子类FileReader

1.1构造方法

  1. FileReader(File file) 在给定从中读取数据的 File 的情况下创建一个新 FileReader。
  2. FileReader(FileDescriptor fd) 在给定从中读取数据的FileDescriptor 的情况下创建一个新 FileReader。
  3. FileReader(String fileName) 在给定从中读取数据的文件名的情况下创建一个新 FileReader。

1.2常用方法

  1. abstract void
    close() 关闭该流。
  2. void
    mark(int readAheadLimit) 标记流中的当前位置。
  3. boolean
    markSupported() 判断此流是否支持 mark() 操作。
  4. int
    read() 读取单个字符。
  5. int
    read(char[] cbuf) 将字符读入数组。
  6. abstract int
    read(char[] cbuf, int off, int len) 将字符读入数组的某一部分。
  7. int
    read(CharBuffer target) 试图将字符读入指定的字符缓冲区。
  8. boolean
    ready() 判断是否准备读取此流。
  9. void
    reset() 重置该流。
  10. long
    skip(long n) 跳过字符。
//字符输入流
	@Test
	void charread() {
		//源文件
		File file=new  File("out.txt");
		//输入流
		try {
			Reader reader=new FileReader(file);
			//读取到char数组中
//			char[] ch=new char[10];
//			reader.read(ch);
//			String str=new String(ch);
//			System.out.println(str);
			//一个一个读取
			int c=0;
			while((c=reader.read())!=-1) {
				System.out.println((char)c);
			}
			//关闭资源
			reader.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
}

2.Writer

  • 使用已知实现子类FileWriter

2.1构造方法

  1. FileWriter(File file) 在给出 File 对象的情况下构造一个 FileWriter 对象。
  2. FileWriter(File file, boolean append) 在给出 File 对象的情况下构造一个 FileWriter 对象。
  3. FileWriter(FileDescriptor fd) 构造与某个文件描述符相关联的 FileWriter 对象。
  4. FileWriter(String fileName) 在给出文件名的情况下构造一个 FileWriter 对象。
  5. FileWriter(String fileName, boolean append) 在给出文件名的情况下构造 FileWriter 对象,它具有指示是否挂起写入数据的 boolean 值。

2.2常用方法

  1. Writer
    append(char c) 将指定字符追加到此 writer。
  2. Writer
    append(CharSequence csq) 将指定字符序列追加到此 writer。
  3. Writer
    append(CharSequence csq, int start, int end) 将指定字符序列的子序列追加到此 writer.Appendable。
  4. abstract void
    close() 关闭此流,但要先刷新它。
  5. abstract void
    flush() 刷新此流。
  6. void
    write(char[] cbuf) 写入字符数组。
  7. abstract void
    write(char[] cbuf, int off, int len) 写入字符数组的某一部分。
  8. void
    write(int c) 写入单个字符。
  9. void
    write(String str) 写入字符串。
  10. void
    write(String str, int off, int len) 写入字符串的某一部分。

基本步骤

  • 写出目标
  • 写出内容
  • 输出流
  • 输出
  • 关闭流
@Test
	void charout() {
		//写出目标
		File file=new File("newout.txt");
		//写出内容
		String mess="要加油,要努力啊!!!!";
		//输出流
		try {
			//Writer w=new FileWriter(file,true);//追加
			Writer w=new FileWriter(file);//不追加
			//输出
			w.write(mess);
			//关闭资源
			w.flush();//强制刷新,但不会关闭流
			//追加
			w.append("相信自己!!!!!");
			System.out.println("写出成功");
			w.flush();
			w.close();//关闭流之后,无法在使用
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
}

小例子

  • 使用字符进行拷贝
// 使用字符进行拷贝
	@Test
	void charcopy() {
		//指定源文件,目标文件
		File sfile=new  File("demo.txt");
		File dfile=new  File("newdemo.txt");
		//输入输出流
		try {
			FileReader reader=new FileReader(sfile);
			FileWriter writer=new FileWriter(dfile);
			//一边读取一边写出
			int c=-1;
			while((c=reader.read())!=-1) {
				writer.write(c);
			}
			//关闭资源
			writer.flush();
			writer.close();
			reader.close();
			System.out.println("复制成功");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值