Java基础20--IO流

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xzm_rainbow/article/details/18307941

20-1,IO流-输入流-输出流

1,IO,即Input和Output的简写,表示输入输出。

IO流用于处理设备之间的设备传输,例如:内存,硬盘,优盘...

2,Java对数据的操作时通过流的方式。

数据从内存转移到硬盘称为输出,数据从硬盘转移到内存称为输入。

 

20-2,字节流-字符流

1,输入流和输出流是相对于内存设备而言的。

将外设中的数据读取到内存中,称为输入。

将内存中的数据写入到外设中,称为输出。

2,字符流的由来。

其实就是:字节流读取文字字节数据后,不直接操作而是先查指定的编码表,获取对应的文字,再对这个文字进行操作。简单说就是:字节流+编码表。

 

20-3,字符流-FileWriter

字符流负责字符的内存和硬盘之间的IO,中文汉字,英文字母都是字符。

1,IO流常用基类

    字节流的抽象基类:InputStream,OutputStream

    字符流的抽象基类:Reader,Writer

注意:由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。例如:InputStream的FileInputStream,Reader的子类FileReader,子类名的前缀就是该对象的功能。

2,需求:将一些文字存储到一个硬盘文件中。

记住:如果要操作文字数据,建议优先考虑字符流,而且要将数据从内存写到硬盘上,要使用字符流中的输出流,Writer。硬盘的数据基本体现是文件。希望可以找到一个可以操作文件的Writer,我们可以发现FileWriter可以满足需求。FileWriter没有空参构造函数,需要用参数指定写入哪个文件,或目的地路径。

public class FileWriterDemo {
	public static void main(String[] args) throws IOException {
		/*
		创建一个可以往文件中写入字符数据的字符输出流对象。
		既然是往一个文件中写入文字数据,那么在创建对象时,就必须明确该文件(指用于存储数据的地方)
		如果文件不存在,则会自动创建。
		如果文件存在,则会自动覆盖。
		*/
		FileWriter fw = new FileWriter("demo.txt");//在当前目录下创建
		//调用Writer对象中的write(String)方法,写入数据,其实是把数据写入到临时存储缓冲区中。
		//此时文件中没有数据。
		fw.write("abcde");
		//进行刷新,将数据直接写到目的地中,用flush()方法
		fw.flush();
		//关闭流,关闭资源,在关闭前会先调用flush刷新缓冲中的数据到目的地。
		fw.close();
		//fw.write("haha");//这时已经无法再写入,因为流已经关闭,抛出异常:java.io.IOException:Stream closed
	}
}

 

20-4,换行和续写

1,想要在输出的文件中进行换行操作,但每个操作系统的换行不一致怎么办?

可以用Properties获取系统信息,字段是line.separator。例如:

public static final StringLINE_SEPARATOR = System.getProperty("line.separator");

2,续写:之前的方法在输出完一个文件之后,不能再在这个文件后面继续写。想要实现续写操作,可以在FileWriter的构造函数中加入true。

FileWriter(String filename,Boolean append),加入已经有一个文本文件,并已经有数据abcde,并且关闭了这个输出流,那么如果是按照上述方法构造的,可以在关闭之后直接fw.writer("xixi");则可以实现在abcde后面直接续写xixi的功能。

 

20-5,IO的异常处理

开启一个IO流是需要消耗资源的,在用完这个流之后,我们应该将他关闭。但是在关闭之间如果程序抛出异常,会导致程序结束,但流仍未关闭,浪费了资源。所以对于可能抛出异常的IO操作,为了确保刘能关闭,要将关闭流的操作放到finally中,下面给出了IO异常通常的解决方法。

public class IOExceptionDemo {
	public static void main(String[] args) {
		FileWriter fw = null;
		try {
			/*
			抛出IO异常,不能在外面new,因为有异常。
			也不能在里面定义fw,否则finally块中会找不到fw变量,
			只能在外面定义,在里面new。
			*/
			fw = new FileWriter("k:\\demo.txt");
			fw.write("abcde");//
		} catch(IOException e) {
			System.out.println(e.toString());
		} finally {
			/*
			无论有没有异常,释放资源的fw.close()操作必须要做,
			将它放在finally中。
			如果new的时候抛出异常,则表明文件创建失败,fw为null。
			如果fw为null的话会抛出空指针异常,所以不为null时才能执行close()操作。
			*/
			if(fw != null){
				try {
					fw.close();
				} catch(IOException e) {
					//处理方法...code...
					throw new RuntimeException("关闭失败");
				}
			}
		}
	}
}

 

20-6,字符流-FileReader-读取方式1

他是一个字符读取流,用于将硬盘中的字符读取到内存中。

需求:读取一个文本文件,将读取到的字符打印到控制台。

public class FileReaderDemo {
	public static void main(String[] args) throws IOException {
		//1,创建读取字符数据的流对象
		//在创建读取流对象时,必须要明确被读取的文件,
		//一定要确定该文件是存在的,用一个读取流关联一个已存在文件
		FileReader fr = new FileReader("demo.txt");
		int ch = 0;
		while((ch = fr.read())!=-1) {
			System.out.println((char)ch);
		}
	}
}

用read方法读取字符,返回一个int型的值,这个值在0-65535之间,如果读到结尾处的后一个字符,则返回-1。

 

20-7,FileReader读取文件方式2

自定义数组缓冲区的方式。定义一个char[]数组,将读取的字符先读到这个数组中,所有的都读取完后,再利用String的构造函数String(char[] buf,int start,intlen)将数组缓冲区中的数据输出。这样效率会比单个字符输出高。

public class FileReaderDemo {
	public static void main(String[] args) throws IOException {
		FileReader fr = new FileReader("demo.txt");
		//使用read(char[])读取文本文件数据
		//先创建字符数组,相当于定义一个缓冲区
		char[] buf = new char[1024];//一般定义成1024的整数倍
		int len = 0;
		while((len = fr.read(buf)) != -1) {
			System.out.println(new String(buf,0,len));
		}
		fr.close();
	}
}

一般优先使用第二种方式,第一种方式每次只取一个,要取好多次,第二种先将所有的取出存在一个数组中,再从数组中一次性取出,效率要高。

猜你喜欢

转载自blog.csdn.net/xzm_rainbow/article/details/18307941