JAVA 基础知识整理-17 字符转换流 InputStreamReader,OutpuStreamWriter,FileReader, FileWriter

1. 输入转换流 InputStreamReader
InputStreamReader是从字节流到字符流的桥:它读取字节,并使用指定的charset将其解码为字符 。 它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集。
每个调用InputStreamReader的read()方法之一可能会导致从底层字节输入流读取一个或多个字节。 为了使字节有效地转换为字符,可以从底层流读取比满足当前读取操作所需的更多字节。

构造方法:

InputStreamReader(InputStream in)
创建一个使用默认字符集的InputStreamReader。
InputStreamReader(InputStream in, Charset cs)
创建一个使用给定字符集的InputStreamReader。
InputStreamReader(InputStream in, CharsetDecoder dec)
创建一个使用给定字符集解码器的InputStreamReader。
InputStreamReader(InputStream in, String charsetName)
创建一个使用命名字符集的InputStreamReader。

方法:
void close()
关闭流并释放与之相关联的任何系统资源。
String getEncoding()
返回此流使用的字符编码的名称。
int read()
读一个字符
int read(char[] cbuf, int offset, int length)
将字符读入数组的一部分。
boolean ready()
告诉这个流是否准备好被读取。

2. 输出转换流OutputStreamWriter
OutputStreamWriter是字符的桥梁流以字节流:向其写入的字符编码成使用指定的字节charset 。 它使用的字符集可以由名称指定,也可以被明确指定,或者可以接受平台的默认字符集。

构造方法 :

OutputStreamWriter(OutputStream out)
创建一个使用默认字符编码的OutputStreamWriter。
OutputStreamWriter(OutputStream out, Charset cs)
创建一个使用给定字符集的OutputStreamWriter。
OutputStreamWriter(OutputStream out, CharsetEncoder enc)
创建一个使用给定字符集编码器的OutputStreamWriter。
OutputStreamWriter(OutputStream out, String charsetName)
创建一个使用命名字符集的OutputStreamWriter。

方法:
void close()
关闭流,先刷新。
void flush()
刷新流。
String getEncoding()
返回此流使用的字符编码的名称。
void write(char[] cbuf, int off, int len)
写入字符数组的一部分。
void write(int c)
写一个字符
void write(String str, int off, int len)
写一个字符串的一部分。

复制文件案例1:

public class CodeCompilerDemo {
	public static void main(String[] args) throws IOException {
		byte[] bys = "hello".getBytes();
		for(byte b:bys){
			System.out.println((char)b);
		}
		
		InputStreamReader isr = new InputStreamReader(new FileInputStream("b.txt"));
		OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("a.txt"));
		int i;
		while((i=isr.read())!=-1){
			osw.write(i);
		}
		isr.close();
		osw.close();
	}
	
}

复制文件案例2:

public class CodeCompilerDemo1 {
	public static void main(String[] args) throws IOException {
		InputStreamReader isr = new InputStreamReader(new FileInputStream("b.txt"));
		OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("a.txt"));
		char[] c= new char[1024];
		int len = 0;
		while((len = isr.read(c))!=-1){
			osw.write(c, 0, len);
		}
		isr.close();
		osw.close();
	}
}

3.便利字符输入流FileReader
阅读字符文件的便利课。 该类的构造函数假定默认字符编码和默认字节缓冲区大小是适当的。 要自己指定这些值,请在FileInputStream上构造一个InputStreamReader。
FileReader是用于读取字符流。 要读取原始字节流,请考虑使用FileInputStream 。

构造方法 :

FileReader(File file)
创建一个新的 FileReader ,给出 File读取。
FileReader(FileDescriptor fd)
创建一个新的 FileReader ,给定 FileDescriptor读取。
FileReader(String fileName)
创建一个新的 FileReader ,给定要读取的文件的名称。

4. 便利字符输出流FileWriter
方便课写字符文件。 该类的构造函数假定默认字符编码和默认字节缓冲区大小是可以接受的。 要自己指定这些值,请在FileOutputStream上构造一个OutputStreamWriter。
文件是否可用或可能被创建取决于底层平台。 特别是某些平台允许一次只能打开一个文件来写入一个FileWriter (或其他文件写入对象)。 在这种情况下,如果所涉及的文件已经打开,则此类中的构造函数将失败。

构造方法:

