您的位置:首页 > 职场人生

黑马程序员————java基础---------IO字符流及综合练习题

2014-11-24 21:39 441 查看
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

第一部分:字符流

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

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

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("\r\n");
//也起到换行效果
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();
}
}



------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