@w460461339
2016-11-16T07:08:19.000000Z
字数 10379
阅读 852
Java基础
今天学习的是字符流。在学习字符流之前,我们还是把File和字节流再理一遍。
File类
其中储存的是文件或者文件夹的抽象路径名。即,无论这个文件存在不存在,都可以写出来。
通过它,可以创建文件/文件夹,获取类型,获取名称,获取文件夹内所有的文件等等操作。总而言之,它是针对文件这个整体进行操作,不涉及文件具体储存内容的修改。
字节流
字节流有两种,输入流和输出流。
输出流:
OutputStream(抽象类)→FileOutputStream(实现子类)或BufferedOutputStream(高速流)
输入流:
InputStream(抽象类)→FileInputStream(实现子类)或者BufferedInputStream(高速流)
构造时,利用File(包装好的文件路径)或者String(字符串表示的文件路径)都行。
字节流能够实现对文件内部数据的操作。注意,此时就没文件夹什么事了,全部都是对文件的。比如往文件内部写入数据,从文件内部读出数据,将文件A的数据复制给文件B等等。所以,字节流是针对文件内部数据的。
字符流=字节流+编码表
因此,最基本的字符流是通过字节流与制定编码表得到的。
按照前文的定义,字符流=字节流+编码表。字符转换流就是负责这一操作的。同理,这也有字符输入流和字符输出流之分。
Writer(抽象类)→OutputStreamWriter(具体实现类)
OutputStreamWriter的构造方法需要一个字节输出流OutputStream的对象以及用String表示指定的编码表,比如“GBK”,"UTF-8"等等。
其中,可以通过write方法往文件中写入数据
void write(int c) 等于 void write(char c);
void write(String st);
void write(char[] chas,int start,int off);
Reader(抽象类)→InputStreamWriter(具体实现类)
InputStreamWriter的构造方法需要一个字节输入流InputStream的对象以及用String表示指定的编码表,比如“GBK”,"UTF-8"等等。
其中,可以通过read方法来读取。read方法有两种形式
int read();//一次读取一个字符
int read(char[] chs);//一次读取一个字符数组
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class ZifuStream {
public static void main(String[] args)throws IOException {
//指明读取和写入都是按照GBK的编码表来读入和写入
InputStreamReader isr=new InputStreamReader(
new FileInputStream("a.txt"), "GBK");
OutputStreamWriter osw=new OutputStreamWriter(
new FileOutputStream("b.txt"), "GBK");
//利用一次读取一个字符数组来读取
int len=0;
char[] chs=new char[1024];
while((len=isr.read(chs))!=-1){
osw.write(chs, 0, len);
}
osw.flush();//刷新后数据才进文件
osw.close();//关闭时自动刷新
isr.close();
}
}
之前那个字符转化流在可以自己指定编码表的同时,名字太长了,用起来不方便。因此诞生了简化的字符流。
简化字符输出流:
Writer(抽象类)→OutputStreamWriter(具体实现类)→FileWriter(具体实现类)
简化字符输入流:
Reader(抽象类)→InputStreamWriter(具体实现类)→FileReader(具体实现类)
这两个类除了构造函数可以直接利用String类型或者File类型来读取文件,并且采用系统默认的编码表以外,和他们的父类没有区别。
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class MyFileWriter_Reader {
public static void main(String[] args) throws IOException {
FileReader isr=new FileReader("a.txt");//默认编码表
FileWriter osw=new FileWriter("b.txt");
int len=0;
char[] chs=new char[1024];
while((len=isr.read(chs))!=-1){
osw.write(chs, 0, len);
}
osw.flush();
osw.close();
isr.close();
}
}
高效字符输入流:
Reader(抽象类)→BufferedReader(实现类)
其构造方法需要用Reader的具体实现类作为参数
高效字符输出流:
Writer(抽象类)→BufferedWriter(实现类)
其构造方法需要用Writer的具体实现类作为参数
其输入和输出的基本用法和之前的基本流完全一样,下面演示其特有用法
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class BufferedDemo {
public static void main(String[] args) throws IOException{
//Reader与Writer的具体实现类作为构造函数的参数
BufferedReader br=new BufferedReader(
new FileReader("a.txt"));
BufferedWriter bw=new BufferedWriter(
new FileWriter("b.txt"));
//初始化字符串为null
String st=null;
//reanLine按行读入,遇到换行符停止,因此不会读入换行符。
//在复制时需要自行写入
//读到末尾时,返回null
while((st=br.readLine())!=null){
bw.write(st);//按行写入
bw.newLine();//人工换行
bw.flush();//刷新
}
bw.close();//关了
br.close();//关了
}
}
分析:
A:构建ArrayList,存入数据
B:利用字符流输出。构建BufferedWriter高效字符输出流。
C:遍历ArrayList,将每次结果输出到txt文件中。
D:利用BufferedWriter的newLine,换行
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
public class CopyArraytoTxtDemo {
public static void main(String[] args) throws IOException{
//添加数据
ArrayList<String> myarray=new ArrayList<String>();
myarray.add("hello");
myarray.add("world");
myarray.add("java");
//两种输出方式,FileWriter基本输出流
//FileWriter fw=new FileWriter(new File("c.txt"));
//BufferedWriter高效输出流
BufferedWriter bw=new BufferedWriter(new FileWriter(new File("d.txt")));
//遍历
for(String s:myarray){
bw.write(s);
bw.newLine();//换行
bw.flush();//刷新
}
bw.close();//关闭
}
}
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
public class CopyTxttoArrayDemo {
/**
* 分析:
* A:利用BufferedReader按行读入数据
* B:将数据转换为String
* C:存入ArrayList
* D:遍历,在控制台显示
*/
public static void main(String[] args)throws IOException {
// TODO Auto-generated method stub
BufferedReader br=new BufferedReader(
new FileReader(new File("a.txt")));
ArrayList<String> myarray=new ArrayList<String>();
String s=null;
while((s=br.readLine())!=null){
myarray.add(s);
}
for(String st:myarray){
System.out.println(st);
}
}
}
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class CopyFoldertoFolder {
/**
* @param args
* 分析:
* 源文件夹:aaa
* 目标文件夹:bbb
* A:单级文件夹,获取该文件夹下所有文件
* B:判断目标文件夹是否存在,否,创建
* C:将所有文件写入目标文件夹中
*/
public static void main(String[] args) throws IOException{
// TODO Auto-generated method stub
//封装源文件夹下的所有文件
File myFile=new File("aaa");
File[] myFileList=myFile.listFiles();
//封装目标文件夹
File aimFile=new File("bbb");
if(!aimFile.exists()){
aimFile.mkdir();
}
//复制文件进另外一个文件
for(File fl:myFileList){
copyFile(fl,aimFile);
}
}
private static void copyFile(File fl, File aimFile) throws IOException{
// 源文件的表示,直接用fl来构建就好
BufferedReader br=new BufferedReader(new FileReader(fl));
//目标文件,必须用File+String的方式构建目标文件夹下的目标文件。否则,就不是复制到目标文件夹下了。
BufferedWriter bw=new BufferedWriter(
new FileWriter(new File(aimFile,fl.getName())));
String st=null;
while((st=br.readLine())!=null){
bw.write(st);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
}
}
以最开始的为例子:
1:"aaa"文件夹和"d:\"进入copyFolders
2:判断“aaa”是不是文件夹
3:是文件夹。
|----3.1:首先在d:\ 下创建aaa文件夹
|----3.2:遍历原来的aaa文件夹,得到其中每一个内容 fl。
|----3.3:把 fl 和 d:\aaa 传入copyFolders,开始递归。回到2
4:不是文件夹(假设aaa不是文件夹)
|----4.1:在d:\ 下创建aaa同名空文件。
|----4.2:将源文件“aaa”复制到d:\ 下的aaa空文件中
package exercise;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyFolderstoFolders {
/**
* 需求:将源文件夹下所有内容复制到目标文件夹下
* 分析:
* A:封装源文件夹,以及目标文件夹
* B:判断源是否是文件夹
* C1:是:封装文件夹下所有内容,遍历,回到B
* C2:否:复制文件到另一文件夹中
*/
public static void main(String[] args) throws IOException{
// 封装源文件夹与目标文件夹
File srcFolder=new File("aaa");
File aimFolder=new File("d:\\");
copyFolders(srcFolder,aimFolder);
}
private static void copyFolders(File srcFolder, File aimFolder) throws IOException{
//注意,先判断,后封装!!!!
//先判断源文件是否是文件夹
if(srcFolder.isDirectory()){
//是文件夹,在目标位置创造同名文件夹
File destFile=new File(aimFolder,srcFolder.getName());
destFile.mkdir();
//封装其下所有内容
File[] srcFileList=srcFolder.listFiles();
for(File fl:srcFileList){
//遍历,递归
copyFolders(fl,destFile);
}
}else{
//不是文件夹
//先在目标文件夹下创建同名文件
File destFile=new File(aimFolder,srcFolder.getName());
//文件对文件的复制
copy(srcFolder,destFile);
}
}
//复制文件
private static void copy(File srcFolder, File destFile)throws IOException {
BufferedInputStream bis=new BufferedInputStream(
new FileInputStream(srcFolder));
BufferedOutputStream bos=new BufferedOutputStream(
new FileOutputStream(destFile));
int len=0;
byte[] bys=new byte[1024];
while((len=bis.read(bys))!=-1){
bos.write(bys, 0, len);
}
bos.close();
bis.close();
}
}
package exercise;
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;
public class CopyandRename {
/**
* @param args
* 需求:
* 将单级文件夹bbb中的.java文件复制到和bbb同目录下的ccc文件夹中
* 并改名为a3.jad,b3.jad.
*分析:
* A:获取bbb中所有.java文件
* B:将获取到的.java文件复制到ccc下
* C:在ccc下对文件进行改名
* PS:若是不复制之间改名到CCC下的话,相当于把bbb中文件剪
* 切到CCC中在改名。
*/
public static void main(String[] args)throws IOException {
//封装源文件夹和目标文件夹
File srcFolder=new File("bbb");
File destFolder=new File("ccc");
//判断目标文件夹是否存在
if(!destFolder.exists()){
destFolder.mkdir();
}
//获取所有以.java结尾的文件
File[] srcFileList=srcFolder.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
// 判断是否是文件,以及判断是否以.java结尾
return new File(dir,name).isFile()
&& name.endsWith(".java");
}
});
//复制到ccc中
for(File fl:srcFileList){
File destFile=new File(destFolder,fl.getName());
copyFile(fl,destFile);
}
//获取ccc中所有文件
File[] destFileList=destFolder.listFiles();
//改名
for(File fl:destFileList){
String oldname=fl.getName();
String newName=oldname.replaceAll(".java", ".jad");
fl.renameTo(new File(destFolder,newName));
}
}
//复制文件
private static void copyFile(File fl, File destFile)throws IOException {
BufferedInputStream bis=new BufferedInputStream(
new FileInputStream(fl));
BufferedOutputStream bos=new BufferedOutputStream(
new FileOutputStream(destFile));
int len=0;
byte[] bys=new byte[1024];
while((len=bis.read(bys))!=-1){
bos.write(bys, 0, len);
}
bos.close();
bis.close();
}
}
package exercise;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;
//创建学生类
class Student{
private String name;
private int chinese;
private int math;
private int english;
public Student(String name, int chinese, int math, int english) {
super();
this.name = name;
this.chinese = chinese;
this.math = math;
this.english = english;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getChinese() {
return chinese;
}
public void setChinese(int chinese) {
this.chinese = chinese;
}
public int getMath() {
return math;
}
public void setMath(int math) {
this.math = math;
}
public int getEnglish() {
return english;
}
public void setEnglish(int english) {
this.english = english;
}
public int getSum(){
return chinese+math+english;
}
}
public class InsertStuentScoreinOder {
/**
* 需求:输入5个学生成绩,按照其总分,语文,数学,外语,姓名的顺序排序
* 分析:
* A:构建学生类,能够获得其总分,语数外姓名等信息
* B:利用TreeSet存储,自定义comparator
* C:输出到txt文件中
* @throws IOException
*/
public static void main(String[] args) throws IOException {
//用来存储学生信息,自定义比较器
TreeSet<Student> st=new TreeSet<Student>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
//o2在前表示从大到小
int r1=o2.getSum()-o1.getSum();
int r2= r1==0?o2.getChinese()-o1.getChinese():r1;
int r3= r2==0?o2.getMath()-o1.getMath():r2;
int r4= r3==0?o2.getEnglish()-o1.getEnglish():r3;
int r5= r4==0?o2.getName().compareTo(o1.getName()):r4;
return r5;
}
});
//读入数据,注意Scanner要在内部定义,不然in.nextLine在循环
//第二次会因为读入换行符而失效
for(int i=1;i<=3;i++){
Scanner in =new Scanner(System.in);
System.out.println("name");
String name=in.nextLine();
System.out.println("chinese");
int chinese=in.nextInt();
System.out.println("math");
int math=in.nextInt();
System.out.println("english");
int english=in.nextInt();
Student s=new Student(name,chinese,math,english);
st.add(s);
}
//封装目标文件
File score=new File("Student.txt");
//创建输出流
BufferedWriter bw=new BufferedWriter(
new FileWriter(score));
for(Student stu:st){
//构造字符串
StringBuilder sbu=new StringBuilder();
sbu.append(stu.getName()).append(" C:").append(stu.getChinese()).append(" M:").append(stu.getMath()).append(" E:").append(stu.getEnglish());
String line=sbu.toString();
//输出
bw.write(line);
bw.newLine();
bw.flush();
}
//关闭
bw.close();
}
}