入门客AI创业平台(我带你入门,你带我飞行)
博文笔记

java基础---------IO字符流及综合练习题

创建时间:2014-11-24 投稿人: 浏览次数:1533


第一部分:字符流

字符流=字节流+编码表。

字符流是相对字节流来说的,由于一个中文字符占据了两个字节,因此用字节流读中文字符时,不如字符流处理中文效果好,因此在遇到文本情况时,能用字符流的最好用字符流。
1、编码表:

由字符及其对应的数值组成的一张表:

这里通过String类的构造函数及方法,来讲述编码表:


String (byte [] bytes,String charseName):通过制定的字符集解码字节数组
byte [] getBytes(String charseName):使用指定的字符集合把字符串编码为字节数组。

String s="你好";
byte [] bys1=s.getBytes("GBK");
byte [] bys2=s.getBytes();
byte [] bys3=s.getBytes("UTF-8");
System.out.println(Arrays.toString(bys))//打印数组


String s1=new String(bys1);
String s2=new String(by2."GBK");
String s3=new String(by3,"UTF-8");
System.out.println(s1);


由于我们使用的是默认的简体中文系统,因此默认使用的是GBK编码表。当我们默认,或者指定将一串中文字符串转为byte数组时,我们看到的是两个byte值的负数表示一个汉字字符。当我们指定用UTF-8编码表时,我们看到的就会是三个byte值的负数表示一个汉字字符。


2、转换流:
(1)、转换输出流的构造方法:

OutputStreamWriter(OutputStream out)//参数为字节流
OutputStreamWriter(OutputStream out,String charsetName)//参数为字节流加上指定编码表

import java.io.OutputStreamWriter;
import java.io.FileOutputStream;
import java.io.IOException;


class OutputStreamWriter{
	public static void main(String [] args)throws IOException {
		OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("a.txt"));
		OutputStreamWriter osw1=new OutputStreamWriter(new FileOutputStream("a.txt"),"UTF-8");//这里由于是UTF-8的编码,因此文本打开的时候,也需要选择UTF-8.
		osw.write("黑马");
		osw1.write("北京");
		osw.close();
		osw1.close();
	}
}


(2)、转换输入流的构造方法:
InputStreamReader(InputStream in)//参数为字节流
InputStreamReader(InputStream in,String charsetName)//参数为字节流和编码表


import java.io.InputStreamReader;
import java.io.FileInputStream;
import java.io.IOException;


class InputStreamReaderDemo{
	public static void main(String [] args)throws IOException{
		//这里也可以采用参数为字节流加上指定编码表。  
		InputStreamReader isr=InputStreamReader(new FileInputStream("b.txt"));
		int ch=0;
		while((ch=isr.read())!=-1){
			System.out.println((char)ch);
		}
		isr.close();
	}
}



(3)、OutputStreamWriter的常用方法方法:
1、public void write(int c)//写一个字符
2、public void write(char [] cbuf)//写一个字符数组
3、public void write(char[] cbuf,int off,int len)//写一个字符数组的一部分
4、public void write(String str)//写一个字符串
5、public void write(String str,int off,int len)//写一个字符串的一部分

import java.io.IOException;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;


class Demo{
	public static void main(String [] args)throws IOException{
		OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("c.txt"));
		osw.write("中");//write(int c);
		osw.write("中国");//write(String str);
		osw.flush();//刷新。一个字符等于两个字节。
		char [] chs={"a","b","c"};
		osw.write(chs);
		osw.close();
	}
}


close()和flush()区别
close():关闭流对象,但是先刷新一次缓冲区。关闭之后,流对象不可以继续再使用了。
flush():仅仅刷新缓冲区,刷新之后,流对象还可以继续使用。


(4)、InputStreamReader的常用方法:
int read():一次读取一个字符
int read(char [] chs):一次读取一个字符数组


