黑马程序员—Java基础学习笔记之IO流

-----------android培训java培训java学习型技术博客、期待与您交流!-----------

.IO

1.概念

IO流用来处理设备之间的数据传输

Java对数据的操作是通过流的方式

Java用于操作流的类都在IO包中

流按流向分为两种:输入流,输出流。

流按操作类型分为两种:字节流与字符流。字节流可以操作任何数据,字符流只能操作纯字符数据,比较方便。

2.IO流常用父类

字节流的抽象父类:

InputStreamOutputStream

字符流的抽象父类:

Reader Writer

3.IO程序书写

使用前,导入IO包中的类

使用时,进行IO异常处理

使用后,释放资源

.字节流

1.读取文件

创建FileInputStream对象,指定一个文件.文件必须存在,不存在则会抛出FileNotFoundException

使用read()方法可以从文件中读取一个字节.如果读取到文件末尾会读到-1

读取结束后需要释放资源,调用close()方法关闭输入流

2.写出文件

创建FileOutputStream对象,指定一个文件.文件不存在会创建新文件,存在则清空原内容.如果需要追加,在构造函数中传入true.

使用write()方法可以向文件写出一个字节.

写出结束后同样需要调用close()

3.拷贝文件

可以从文件中逐个字节读取,逐个字节写出,但这样做效率非常低

我们可以定义一个数组作为缓冲区,一次读取多个字节装入数组,然后再一次性把数组中的字节写出1byte = 8bit

4.常用方法

InputStream:

read()读取一个字节

read(byte[])读取若干(数组长度)字节

available()获取可读的字节数

close()关闭流,释放资源

OutputStream:

write(int)写出一个字节

write(byte[])写出数组中的所有字节

write(byte[],start,len);

close()关闭流,释放资源

5.BufferedInputStream

BufferedInputStream内置了一个缓冲区(数组)

BufferedInputStream中读取一个字节时

BufferedInputStream会一次性从文件中读取8192,存在缓冲区中,返回给程序一个

程序再次读取时,就不用找文件了,直接从缓冲区中获取

直到缓冲区中所有的都被使用过,才重新从文件中读取8192

6.BufferedOutputStream

BufferedOutputStream也内置了一个缓冲区(数组)

程序向流中写出字节时,不会直接写到文件,先写到缓冲区中

直到缓冲区写满, BufferedOutputStream才会把缓冲区中的数据一次性写到文件里

1.四种拷贝文件方法

* a.使用FileInputStreamFileOutputStream,逐个字节拷贝

* b.使用FileInputStreamFileOutputStream,定义一个大数组(length等于文件大小),一次性拷贝

***** c.使用FileInputStreamFileOutputStream,定义一个小数组(例如1024),多次拷贝

***** d.使用BufferedInputStreamBufferedOutputStream内置的缓冲区,逐个字节拷贝

2.标准化IO流操作的代码

*** a.finally嵌套

*** b.try close

.练习

1,copy文件

 package com.heima.bij.io.test;

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

public class Demo_Copy_Method {

	/**
	 * 1,copy文件	
	 */
	public static void main(String[] args) throws IOException {
		//demo1();
		//demo2();
		//demo3();
		//demo4();
		FileInputStream fis = new FileInputStream("Beyond - 海阔天空.mp3");//创建字节流读取对象
		FileOutputStream fos = new FileOutputStream("copy.mp3");//创建字节流写出对象
		byte[] arr = new byte[fis.available()];
		fis.read(arr);
		fos.write(arr);
		
		fis.close();
		fos.close();
	}

	public static void demo4() throws FileNotFoundException, IOException {
		FileInputStream fis = new FileInputStream("Beyond - 海阔天空.mp3");//创建字节流读取对象
		FileOutputStream fos = new FileOutputStream("copy.mp3");//创建字节流写出对象
		BufferedInputStream bis = new BufferedInputStream(fis);//将字节流对象包装
		BufferedOutputStream bos = new BufferedOutputStream(fos);//将字节流对象包装
		
		int b;
		while((b = bis.read()) != -1) {			//从输入流缓冲区的字节数组读
			bos.write(b);				//写到输出流的缓冲区字节数组
		}
		
		bis.close();
		bos.close();
	}

	public static void demo3() throws FileNotFoundException, IOException {
		FileInputStream fis = new FileInputStream("Beyond - 海阔天空.mp3");	//创建字节流读取对象
		FileOutputStream fos = new FileOutputStream("copy.mp3");//创建字节流写对象
		
		int len;							//记录读取的有效的字节个数
		byte[] arr = new byte[1024];			         //创建字节数组
		while((len = fis.read(arr)) != -1) {			         //将数据读取到字节数组中
			fos.write(arr, 0, len);				//将字节数组写出去,按照len写出有效的字节个数
		}
		
		fis.close();
		fos.close();
	}

	public static void demo2() throws FileNotFoundException, IOException {
		FileInputStream fis = new FileInputStream("aaa.txt");
		FileOutputStream fos = new FileOutputStream("bbb.txt");
		
		int len;		 //记录读取的有效的字节个数
		byte[] arr = new byte[1024];
		while((len = fis.read(arr)) != -1) {
			//fos.write(arr);
			fos.write(arr, 0, len);
		}
		
		fis.close();
		fos.close();
	}