FileWriter(File file)
给一个File对象构造一个FileWriter对象。
FileWriter(File file, boolean append)
给一个File对象构造一个FileWriter对象。
FileWriter(FileDescriptor fd)
构造与文件描述符关联的FileWriter对象。
FileWriter(String fileName)
构造一个给定文件名的FileWriter对象。
FileWriter(String fileName, boolean append)
构造一个FileWriter对象,给出一个带有布尔值的文件名,表示是否附加写入的数据。

复制文件案例1:

public class FileReaderWriterDemo {
	public static void main(String[] args) throws IOException {
		FileReader fd = new FileReader(new File("a.txt"));
		FileWriter fw = new FileWriter(new File("b.txt"),true);
		int c;
		while((c= fd.read())!=-1){
			fw.write(c);
		}
		fd.close();
		fw.close();
	}
}

复制文件案例2:

public class FileReaderWriterDemo {
	public static void main(String[] args) throws IOException {
		FileReader fd = new FileReader(new File("a.txt"));
		FileWriter fw = new FileWriter(new File("b.txt"),true);
		char[] c= new char[1024];
		int len;
		while((len = fd.read(c))!=-1){
			fw.write(c,0,len);
		}
		fd.close();
		fw.close();
	}
}

5. 字符缓冲输入流BufferedReader

从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取。
可以指定缓冲区大小,或者可以使用默认大小。 默认值足够大,可用于大多数用途。

构造方法 :

BufferedReader(Reader in)
创建使用默认大小的输入缓冲区的缓冲字符输入流。
BufferedReader(Reader in, int sz)
创建使用指定大小的输入缓冲区的缓冲字符输入流

方法:

void close()
关闭流并释放与之相关联的任何系统资源。
Stream lines()
返回一个 Stream ,其元素是从这个 BufferedReader读取的行。
void mark(int readAheadLimit)
标记流中的当前位置。
boolean markSupported()
告诉这个流是否支持mark()操作。
int read()
读一个字符
int read(char[] cbuf, int off, int len)
将字符读入数组的一部分。
String readLine()
读一行文字。
boolean ready()
告诉这个流是否准备好被读取。
void reset()
将流重置为最近的标记。
long skip(long n)
跳过字符

6.字符缓冲输出流BufferedWriter

将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入。
可以指定缓冲区大小,或者可以接受默认大小。 默认值足够大,可用于大多数用途。

构造方法 :

BufferedWriter(Writer out)
创建使用默认大小的输出缓冲区的缓冲字符输出流。
BufferedWriter(Writer out, int sz)
创建一个新的缓冲字符输出流,使用给定大小的输出缓冲区。

方法:

void close()
关闭流,先刷新。
void flush()
刷新流。
void newLine()
写一行行分隔符。
void write(char[] cbuf, int off, int len)
写入字符数组的一部分。
void write(int c)
写一个字符
void write(String s, int off, int len)
写一个字符串的一部分。

7. IO流的结构
在这里插入图片描述在这里插入图片描述

案例1缓冲字符流的3种方法复制文件:

public class BufferedWriterReaderDemo {
	
	public static void main(String[] args) throws IOException {
		//copy1();
		//copy2();
		copy3();		
	}
	
	private static void copy1() throws IOException {
		//读一个写一个
		BufferedReader br = new BufferedReader(new FileReader("a.txt"));
		BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));
		int c = 0;
		while((c=br.read())!=-1){
			bw.write(c);
		}
		 br.close();
		 bw.close();
	}
	
	private static void copy2() throws IOException {
		BufferedReader br = new BufferedReader(new FileReader("a.txt"));
		BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));
		char[] c= new char[1024];
		int len;
		while((len=br.read(c))!=-1){
			bw.write(c,0,len);
			bw.flush();
		}
		 br.close();
		 bw.close();
		
	}

	private static void copy3() throws IOException {
		BufferedReader br = new BufferedReader(new FileReader("a.txt"));
		BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));
		String line = null;
		while((line = br.readLine())!=null){
			bw.write(line);
			bw.newLine();
			bw.flush();
		}
		 br.close();
		 bw.close();
		
	}
	
}

例2将集合中的字符串写入指定文件中:

public class IoWithArrayList {
 public static void main(String[] args) throws IOException {
  ArrayList<String> arrstr = new ArrayList<String>();
  arrstr.add("hello");
  arrstr.add("world");
  arrstr.add("java");
  writeIntoFiles1( arrstr);
 }
 public static void writeIntoFiles(ArrayList<String> arrstr) throws IOException{
  BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt"));  
  for(String s:arrstr){
   bw.write(s);
   bw.newLine();
  }  
  bw.close();
 }
 
