黑马程序员——IO学习笔记(一)

本文详细介绍了Java和Android开发中流操作的基本概念,包括字节流与字符流的区别,四种抽象基类的应用,以及IO异常处理、已有文本文件数据续写、文件读取、复制文本文件、缓冲区提高效率、装饰设计模式、LineNumberReader的使用、字节流应用、键盘输入流的转换、流的基本规律和IO对Properties()的操作。文章还展示了装饰设计模式的特点、不同类型的流及其应用场景,以及如何通过装饰类增强已有对象的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

------- android培训java培训、期待与您交流! ----------

流按操作数据分为两种:字节流和字符流。
字符流是基于字节流,去查询对应的编码表所表示的文字,因此适用于文本的传输。
字节流为通用的流,既可以适用文本也可以适用图片等。

4个抽象基类:
字节流:InputStream,OutputStream。
字符流:Reader,Writer。

class FileWriterDemo{
	public static void main(String[] args) throws IOException{
		//创建一个FileWriter对象,该对象一被初始化就必须要明确被操作的文件。
		//而且该文件会被创建到指定目录下。如果该目录下已有同名文件,将被覆盖。

	FileWriter fw = new FileWriter(“demo.txt”); //该步就是在明确数据要存放的目的地。

		fw.writer(“abcde”);//将字符串写入流中。
		fw.flush();//刷新流对象中缓冲的数据,将数据刷到目的地中。
		fw.close();//刷新后关闭流。
	}
}


IO异常处理方式:

class FileWriterDemo2{
	public static void main(String[] args){
		FileWriter fw = null;
		try{
			fw = new FileWriter("demo.txt");

			fw.write("abcdefg");

			fw.close();
		}
		catch(IOException e){
			System.out.println(e.toString());
		}
		finally{
			try{
				if(fw!=null)//当找不到文件异常出现时,fw没有指向对象,但还是要执行finally中的代码,这时候调用close方法会出现空指针异常。因此需要先判断一下fw是否为空,再去关闭流
					fw.close();
			}
			catch(IOException e){
				System.out.println(e.toString());
			}
		}
	}
}


对已有文本文件的数据续写:

class FileWriterDemo3{
	public satic void main(String[] args) throws IOException{
		//传递一个true参数,代表不覆盖已有的文件,并在已有文件末尾处续写
		FileWriter fw = new FileWriter("demo.txt", true);

		fw.write("haha\r\nwawa");//windows下,换行用\r\n表示,linux下用\n表示。

		fw.close();
	}
}


读取文件:

class FileReaderDemo{
	public static void main(String[] args){
		//创建一个文件读取流对象,和指定名称的文件相关联。
		//要保证该文件是已经存在的,如果不存在,会发生异常FileNotFoundException。
		FileReader fr = ew FileReader("demo.txt");

		//第一种读取方式:调用读取流对象的read方法,读取文件内容。
		int ch = 0;
		while((ch = fr.read()) != -1){
			System.out.println("ch="+(char)ch);
		}

		//第二种读取方式:通过字符数组进行读取。
		char[] buf = new char[1024];//定义一个字符数组,用于存储读到的字符。
		
		int num = 0;
		while((num=fr.read(buf) != -1)){//read(char[])返回读到字符的个数。
			System.out.println(new String(buf,0,num));
		}
		
	}

	//例:复制一个文本文件
	public static void copy_1(){
		FileWriter fw = null;
		FileReader fr = null;

		try{
			fw = new FileWriter("SystemDemo.copy.txt");//最好先定义FileWriter,在硬盘中先建立一个要写入的空文件。
			fr = new FileReader("SystemDemo.java");

			char[] buf = new char[1024];

			int len = 0;
			while((len=fr.read(buf)) != -1){
				fw.write(buf, 0, len);
			}
		}
		catch(IOException e){
			throw new RuntimeException("读写失败");
		}
		finally{
			if(fr != null){
				try{
					fr.close();
				}
				catch(IOException e){
					
				}
			}
			if(fw != null){
				try{
					fw.close();
				}
				catch(IOException e){
					
				}
			}
		}
	}
}

//缓冲区:为了提高流的读写效率而出现。
class BufferedWriterDemo{
	public static void main(string[] agrs) throws IOException{
		//创建一个字符写入流对象
		FileWriter fw = new FileWriter("buf.txt");

		//为了提高字符写入流效率,加入了缓冲技术。只要将需要被提高的流对象作为参数传递给缓冲区的构造方法即可。
		BufferedWriter bufw = new BufferedWriter(fw);
		bufw.write("abcde");

		bufw.newLine();//为了夸平台的输入换行符,使用此对象输出一个换行符。(Windows:\r\n,Linux:\n)

		//关闭缓冲区,就是在关闭缓冲区中的流对象。所以不需要写fw.close()了
		bufw.close();
	}

	public bufferedReaderDemo(){
		//创建一个读取流对象和文件相关联。
		FileReader fr = new FileReader("buf.txt");

		//为了提高效率,创建字符缓冲对象。
		BufferedReader bufr = new BufferedReader(fr);

		String line = null;
		while((String s1 = bufr.readLine()) != null){//readLine可以一次性读取一行数据,方便于对文本数据的获取,但是它读取一行后,并没有最后的换行符,需要用newLine()方法添加一个换行符。当返回null时表示读到末尾。
			System.out.println("s1:" + s1);
		}
		bufr.close();
	}