	public static void demo1() throws FileNotFoundException, IOException {
		FileInputStream fis = new FileInputStream("aaa.txt");
		
		byte[] arr = new byte[2];
		
		int len1 = fis.read(arr);
		for (byte b : arr) {
			System.out.println(b);//97 98
		}
		System.out.println("---------------------");
		int len2 = fis.read(arr);
		for (byte b : arr) {
			System.out.println(b);//99 98
		}
		System.out.println("-------------------");
		int len3 = fis.read(arr);
		int len4 = fis.read(arr);
		System.out.println(len1);
		System.out.println(len2);
		System.out.println(len3);
		System.out.println(len4);
		fis.close();
	}

}

2,给图片加密

package com.heima.bij.io.test;

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

public class Test_pagejiami {
/**
 * 2,给图片加密
 * 思路:加密即可以通过异或一个密码,解密只需要再异或一次即可
 */
	public static void main(String[] args) throws IOException {
		FileInputStream fis = new FileInputStream("1.jpg");
		FileOutputStream fos = new FileOutputStream("2.jpg");
		//解密只需要再将图标异或一次即可
		//FileInputStream fis = new FileInputStream("2.jpg");
		//FileOutputStream fos = new FileOutputStream("3.jpg");
		int b;
		while((b=fis.read())!=-1) {
			fos.write(b ^ 123456);//通过异或进行加密
		}
		fis.close();
		fos.close();
	}

}

3.从键盘输入接收一个文件路径,把该文件的内容拷贝到工程中

package com.heima.bij.io.test;

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

public class Test_lujing {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入一个文件路径");
		
		String dir = sc.nextLine();//把路径存放到dir变量中
		int index = dir.lastIndexOf('\\');//单斜线是专业字符,所以需要用双;读取最右边的\
		String name = dir.substring(index+1);//通过下标+1获取文件名
		
		FileInputStream fis = new FileInputStream(dir);	//创建文件的读取对象
		FileOutputStream fos = new FileOutputStream(name);//创建写文件的对象
		
		int len;
		byte[] arr = new byte[1024];//定义缓冲区
		
		while((len=fis.read(arr))!= -1) {//将文件读到缓存区去
			fos.write(arr,0,len);       //写出缓冲区
		}
		fis.close();
		fos.close();
		sc.close();//sc也需要关闭资源
	}

}


4.从键盘接收输入,把键盘输入的数据写到文件,直到输入quit时退出

package com.heima.bij.io.test;

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

public class Io_copy {

	/**
	 * 4,将键盘录入的数据拷贝到当前项目下的text.txt文件中,键盘录入数据当遇到quit时就退出
	 */
	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		FileOutputStream fos = new FileOutputStream("text.txt",true);
		System.out.println("请输入:");
		
		while(true) {
			String line = sc.nextLine();
			if(line.equals("quit"))
				break;
			
			fos.write(line.getBytes());	//将键盘录入的字符串转换为字节数组写出去
			//fos.write('\r');
			//fos.write('\n');
			fos.write("\r\n".getBytes());			//写出回车换行符号
		}
		
		sc.close();
		fos.close();
	}

}

附加题:约瑟夫环

package com.heima.bij.io.test;

import java.util.LinkedList;
import java.util.List;

/**
 * 附加题:约瑟夫环
 */
public class Io_yuesefuhuan {
	public static void main(String[] args) {
		int lucklyNum = getLucklyNum(8);
		System.out.println(lucklyNum);
	}
	//定义getLuckyNum方法
	public static int getLucklyNum(int num) {
		List<Integer> list = new LinkedList<>();
		//将num存入集合中
		for(int i = 1; i <= num; i++) {
			list.add(i);
		}
		
		int count = 1;						//查数
		for(int i = 0; list.size() != 1 ; i++) {			//遍历集合,只要集合中的元素不为1,就不断循环
			if(i == list.size()) {				//当i自增到了集合中元素的个数时
				i = 0;				//就将i重新置为0;count还是在自加,比如此时,归零,对应count=9
			}
			
			if(count % 3 == 0) {		//只要查到了3的倍数就从集合中杀人
				list.remove(i--);	         //删除的时候要索引--
			}
			count++;				//查数递增
		}
		return list.get(0);			//最后集合中只有一个元素就是哪个幸运的数
	}
}

控制台结果:

7

关键代码分析:remove(i--),为何要i--?

答:删除3后,后面的数会自动补上,即4补到3的位置上,5补到4位置上,然而此时索引指向的是4原来的位置,这样就会漏掉一个4,所以要remove(i)后再将i--,画图分析如下

使用迭代器也可以实现约瑟夫环

代码如下:

package com.heima.bij.io.test;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/**
 * 附加题:约瑟夫环
 * 分析:使用迭代其也可以实现约瑟夫环
 */

public class Io_yuesefuhuan_iterator {

	public static void main(String[] args) {
		int counter = 1;
		List<Integer> list = new LinkedList<>();
		for(int i = 1; i <= 8; i++)
			list.add(i);
		System.out.println(list);
		while(true) {
			Iterator<Integer> it = list.iterator();
			if(list.size() == 1)
				break;
			while(it.hasNext()) {
				Integer i = it.next();
				if(counter++ % 3 == 0){
					it.remove();
					System.out.print(i + " ");
				}
			}
		}
		System.out.println("\n" + list);
	}

}

控制台结果:

[1, 2, 3, 4, 5, 6, 7, 8]
3 6 1 5 2 8 4
[7]

-----------android培训java培训java学习型技术博客、期待与您交流!-----------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值