 public static void writeIntoFiles1(ArrayList<String> arrstr) throws IOException{
  FileWriter fw = new FileWriter("a.txt");
  for(String s:arrstr){
   fw.write(s+"\r\n");
  }
  fw.close();
 }
}

案例3想ArrayList中添加文本文件中的内容:

public class WriteStringIntoColleaction {
 public static void main(String[] args) throws IOException {
  String filepath = "a.txt";
  readIntoCollection(filepath);
 }
 
 public static void readIntoCollection(String filename) throws IOException{
  BufferedReader fd = new BufferedReader(new FileReader(filename));
  ArrayList<String> arrstr = new ArrayList<String>();
  String s;
  while((s=fd.readLine())!=null){
   arrstr.add(s);
  }
  
  fd.close();
  System.out.println(arrstr.toString());
 }
 
}

案例4读取任意一行内容:

public class WriteStringIntoColleaction {
 public static void main(String[] args) throws IOException {
  String filepath = "a.txt";
  readIntoCollection1(filepath);
 }
 public static void readIntoCollection1(String filename) throws IOException{
  BufferedReader fd = new BufferedReader(new FileReader(filename));
  ArrayList<String> arrstr = new ArrayList<String>();
  String s;
  while((s=fd.readLine())!=null){
   arrstr.add(s);
  }
  fd.close();
  Random rd = new Random();
  int n = rd.nextInt(arrstr.size());
  System.out.println(arrstr.get(n));
 }
 
}

案例5复制单级文件夹:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class CopyFolder {
 public static void main(String[] args) throws IOException {
  String oldfilepath = "D:\\src";
  String newfilepath = "D:\\ceshi";
  copyFileFolder(oldfilepath,newfilepath);
 }
public static void copyFileFolder(String oldfilepath,String newfilepath) throws IOException{
  File oldfile = new File(oldfilepath);
  File newfile = new File(newfilepath);
  if(!newfile.exists()){
   newfile.mkdir();
  }
  File[] filelist = oldfile.listFiles();
  for(File f:filelist){
   if(f.isFile()){
    File newfileeach = new File(newfilepath,f.getName());
    fileCopier(f,newfileeach);
   }
  }
  
 }
 
 public static void fileCopier(File f1,File f2) throws IOException{
  BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(f1)));
  BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f2)));
  String line;
  while((line= br.readLine())!=null){
   bw.write(line);
   bw.newLine();
   bw.flush();
  }
  br.close();
  bw.close();
 }
}

**
案例6复制指定目录下的指定文件并修改后缀名:**
(D:\src\IoWithArrayList.java===>D:\ceshi\IoWithArrayList.txt)

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class CopyAndAmendFileName {
 public static void main(String[] args) throws IOException {
  String oldpath = "D:\\src";
  String newpath = "D:\\ceshi";
  String oldfilename = "IoWithArrayList.java";
  String newfilename = "IoWithArrayList.txt";
  copyAmendFile(oldpath,newpath,oldfilename,newfilename);
 }
 
 public static void copyAmendFile(String oldpath,String newpath,String oldfilename,String newfilename) throws IOException{
  File oldf = new File(oldpath);
  File newf = new File(newpath);
  if(!newf.exists()){
   newf.mkdir();
  }
  File[] oldlis = oldf.listFiles();
  for(File oldfile: oldlis){
   if(oldfile.getName().equals(oldfilename)){
    System.out.println(oldfile.getName());
    File newfile = new File(newpath,newfilename);
    copyFile(oldfile,newfile);
   }
  }
 }
 
 public static void copyFile(File f1,File f2) throws IOException{
  BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(f1)));
  BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f2)));
  String line;
  while((line= br.readLine())!=null){
   bw.write(line);
   bw.newLine();
   bw.flush();
  }
  br.close();
  bw.close();
 }
}


案例7复制多级文件夹:

public class No52Demo {
	public static void main(String[] args) throws IOException {
		//复制多级文件夹
		String oldpath = "F:\\2ND SHOW";
		String newpath = "F:\\Download\\2ND SHOW";
		copyFolders(oldpath, newpath); 
	}
	
