Java /O的一些典型使用方式
※两种流的典型使用场景:
①面向字符流:Reader/Writer 读写文本文件(特别是Unicode编码字符文件,如中文文件);
②面向字节流:InputStream/OutputStream 读写音频,视频、图片等二进制文件,对文件进行复制、分割、合并等操作,
也可以读取ANSI编码的文本文件(但同等条件下优先考虑面向字符流);*/
1、缓冲输入文本文件到内存
/**
* Description: 缓冲输入文件到内存
*/
import java.io.*;
public class BufferedInputFile {
/**使用BufferedReader缓冲面向字符流读取,使用readLine每次读取一行;(处理文本文件优先考虑)*/
public static String read(String filename) throws IOException{
BufferedReader in = new BufferedReader(new FileReader(filename));
String temp = "";
StringBuilder sb = new StringBuilder();
while((temp = in.readLine()) != null)
sb.append(temp+"\n");
//由于BufferedReader的readLine会自动将每行的换行符删除,必要时要自己添加;
in.close();
return sb.toString();
}
/**BufferedReader缓冲面向字符流读取,每次使用read读取一个字符;(可以读取中文)*/
public static String readByChar(String filename) throws IOException{
BufferedReader in = new BufferedReader(new FileReader(filename));
int temp ;
StringBuilder sb = new StringBuilder();
while((temp = in.read()) != -1)
sb.append((char)temp);
//使用面向字符流 read读取的是单个字符的Unicode码;
in.close();
return sb.toString();
}
/**使用面向字节的DataInputStream读取,每次使用read读取一个字节
这种方式只能读取ansi字符(无法读取中文等)*/
public static String readByBytes(String filename) throws IOException{
DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(filename)));
StringBuilder sb = new StringBuilder();
while((in.available()) != 0)
sb.append((char)(in.readByte()));
in.close();
return sb.toString();
}
public static void main(String[] args) throws IOException{
System.out.println(readByBytes("Country_City_Asia.txt"));
}
}
2、从内存中输入
//输入流不仅可以用于外部文件流的输入,也可以用于内存中流的输入,StringReader可以以字符流的形式读取内存中的一个字符串;
StringReader in = new StringReader(BufferedInputFile.read("Demo.java"));
int c;
while((c = in.read()) != -1)
System.out.print((char)c);
in.close();
3、基本的文本文件输出
//FileWriter对象可以向文件写入数据,一般会使用BufferedWriter对其进行包装, 使用缓冲流能很明显地增加I/O操作的性能;
//使用PrintWriter对其进行包装,可以进行格式化输出;
//从源文件中读取文本(在内存中以String的形式储存)到内存后,使用一个StringReader对其进行读取;
BufferedReader in = new BufferedReader(new StringReader(BufferedINputFile.read("demo.java")));
//使用一个PrintWriter格式化输出StringReader流中的数据;
PrintWriter out = new PrintWriter(new BufferedWirter(new FileWriter("demo.out")));
/*Java SE5在PrintWriter添加了一个辅助构造器,可以节省装饰代码:
* PirntWriter out = new PrintWriter("demo.out")
*/
int lineCount = 1;
String strRead = "";
while((strRead = in .readLine())!=null)
out.println(lineCount++ +":"+ strRead);
out.close();
in.close();
4、储存和恢复数据
//为了输出可供另一个流恢复的数据,需要使用DataOutputStream写入数据,用DataInputStream恢复数据,这些流可以是任何形式,使用这种方式储存和恢复数据的优点是,具有平台通用性;
DataOutputStream out = new DataOutStream(new BufferedOutputStream(new FileOutputStream("Data.txt")));
out.writeDouble(3.14);
out.wirteUTF("This is PI");
out.writeInt("1024");
out.close();
DataInputStream in = new DataInputStream(new BufferedInputSream(new FileInputStream("Data.txt")));
System.out.println(in.readDouble());
System.out.println(in.readUTF());
System.out.println(in.readInt());
5、读写随机访问文件
//使用RandomAccessFile可以对文件进行随机读写
import java.io.*;
public class UsingRadnomAccessFile {
static String file = "rTest.dat";
static void display() throws IOException{
RandomAccessFile rf = new RandomAccessFile(file,"r");
for(int i=0;i<5;i++)
System.out.println("Value "+i+":"+rf.readDouble());
System.out.println(rf.readUTF());
}
public static void main(String[] args) throws IOException{
//顺序写入数据
RandomAccessFile rf = new RandomAccessFile(file,"rw");
for(int i=0;i<5;i++)
rf.writeDouble(i*3.14);
rf.writeUTF("The end of the file");
rf.close();
display();
//随机写入数据
rf = new RandomAccessFile(file,"rw");
rf.seek(3*8);
//seek是以字节byte单位进行跳跃的,跳到某一个字节位后,对后面的字节位写入数据覆盖写入的
//一个double为8byte;
rf.writeDouble(1024.1024);
rf.close();
display();
}
}
/*output:*
Value 0:0.0
Value 1:3.14
Value 2:6.28
Value 3:9.42
Value 4:12.56
The end of the file
Value 0:0.0
Value 1:3.14
Value 2:6.28
Value 3:1024.1024
Value 4:12.56
The end of the file
/
RandomAccessFile不同基本类型所占用的数位: 3-T3.Java I/O流 类库
6、文件读写实用工具
package java_io_system;
/**
* Description: 实用文本文件读写类
* 使用一个ArrayList<String>来保存文件的若干行,当操纵文件内容时,就可以使用ArrayList的所有功能;
* 如可以将TestFile包装为其他的Collection容器,或者使用List的特性对文件内容进行随机访问;
* 1、使用write(String filename,String text)向文件写入文本;
* 2、使用read(String filename)读取文件的所有文本;
*/
import java.util.*;
import java.io.*;
public class TextFile extends ArrayList<String> {
/**静态方法:读取文本文件的所有文本到内存*/
public static String read(String filename){
StringBuilder sb = new StringBuilder();
try{
BufferedReader in = new BufferedReader(new FileReader(new File(filename).getAbsoluteFile()));
try{
String s;
while((s=in.readLine())!=null){
sb.append(s);
sb.append("\n");
}
}finally{
in.close();
}
}catch(IOException e){
e.printStackTrace();
}
return sb.toString();
}
/**静态方法:向文本文件写入文本,
* 缺陷:text中的"\n"可能无法正确地被写入到文本文件filename中;
* 使用成员方法write(String name)可以避免这一点*/
public static void write(String filename,String text){
try{
PrintWriter out = new PrintWriter(new File(filename).getAbsoluteFile());
try{
out.print(text);
}finally{
out.close();
}
}catch(IOException e){
e.printStackTrace();
}
}
/**构造方法:通过一个filename读取文件文本,使用指定的splitter对文本进行分割后装载到List中*/
public TextFile(String filename,String splitter){
super(Arrays.asList(read(filename).split(splitter)));
if(get(0).equals(""))
remove(0);
}
/**默认构造方法:以行分隔符作为默认分割符号*/
public TextFile(String filename){
this(filename,"\n");
}
/**成员方法,将本TextFile中的所有文本内容全部写入到一个文本文件*/
public void write(String filename){
try{
PrintWriter out = new PrintWriter(new File(filename).getAbsoluteFile());
try{
for(String item : this)
out.println(item);
}finally{
out.close();
}
}catch(IOException e){
e.printStackTrace();
}
}
//Test:
public static void main(String[] args){
String file = read("src/java_io_system/TextFile.java");
write("test.txt",file); //"test.txt"可能没有正确的分隔行;
TextFile text = new TextFile("test.txt");
text.write("test2.txt"); //"test2.txt"中有正确的分隔行
//提取一个文本文件中的所有大写字母开头的单词
TreeSet<String> words = new TreeSet<String>(new TextFile("test2.txt","\\W+"));
System.out.println(words.subSet("A","["));
}
}
//二进制读写工具类,类似上面的TextFile,不过BinaryFile使用byte[]储存内部数据;
public class BinaryFile{
public static byte[] read(File file) throws IoException{
BufferedInputStream bf = new BufferedInputStream(new FileInputStream(file));
try{
byte[] data = new byte[bf.available()];
bf.read(data);
}finally{
bf.close();
}
return data;
}
public static byte[] read(String filename) throws IOException{
return read(nw File(filename).getAbsoluteFile());
}
}