	public bufferedCopyDemo(){
		BufferedReader bufr = null;
		BufferedWriter bufw = null;

		try{
			bufr = new BufferedReader(new FileReader("a.txt"));
			bufw = new BufferedWriter(new FileWriter("acopy.txt"));

			String line = null;
			while((line = bufr.readLine())!= null){
				bufw.write(line);
				bufw.newLine();
				bufw.flush();
			}
		}
		catch(IOException e){
			throw new RuntimeException("读写失败");
		}
		finally{
			try{
				if(bufw != null)
					bufw.close();
			}
			catch(IOException e){
				throw new RuntimeException("写入关闭失败");
			}
		}
	}
}


 

readLine方法的原理:无论是读一行,或者读取多个字符。其实最终都是在硬盘上一个一个读取。所以最终使用的还是read方法一次读一个的方法。
readLine每次从数据中读取一个字符,存到数组里,当读取到\n的时候,把所有已存的数组数据一起返回。

装饰设计模式:
当想要对已有的对象进行功能增强时,可以定义一个类,将已有对象传入,基于已有对象的功能,并提供加强功能。
那么自定义的该类就称为装饰类。
示例:

class Person{
	public void chifan(){
		System.out.println("吃饭");
	}
}

class SuperPerson{
	private Person p;
	SuperPerson(Person p){
		this.p = p;
	}
	public void superChifan(){
		System.out.println("开胃酒");
		p.chifan();
		System.out.println("甜点");
		System.out.println("来一根");
	}
}

class PersonDemo{
	public static void main(String[] args){
		//Person p= new Person();
		//p.chifan();
		SuperPerson sp = new SuperPerson(p);
		sp.superChifan();
	}
}

 

装饰设计模式特点:装饰类通常会通过构造方法接收被装饰的对象,并基于被装饰的对象的功能,提供更强的功能。

装饰和继承的区别:
装饰模式比继承要灵活,避免了继承体系的臃肿。而且降低了类与类之间的关系。
装饰类因为增强已有对象,具备的功能和已有的是相同的,知不是提供了更强功能,所以装饰类和被装饰类通常都属于一个体系中。

LineNumberReader:另一个装饰类,提供了行号的设置和获取:
setLineNumber(100);//将行号起始值设为100
getLineNumber();//返回当前行号。

字节流:
InputStream OutputStream

需求:想要操作图片数据,就要用到字节流。

class FileStream{
	public static void main(String[] args) throws IOException{
		System.out.println("Hello World!");
	}

	public static void writeFile() throws IOException{
		FileOutputStream fos = new FileOutputStream("fos.txt");

		fos.write("abcde".getBytes());//将字符串转换为字节。

		fos.close();
	}

	public static void readFile_1() throws IOException{
		FileInputStream fis = new FileInputStream("fos.txt");

		int ch = 0;

		while((ch=fis.read()) != -1){
			System.out.println((char)ch);
		}

		fis.close();
	}

	public static void readFile_2() throws IOException{
		FileInputStream fis = new FileInputSteam("fos.txt");

		byte[] buf = new byte[1024];
		int len = 0;
		while((len=fis.read(buf)) != -1){
			System.out.println(new String(buf,0,len));
		}
		fis.close();
	}

	public static void readFile_3() throws IOException{
		FileInputStream fis = new FileInputStream("fos.txt");
		//int num = fis.available();//获取文件大小(字节数)
		byte[] buf = new byte[fis.available()];//定义一个刚刚好的缓冲区,不用循环了,但是容量过大时会出现内存溢出,所以此方法要慎用
		fis.read(buf);
		System.out.println(new String(buf));

		fis.close();
	}
}


键盘输入流:System.in,返回InputStream对象。
*要使用字符流bufferedReader的readLine()方法获取键盘输入字节流的一行数据,应该怎样做?

class TransStreamDemo{
	public static void main(String[] args) throws IOException{
		InputStream in = System.in;//获取键盘录入对象

		InputStreamReader isr = inputStreamReader(in);//将字节流转换为字符流。

		BufferedReader bufr = new BufferedReader(isr);

		OutputStream out = System.out;
		OutputStreamWriter osw = new OutputStreamWriter(out,"UTF-8");//创建一个字符输出流。编码表为"UTF-8"
		BufferedWriter bufw = new BufferedWriter(osw);

		Sting line = null;
		while((line=bufr.readLine())!=null){
			if("over".equals(line)){//如果输入over,退出程序。
				break;
			}
			bufw.write(line.toUpperCase());
			bufw.newLine();
			bufw.flush();
		}

		bufr.close();
	}
}

 

流的基本规律:两个明确:

1,明确源和目的。
 源:输入流。InpusStream Reader
 目的:输出流。OutputStream Writer
2,操作的数据是否是纯文本。
 是,字符流。
 不是,字节流。
3,当体系明确后,再明确要使用哪个具体的对象。
 通过设备来进行区分。
 源设备:内存,硬盘,键盘。
 目的设备:内存,硬盘,控制台。

 

IO对Properties()的操作:

class SystemInfo{
	public static void main(String[] args) throws IOException{
		Properties prop = System.getProperties();//获得系统信息

		prop.list(new PrintStream("sysinfo.txt"));//list方法可以将信息输出到指定输出流。
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值