	public static void copyFolders(String oldpath, String newpath) throws IOException{
		File oldf = new File(oldpath);
		File newf = new File(newpath);
		if(!newf.exists()){
			newf.mkdir();
		}
		folder(oldf, newf);
	}
	
	public static void file(File oldfile,File newfile) throws IOException{
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream(oldfile));
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newfile));
		byte[] c= new byte[1024];
		int len=0;
		while((len = bis.read(c))!=-1){
			bos.write(c,0,len);			
		}
		bis.close();
		bos.close();
	}
	
	public static void folder(File oldfile, File newfile) throws IOException{
		File[] oldlis = oldfile.listFiles();
		for(File f:oldlis){
			if(f.isDirectory()){
				//是文件夹就创建文件夹,并递归调用知道没有子文件夹
				File newf = new File(newfile,f.getName());
				if(!newf.exists()){
					newf.mkdir();
				}
				System.out.println(f.getName());
				folder(f,newf);
			}else{
				//是文件,就创建文件对象,并复制文件
				File newf = new File(newfile,f.getName());
				file(f,newf);
			}
		}
	}

案例8

public class SortAndWriteString {
 public static void main(String[] args) throws IOException {
  //题目:已知s.txt文件中有这样的一个字符串:
  //"dfghyratygjhbvfdagytrygefhbhffgygg"
  //编写程序读取数据内容,吧数据排序后写入b.txt中  
  String s = "dfghyratygjhbvfdagytrygefhbhffgygg";
  String filepath = "a.txt";
  writeStr(s,filepath);
 }
 
 public static void writeStr(String s,String filepath) throws IOException{
  File f = new File(filepath);
  BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(f));
  char[] c = s.toCharArray();
  Arrays.sort(c);
  for(char cs:c){
   bos.write((byte)cs);
  }
  bos.close();
 }
}

案例9用Reader的read()方法模仿BufferedReader 的readLine()功能:

public static void main(String[] args) throws IOException {
  //用Reader模拟BufferedReader的readLine()功能
  String srcpath = "a.txt";
  Reader rd = new InputStreamReader(new FileInputStream(new File(srcpath)));
  String ss;
  while((ss= bufferedReaderwithReader(rd,srcpath))!=null){
   System.out.println(ss);
  }
  rd.close();
 }
 
 public static String bufferedReaderwithReader(Reader rd,String srcpath) throws IOException{
  
  StringBuilder sb = new StringBuilder();
  int c;
  while((c = rd.read())!=-1){
   if(c=='\r'){
    continue;
   }else if(c=='\n'){
    break;
   }else{
    sb.append((char)c);
   }   
  }
  if(sb.length()>0){
   return sb.toString();
  }else{
   return null;
  }
 } 

案例10创建学生对象并写入文本文件按总分从大到小排序:
Student类