import java.io.IOException;
import java.io.InputStreamReader;
import java.io.FileInputStream;
class InputStreamReaderDemo{
	public static void main(String [] args)throws IOException{
		InputStreamReader isr=new InputStreamReader(new FileInputStream("d.txt"));
		int len=0;//一次读取一个字节
		while((len=isr.read())!=-1){
			System.out.print(char(len));
		}
		isr.close();
	}<span style="white-space:pre">	</span>//一次读取一个数组
		/*InputStreamReader isr1=new InputStreamReader(new FileInputStream("e.txt"));
		char [] chs=new char[1024];
		int le=0;
		while((le=isr1.read(chs))!=-1){
			System.out.print(new String(chs,0,le));
		}
		isr.close();*/
}




3、字符流读写案例:
(1)、一次读取一个字符复制

import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.IOException;
class CopyDemo{
	public static void main(String [] args)throws IOException{
		InputStreamReader isr=new InputStreamReader(new FileInputStream("f.txt"));
		OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("g.txt"));
		int ch=0;
		//一次读一个字符,直到返回为-1
		while((ch=isr.read())!=-1){
			osw.write(ch);
		}
			//关闭转换流
			osw.close();
			isr.close();
	}
}




(2)、一次读取一个字符数组复制
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.IOException;
class CopyDemo1{
	public static void main(String [] args)throws IOException{
		OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("h.txt");
		InputStreamReader isr=new InputStreamReader(new FileInputStream("i.txt");
		//定义一个字符数组的长度
		char[] chs=new char[1024];
		int len=0;
		//一次读一个字符数组的长度,直到长度为-1
		while((len=isr.read(chs))!=-1){
			osw.write(chs,0,len);
		}
		//关闭转换流
		isr.close();
		osw.close();
	}
}


4、转换流的简化形式

由于我们使用本地编码表,不使用制定编码,又由于转换流名字较长,因此就有了转换流的子类
OutputStreamWriter=FileOutputStream+编码表
FileWriter = FileOutStream+编码表


InputStreamReader= FileInputStream+编码表
FileReader =FileInputStream + 编码表


一次读取一个字符

import java.io.IOException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
class CopyDemo3{
	public static void main(String [] args)throws IOException{
		FileReader fr=new FileReader("j.txt");
		FileWriter fw=new FileWriter("k.txt");
		int ch=0;
		while((ch=fr.read())!=-1){
			fw.write(ch);
		}
		fr.close();
		fw.close();
	}
}



一次读取一个字符数组
import java.io.IOException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
class CopyDemo4{
	public static void main(String [] args)throws IOException{
		FileReader fr=new FileReader("l.txt");
		FileWriter fw=new FileWriter("m.txt");
		char [] chs = new char[1024];
		int len=0;
		while((len=fr.read(chs))!=-1){
			fw.write(chs,0,len);
			fw.flush();
		}
		fr.close();
		fw.close();
	}
}


5、高级字符缓冲流

BufferedWriter(Writer out)

字符缓冲输出流构造函数.其参数为字符转换流。字符转换流构造函数的的参数为字节流。
import java.io.IOException;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.FileOutputStream;
class BufferedWriterDemo{
	public static void main(String [] args)throws IOException{
		BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("n.txt")));
		//上面的可以简化为:BufferedWriter bw=new BufferedWriter(new FileWriter("n.txt"));
		bw.write("北京黑马");
		bw.close();		
	}
}



BufferedReader(Reader in)
字符缓冲输入流
一次读取一个字符
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
class BufferedReaderDemo{
	public static void main(String [] args)throws IOException{
		BufferedReader br=new BufferedReader(new FileReader("o.txt"));
		int ch=0;
		while((ch=br.read())!=-1){
			System.out.print(char(ch));
		}
		br.close();
	}
}




一次读取一个字符数组
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
class BufferedReaderDemo{
	public static void main(String [] args)throws IOException{
		BufferedReader br=new BufferedReader(new FileReader("o.txt"));
		char [] chs =new char[1024];
		int len=0;
		while((len=br.read(chs))!=-1){
			System.out.print(new String(chs,0,len));
		}
		br.close();
	}
}




用缓冲流复制文件:
import java.io.IOException;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.bufferedWriter;
import java.io.FileWriter;
//一次读取一个字符数组复制文件
class BufferedCopyDemo{
	public static void main(String [] args)throws Exception{
		BufferedReader br=new BufferedReader(new FileReader("p.txt"));
		bufferedWriter bw=new BufferedWriter(new FileWriter("q.txt"));
		char [] chs=new char[1024];
		int len=0;
		while((len=br.read(chs))!=-1){
			bw.write(chs,0,len);
		}
		bw.close();
		br.close();
	}
}


