1. FileReader 读文件三种粒度方式
FileReader 一个字节一个字节读
FileReader fr = null;
try {
fr = new FileReader("D:/out.java");
int c = 0;
while((c = fr.read())!=-1){//这里可以fr.read
System.out.print((char)c);//这里打出来的是中文非乱码,因为FileReader是一个字符一个字符往外读,不会把中文读出一半。
//而且这里的\n 也能被记成换行符。
}
} catch (IOException e) {
e.printStackTrace();
}
FileReader 一个char数组一个char数组的读
FileReader fr = null;
try {
fr = new FileReader("D:/out.txt");
char[] cbuf = new char[1000];
while(fr.read(cbuf)!=-1){//这里可以fr.read
System.out.print(cbuf);//这里打出来的是中文非乱码,因为FileReader是一个字符一个字符往外读,不会把中文读出一半。
//而且这里的\n 也能被记成换行符。
cbuf = new char[1000];//如果没有这句话,cbuf里会有脏数据,
}
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
FileReader + BufferedReader 一行行读( 注意:一行行读只能套一层BufferedReader ,BufferedReader 和BufferedWriter 用的非常普遍 ),执行的内存空间示意图如下面图1
public static void main(String[] args) {
FileReader fr = null;
String line = null;
try {
fr = new FileReader(new File("d:/file.txt"));
BufferedReader br = new BufferedReader(fr);
while((line = br.readLine())!=null ){ //readLine方法非常好用,即使为了这个方法,也要包一层bufferedReader 缓冲流
System.out.println(line); //这个readLine方法底层调用的是Reader的read(char [])
}
} catch (Exception e) {
e.printStackTrace();
}
}
</pre><pre>
2. FileWriter 写文件 write()函数的两种参数调用方式public void write(int c)
throws IOException写入单个字符。要写入的字符包含在给定整数值的 16 个低位中,16 高位被忽略。
用于支持高效单字符输出的子类应重写此方法。
FileWriter bw = null ;
try {
bw = new FileWriter("D:/out.txt");
for(int i=0;i<50000;i++) //此处的i取后16位,2的16次方能表示65536个字符,所以此处写50000都能显示。这里相当于我们把unicode大多数国家的字符都写了进去
bw.write(i);
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
public abstract void write(char[] cbuf,
int off,
int len)
throws IOException写入字符数组的某一部分。
public void write(String str)
throws IOException写入字符串。
public void writeFile(){
FileWriter bw = null ;
bw = new FileWriter("D:/result.txt");//注意这个路径符号
bw.write("warm up");//这里的write(String)就是调用了String的toCharArray()方法,最终调用上面的write(char[] )方法
bw.write("first");
bw.write("second");
bw.close();
}
FileWriter 写文件包一层处理流中的缓冲流
try {
BufferedWriter bw = new BufferedWriter(new FileWriter("D:/out.txt"));
for(int i=0;i<50000;i++){
bw.write("\t"+i);
bw.newLine(); //写完就换行
}
bw.flush(); //是把小桶(管道)里面的东西倒光,全部都写到文件里去。
bw.close(); //如果上面不调用flush(),下面直接close()也行,flush和close最终都调用一个方法去flush
} catch (IOException e) {
e.printStackTrace();
}
3. FileInputStream 读文件 (注意这里文件如果有中文,则System.out.print( (char) b) 是乱码)
/**
*这根管道就叫流,不同的管道,就是java的流。java的流和水流完全一致。流里面都是0101,
如果觉得不合适,就在流外面包一层强大一点的管道,这个管道可以帮你把0101转换成字符串
*
*/
int b = 0;
FileInputStream in =null;
try {
in = new FileInputStream("D:/Users/workspaceReal1/service/src/test/java/Iplong.java");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
long num = 0 ;
try {
while((b = in.read())!=-1){
System.out.print((char) b); //这里如果是int / byte,则显示数字,所以强转成char,显示字符
//如果被读文件里有中文,则出现乱码
num++;
if(num % 1000 == 0)//这里是为了照顾控制台一行输出的字符数限制
System.out.println();
}
in.close();
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
4. FileOutputStream 写文件(注意这里文件如果有中文,则out.write( b ) 不是乱码,是正常的中文)
/**
*这根管道就叫流,不同的管道,就是java的流。java的流和水流完全一致。流里面都是0101,
如果觉得不合适,就在流外面包一层强大一点的管道,这个管道可以帮你把0101转换成字符串
*
*/
int b = 0;
FileInputStream in =null;
FileOutputStream out = null;
try {
in = new FileInputStream("D:/Users/workspaceReal1/service/src/test/java/Iplong.java");
out = new FileOutputStream("D:/out.java");//FileOutputStream 在没有这个文件时候,会自动创建这个文件
} catch (FileNotFoundException e) {
e.printStackTrace();
}
long num = 0 ;
try {
while((b = in.read())!=-1){
//System.out.print((char) b);
out.write(b);//这里不是乱码,是正常的中文
num++;
if(num>3750)//如果加上这句,卡在文件中文的一半,则会出现一点点乱码如下图。
break; //原因:无论这里是char/int/byte,底层二进制都是一样的。一股脑写入文件,
//不会出现乱码。中途输出char/int/byte型,则出现一半中文。如果是char型,则是乱码,
//如果是int/byte则是数字0~255,这两个类型数据相等。
}
in.close();
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
System.out.println("total "+num+" bytes");
图 1 两部分缓冲的关系
5. outputstreamWriter 写文件
long longvar = 456;
//String longvar = "你好"; //上面的long 型和下面的string 型都可以非乱码写入文件,改一个utf16 则是乱码,原因不明
OutputStreamWriter osw;
try {
FileOutputStream ss = new FileOutputStream(new File("D:/out.txt"));
ss.write(String.valueOf(longvar).getBytes());//如果直接用 FileOutputStream,则write方法调用 ss.write("你好".getBytes());
osw = new OutputStreamWriter(new FileOutputStream(new File("D:/out.txt"),true));
osw.write(String.valueOf(longvar));
osw.flush();
System.out.println(osw.getEncoding());//这里显示的是当前Windows系统默认的编码是,UTF8。
//没有指定编码的情况下,OutputStreamWriter就使用当前系统默认的编码
//上面输出是乱码,now指定个编码,这里true的意思是在原来文件基础上追加,不写true,则把原文件擦掉
osw = new OutputStreamWriter(new FileOutputStream(new File("D:/out.txt"),true),"utf8");
osw.write(String.valueOf(longvar));
System.out.println(osw.getEncoding());//UTF-16
osw.flush();
osw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
6.InputStreamReader 读标准输入
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String s = null;
try { //这里是system.in 特殊,是同步的,你不输入,我不动
s = br.readLine(); //如果不输入,程序卡在这不动,只有输入后点击回车,程序才往下走.这种叫阻塞式的方法,以后还会见到,很多。
while(s!=null){
if(s.equalsIgnoreCase("exit")) break;
System.out.println(s.toUpperCase());
s = br.readLine(); //和上面一样,如果不输入就卡住
}
} catch (IOException e) {
e.printStackTrace();
}
7.数据流 DataInputStream / DataOutputStream ( 或者 ByteArrayInputStream / ByteArrayOutputStream )
从字节数组读东西,用ByteArrayInputStream
long longvar = 12121212121245L;
double doublevar = Math.random();
DataOutputStream dos;
DataInputStream dis;
FileOutputStream fos;
File file;
ByteArrayOutputStream baos;
ByteArrayInputStream bais ;
try {
//DataOutputStream + FileOutputStream,写文件
file = new File("D:/out.txt");
fos = new FileOutputStream(file);
dos = new DataOutputStream(fos);
dos.writeLong(longvar);// 写二进制数据,所以打开文件看到的是乱码,但是用DataInputStream 按你写的顺序读进来,就是正常值了
dos.writeDouble(doublevar);
dos.flush();
dos.close();
//DataInputStream + FileInputStream,读文件
dis = new DataInputStream(new FileInputStream(file));
System.out.println(dis.readLong());
System.out.println(dis.readDouble());
dis.close();
//dataOutputStream + ByteArrayOutputStream ,写内存(内存中用byte[]数组存)
baos = new ByteArrayOutputStream();
dos = new DataOutputStream(baos);
dos.writeLong(longvar);// 写二进制数据,所以打开文件看到的是乱码,但是用DataInputStream 按你写的顺序读进来,就是正常值了
dos.writeDouble(doublevar);
dos.flush();
dos.close();
//dataIntputStream + ByteArrayInputStream ,读内存<span style="font-family: Arial, Helvetica, sans-serif;">(内存中用byte[]数组存)</span>
bais = new ByteArrayInputStream(baos.toByteArray());//内存中被写入的东西,以byte[]数组的方式呈现出来,此处长度 //已存内容的byte[]数组的真实长度
//ByteArrayInputStream bais = new ByteArrayInputStream(buf);// 这里如果有,也可以用现成的buf直接初始化
dis = new DataInputStream(bais);
System.out.println(dis.readLong());
System.out.println(dis.readDouble());
dis.close();
} catch (IOException e) {
e.printStackTrace();
}
注意,dataInputStream是java原生的,比较慢,用hessian2
ByteArrayOutputStream byt1=new ByteArrayOutputStream();
aerospikeItem.setValue(CompressUtil.gzipToByteArray(value));
Hessian2Output hessian2Output = new Hessian2Output(byt1);
hessian2Output.writeObject(aerospikeItem);
hessian2Output.flush();
oArr1 = byt1.toByteArray();
}
hessian2Output.close();
byt1.close();
ByteArrayInputStream bis1=new ByteArrayInputStream(oArr1);
Hessian2Input hessian2Input = new Hessian2Input(bis1);
AerospikeItem to2 = (AerospikeItem)hessian2Input.readObject();
if (to2.isCompressed()) {
CompressUtil.ungzip(to2.getValue());
} else {
new String(to2.getValue(), "utf-8");
}
hessian2Input.close();
bis1.close();
8.PrintStream 三个用法
//format 格式控制
int s = 6;
boolean b = true;
System.out.format("我们现在有%d个", s).print(b);//我们现在有6个true
System.out.format("我们现在有%d个", s).println();//我们现在有6个
//System.out.print 分解
PrintStream ps;
ps = System.out;
ps.print(true);
//改变标准输出位置
try {
ps = new PrintStream(new FileOutputStream(new File("D:/out.txt")));
System.setOut(ps); //设置标准输出不在是控制台,而是文件out.txt
for(char c=0;c<50000;c++)
System.out.print(c); //此时标准输出不在是控制台,而是文件out.txt
} catch (FileNotFoundException e) {
e.printStackTrace();
}
9.ObjectOutputStream 的用法
Object 流,用的比较多,叫做序列化,其他语言上也叫序列化,就是把一个object 直接变成字节流,写到硬盘上,或者直接写到网络上。
class Iplong{
public void ObjectOutputStreamTest(){
T t = new T();
t.k = 9;
ObjectOutputStream oos;
try {
//写对象
oos = new ObjectOutputStream(new FileOutputStream(new File("d:/out.txt")));
oos.writeObject(t);
//读对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("d:/out.txt")));
T getTObjct = (T) ois.readObject();
System.out.println(getTObjct.d +" "+ getTObjct.i +" "+ getTObjct.j +" "+ getTObjct.k);//2.3 0 9 9
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
class T
implements Serializable{ //如果想把某个类的对象序列化,必须实现Serializable 接口
int i=0;
int j=9;
double d = 2.3;
transient int k = 15; //transient是瞬时的意思,往硬盘序列化的时候只写前三个值,这个transient 修饰的值不考虑
}