public class Student implements Comparable{
	private String name;
	private String math;
	private String chinese;
	private String english;
	public Student(String name, String math, String chinese, String english) {
		super();
		this.name = name;
		this.math = math;
		this.chinese = chinese;
		this.english = english;
	}
	public Student() {
		super();
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getMath() {
		return math;
	}
	public void setMath(String math) {
		this.math = math;
	}
	public String getChinese() {
		return chinese;
	}
	public void setChinese(String chinese) {
		this.chinese = chinese;
	}
	public String getEnglish() {
		return english;
	}
	public void setEnglish(String english) {
		this.english = english;
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((chinese == null) ? 0 : chinese.hashCode());
		result = prime * result + ((english == null) ? 0 : english.hashCode());
		result = prime * result + ((math == null) ? 0 : math.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		if (chinese == null) {
			if (other.chinese != null)
				return false;
		} else if (!chinese.equals(other.chinese))
			return false;
		if (english == null) {
			if (other.english != null)
				return false;
		} else if (!english.equals(other.english))
			return false;
		if (math == null) {
			if (other.math != null)
				return false;
		} else if (!math.equals(other.math))
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
@Override
	public int compareTo(Object o) {
		Student s = (Student)o;
		int thissum = Integer.parseInt(this.math)+Integer.parseInt(this.english)+Integer.parseInt(this.chinese);		
		int othersum =Integer.parseInt(s.getMath())+Integer.parseInt(s.getEnglish())+Integer.parseInt(s.getChinese()); 
		int num = thissum-othersum;
		int num1 = num==0?this.name.hashCode()-s.name.hashCode():num;
		int num2 = num1==0? Integer.parseInt(this.math)-Integer.parseInt(s.getMath()):num1;
		int num3 = num2==0? Integer.parseInt(this.english)-Integer.parseInt(s.getEnglish()):num2;
		int num4 = num3==0? Integer.parseInt(this.chinese)-Integer.parseInt(s.getChinese()):num3;
		//int num2 = 
		return num4;
	}
public class No53Demo {
	public static void main(String[] args) throws IOException {
		BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt"));
		TreeSet<Student> ts = new TreeSet<Student>();
		Student s1 = new Student("Kathy","99","97","95");
		Student s2 = new Student("Kathy","90","97","50");
		Student s3 = new Student("Jack","100","99","99");
		Student s4 = new Student("Kenny","88","88","85");
		Student s5 = new Student("Many","88","88","85");
		Student s6 = new Student("Jack","99","100","99");
		ts.add(s1);
		ts.add(s2);
		ts.add(s3);
		ts.add(s4);
		ts.add(s5);
		ts.add(s6);
		System.out.println(s4.hashCode());
		System.out.println(s5.hashCode());
		System.out.println(s4.equals(s5));
		System.out.println(s3.equals(s6));
		for(Student s:ts){
			System.out.println(s.getName()+"---"+s.getMath()+"---"+s.getEnglish()+"---"+s.getEnglish());
			
			bw.write(s.getName()+"---"+s.getMath()+"---"+s.getEnglish()+"---"+s.getEnglish()+"\r\n");
		}
		bw.close();
	}
}
output:
Kathy---90---50---50
Many---88---85---85
Kenny---88---85---85
Kathy---99---95---95
Jack---99---99---99
Jack---100---99---99

7.LineNumberReader
缓冲字符输入流,跟踪行号。 该类定义方法setLineNumber(int)和getLineNumber()用于分别设置和获得当前行号。
默认情况下,线路编号从0开始。随着数据的读取,每个line
terminator的数字递增,可以通过呼叫setLineNumber(int)进行更改。 但是请注意,
setLineNumber(int)实际上并不改变流中的当前位置;
它只会更改getLineNumber()将返回的值 。
的线被认为是terminated一个换行(“\ n”)中的任何一个,回车(“\
r”),或回车一个换行符紧跟。

构造方法 :
ineNumberReader(Reader in)
使用默认的输入缓冲区大小创建一个新的行号阅读器。
LineNumberReader(Reader in,
int sz)
创建一个新的行号阅读器,将字符读入给定大小的缓冲区。

方法:
int getLineNumber()
获取当前行号。
void mark(int readAheadLimit)
标记流中的当前位置。
int read()
读一个字符
int read(char[] cbuf, int off, int len)
将字符读入数组的一部分。
String readLine()
读一行文字。
void reset()
将流重新设置为最近的标记。
void setLineNumber(int lineNumber)
设置当前行号。
long skip(long n)
跳过字符

案例1:

public static void main(String[] args) throws IOException {
  LineNumberReader lnr = new LineNumberReader(new FileReader("a.txt"));
  System.out.println(lnr.getLineNumber());
  lnr.setLineNumber(3);
  System.out.println(lnr.getLineNumber());
  String ss;
  while((ss= lnr.readLine())!=null){
   System.out.println(lnr.getLineNumber()+":"+ss);
  }
  
 }

案例2:模拟获取和设置行号功能

public class MyLineNumberReader {
private Reader r;
 private int lineNumber = 0;
 
 public MyLineNumberReader(Reader r){
  this.r = r;
 }
 
 public void setLineNumber(int n){
  this.lineNumber = n;  
 }
 
 public int getLineNumber(){
  return this.lineNumber;
 }

public String readLine() throws IOException{
StringBuilder sb = new StringBuilder();
  int c;
  while((c = this.r.read())!=-1){
   if(c=='\r'){
    continue;
   }else if(c=='\n'){
    this.lineNumber+=1;
    return sb.toString();
   }else{
    sb.append((char)c);
   }   
   }
  
  if(sb.length()>0){
   this.lineNumber+=1;
   return sb.toString();
  }else{
   return null;
  }
 }
 
 public void close() throws IOException{
  this.r.close();
 }
}




发布了55 篇原创文章 · 获赞 0 · 访问量 2068

猜你喜欢

转载自blog.csdn.net/KathyLJQ/article/details/105111048
今日推荐