一次读取一个字符复制文件

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


class BufferedCopyDemo{
	public static void main(String [] args)throws Exception{
		BufferedReader br=new BufferedReader(new FileReader("p.txt"));
		bufferedWriter bw=new BufferedWriter(new FileWriter("q.txt"));
		int ch=0;
		while((ch=br.read())!=-1){
			bw.write(ch);
		}
		bw.close();
		br.close();
	}
}



6、字符缓冲流的特殊方法:
BufferedWriter:  public void newLine():根据系统来决定换行符
BufferedReader: public String readLine():一次读取一行.包含了改行的字符串内容,不包含终止符。如果读不到,返回null。


import java.io.BufferedReader;
import java.io.FileReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
class BufferedSpecialDemo{
	public static void main(String [] args){
		BufferedWriter bw =new BufferedWriter(new FileWriter("r.txt"));		
		 for(int x=0;x<10;x++){
			bw.write("黑马"+x);
			//起到换行效果
			bw.write("
");
			//也起到换行效果
			bw.newLine();
		}
		
			bw.close();
	}
	public static void read() throws IOException{
		BufferedReader br=new BufferedReader(new FileReader("s.txt"));
			String line=null;
			while( (line=br.readLine()!=null){
				System.out.println(line);	
			}
			br.close();
			
		
	}
}




特殊功能复制文件:一次读一行
import java.io.IOException;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.BufferedReader;
import java.io.FileReader;
class ReaderLineCopy{
	public static void main(String [] args) throws IOException{
		BufferedReader br=new BufferedReader(new FileReader("t.txt"));
		BufferedWriter bw = new BufferedWriter(new FileWriter("u.txt"));
		String line=null;
		while((line=br.readLine())!=null){//一次读取一行
			bw.write(line);
			bw.newLine();
			bw.flush();
		}
		bw.close();
		br.close();
		
	}
}


第二部分:练习题:


1、将ArrayList集合中的字符串数据存储到文本文件


分析:首先我们应该考虑到将数据存储到文本,这个数据是从哪里来的?毫无疑问,数据是从ArrayList集合中遍历得到的,那么我们遍历得到的数据,该如何存储到文本文件呢?方式有很多有字节流,也有字符流,这里由于是文本文件,因此我们选择的是字符流。在遍历集合的过程中,将获得的每一个集合元素,写到文本中。


import java.io.IOException;
import java.util.ArrayList;
import java.io.FileWriter;
import java.io.BufferedWriter;
class ArrayListDemo{
	public static void main(String [] args)throws IOException{
		//创建一个ArrayList集合
		ArrayList<String> list= new ArrayList<String>();
		//创建一个字符缓冲流
		BufferedWriter bw=new BufferedWriter(new FileWriter("v.txt"));
		//为集合添加数据
		list.add("hello");
		list.add("heima");
		list.add("beijing");
		//遍历集合
		for(String s:list){
		//将遍历获得的集合元素,写到文本中
			bw.write(s);
			bw.newLine();
			bw.flush();
		}
		//关闭字符缓冲流
		bw.close();
	}
}



2、从文本文件中读取数据(每一行为一个字符串数据)到集合中,并遍历集合


分析:数据是我们从文本文件中获得的,这就要用到字符流或者字节流,这里我们选择了字符缓冲流来读取文件数据,由于要求每一行为一个字符串,因此我们选择的是字符缓冲流中的readLine().在我们每读一行时,通过集合的add方法,将改行的数据添加到集合。然后遍历该集合,就能得到答案。


import java.io.IOException;
import java.util.ArrayList;
import java.io.BufferedReader;
import java.io.FileReader;
class ReadText{
	public static void main(String [] args)throws IOException{
		//创建字符缓冲流
		BufferedReader br=new BufferedReader(new FileReader("w.txt"));
		//创建集合
		ArrayList<String> list=new ArrayList<String>();
		//定义一个String类型的变量
		String line=null;
		//调用字符缓冲流的特有方法readLine()来读取数据
		while((line=br.readLine())!=null){
		//添加数据到集合
			list.add(line);
		}
		//关闭字符缓冲流
		br.close();
		//遍历集合
		for(String s:list){
			System.out.println(s);
		}
	}
}



3、复制单级文件夹


第一步:复制单级文件夹的时,首先先不考虑里面的文件,而是考虑需要复制到的盘符里是否有该文件夹,如果有,则不用创建,如果没有,则要另外创建。
第二步:将需要复制的文件夹中的文件一一遍历出来,由于是单级目录,所以文件夹下都是文件,所以遍历出来一个,就可以通过复制方法,将其复制到目标文件夹一个。
第三步:但是在复制之前,就是虽然目标文件夹我们在第一步就已经创建或者已经有了,但是我们知道在使用复制功能时,需要传递的是如同d:\t.txt;e:\y.txt这样的文件路径名,但是我们的目标文件地只有文件夹,还没有文件名的全路径,因此需要通过File的另一个构造函数:FIle file =new File(File file,String name);这里面的参数前者是文件夹的路径,后者是文件的文件名,因此这个封装的就是文件全路径名。这个时候就可以赋值了。这里面的name可以再第二步的时候,通过getName()方法,从需要复制的文件身上得到。


import java.io.BufferedInputStream;
import java.io.BufferedOutputStream; 
import java.io.IOException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputSteram;
class CopyFolder{
	public static void main(String [] args)throws IOException{
		File src=new File("d:\x");//封装源文件夹目录
		File dest=new File("e:\y");//封装目的地文件夹目录
		if(!dest.exists()){//如果目标文件夹不存在,就创建一个
			dest.mkdir();
		}
		File [] fileArray=src.listFiles();//将源文件的每个对象封装成一个对象
		for(File file:fileArray){//得到每一个对象
			String name=file.getName();//获得每个对象的名字
			File newFile=new File(dest,name);//创建目的地文件夹目录对象
			copy(file,newFile);//复制到目的地文件夹
		}
				
	}<span style="white-space:pre">	</span>//将复制方法封装成独立的方法
		public static void copy(File file, File newFile)throws IOException{
		BufferedInputStream bis=new BufferedInputStream(new FileInputStream(file));
		BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(newFile));
		byte [] bys=new byte[1024];
		int len=0;
		while((len=bis.read(bys))!=-1){
			bos.write(bys,0,len);
		}
		bis.close();
		bos.close();
	}
}



4、复制单级文件夹中指定文件并修改文件后缀名


分析:这里在复制的过程中,同上面一题的步骤相同,都是先封装文件源目录,和文件目的地目录。如果文件目的地文件夹没有就创建。


第二步是将源文件中需要复制的文件转为File[],这一步是通过文件过滤器来实现的。在上面那题复制文件夹时,我们不需要通过文件过滤器来选择需要复制哪些文件,而是直接一窝端。文件过滤器可以将不需要复制的文件排除在外。这样需要复制的文件就转为File [];


第三步,遍历需要复制的文件数组,然后一个一个地复制到目标文件夹。


第四步,虽然复制到了目标文件夹,但是文件名没有改,这时就可以再次将目标文件夹转为File[] 数组,遍历获得刚刚复制过来的文件。


第五步,再次遍历这个File[]数组,里面的每个刚刚复制过来的文件都是File类型,因此调用getName()可以得到该文件的名称,获取的这个名称仅仅是个字符串,而不是这个文件本身,该文件的名称是个字符串类型,因此可以通过字符串的替换功能,将需要改名后的名字替换先前的名字,现在这个字符串被替换成了我们需要的名字,但是如何才能把这个字符串重新赋给文件呢?这个时候可以通过File的构造函数File(File dir,String name);参数的前者是路径,后者是文件名,这样就相当建了一个新的File对象,新的文件名和复制过来后的路径组合成了新的文件,然后再将旧的我们在这一步开始就遍历获得的那个文件名,也就是从源文件地复制过来的文件,更名为新的File对象即可。


import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;


class ModificationDemo{
	public static void main(String [] args)throws IOException{
		//封装源文件夹目录
		File srcFile=new File("e:\heima");
		//封装目的文件夹目录
		File destFile =new File("d:\chuanzhi");
		if(!destFile.exists()){
			//如果没有文件夹,将会建一个文件夹。但是destFile从始至终指向的都是d:chuanzhi这个文件夹。尽管没有这个文件夹,但是依然指向的是这个地方。这里只是创建了这个文件夹而已。
			destFile.mkdir();
		}


		//将需要复制的文件过滤出来,通过文件过滤器
		File [] fileArray=srcFile.listFiles(new FilenameFilter(){
		public boolean accept(File dir,String name){
			return new File(dir,name).isFile()&&name.endsWith(".jpg");
		}
		});


		//将需要复制的文件遍历
		for(File file:fileArray){
			String name=file.getName();
			File newFile=new File(destFile,name);
			copy(file,newFile);
		}
		


		File[] destFileArray=destFile.listFiles();
		for(File dest:destFileArray){
			String name=dest.getName();
			String newName=name.replace(".jpg",".jpeg");
			File newFile =new File(destFile,newName);
			dest.renameTo(newFile);
			
		}
	}


		//封装的复制方法
	public static void copy(File file, File newFile)throws IOException{
		BufferedInputStream bis=new BufferedInputStream(new FileInputStream(file));
		BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(newFile));
		byte [] bys=new byte[1024];
		int len=0;
		while((len=bis.read(bys))!=-1){
			bos.write(bys,0,len);
		}
		bis.close();
		bos.close();
	}
}


5、复制多层文件夹


分析:复制多层文件夹,可以建两个方法,一个方法时复制文件,一个方法时复制文件夹
在复制文件夹时,首先要封装该文件夹,封装后,通过该File的对象,来调用isDirectory()判断,这个对象是文件还是文件夹。(1)如果是文件的话,就将目的地目录和通过该文件对象调用的getName()作为参数,来创建一个新File。这个新File就是目标文件所要复制到的地方。(2)如果对象是文件夹的话,通过文件夹对象来调用方法,获得其名称,然后和目标文件夹拼接成新的目的地文件夹。然后创建。这时再将对象转成File类型的数组,通过遍历该对象,就可以获取对象文件夹下的内容,然后重复调用isDirectory()判断是文件还是文件夹。

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


class CopyFolderDemo{
	public static void main(String [] args) throws IOException{
		File srcFolder=new File("d:\资料\day03");
		File destFolder=new File("e:\");
		copyFolder(srcFolder,destFolder);




	}//复制文件夹的方法
	public static void copyFolder(File srcFolder,File destFolder) throws IOException{
		//判断对象是不是文件夹
		if(srcFolder.isDirectory()){
			//如果是文件夹,就通过File的构造方法,将目的地和源文件夹名作为参数,构造新的文件夹。
			File newdestFolder=new File(destFolder,srcFolder.getName());
			//在目的地创建该新的文件夹
			newdestFolder.mkdir();
			//将源文件夹对象的内容作为对象,存入一个File类型的数组。
			File[] fileArray=srcFolder.listFiles();
			//遍历该数组,得到的是该源文件夹内容的对象
			for( File file:fileArray){
			//重复复制文件夹,判断其是文件夹还是文件。
				copyFolder(file,newdestFolder);
			}
		}else{//如果是文件对象,就通过File的带参构造方法,在目的文件夹中创建对象。其参数分别为目的地文件夹路径,源文件名称。
			File newFile=new File(destFolder,srcFolder.getName());
			//复制该源文件
			copy(srcFolder,newFile);
		}
	}
		
		//复制文件的方法
	public static void copy(File file, File newFile)throws IOException{
		BufferedInputStream bis=new BufferedInputStream(new FileInputStream(file));
		BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(newFile));
		byte [] bys=new byte[1024];
		int len=0;
		while((len=bis.read(bys))!=-1){
			bos.write(bys,0,len);
		}
		bis.close();
		bos.close();
	}
}




声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。
  • 上一篇:没有了
  • 下一篇:没有了
未上传头像