JAVA输入输出笔记
刚刚开始学习java的时候,发现java提供的输入输出流类有好多,名字也很容易搞混了,因此跳了过去没认真看。遇到了问题一直都是靠百度来临时性的解答。相信很多新手学习java的时候,应该也和我一样吧。这就遗留了一个问题,离开了百度自己就什么都写不出了,哪怕是最简单的文件复制。没辙,被整得实在是头疼,认真的翻了翻jdk,发现其实java的输入输出没想象中的那么复杂。只要理解了一些基本的类,以后无论是遇到什么框架下封装的输入输出流,都将能很快上手。以下是我的一些学习总结,高手见笑了。
一,基本定义
1,流根据流向不同,分为输入流和输出流。这个“入”和“出”是以你写的程序为参考对象的。
2,流根据处理的数据类型不同,分为字节流和字符流。
我建议学习的时候,以字节流和字符流作为区分来学习,以下是java最基本的流结构图。
字节流读写的时候以字节为基本单位,字符流读写的时候以字符为基本单位。其实字符流的底层也是字节流,只是在读写的同时使用码表解析成字符。码表有好多种,中文默认的码表采用gbk编码,每个字符占用2个字节,保持成TXT文件的时候,可以看到类型是ANSI的。可以指定使用utf8编码的码表,每个字符占用3个字节,保持成TXT时文件类型是UTF-8的。

二,字节流

主要掌握这四个类,再往上是抽象的不能直接使用的类了。Buffered开头的含有缓冲区,效率比较高。
读文件(输入流)
读取主要使用两种方法
1,int read()
2,int read(byte[] bt)
虽然都是返回int类型,但是这个int的含义是不一样的。方法1返回的是直接读取的到的字节,方法2返回的是读取到的字节的个数。
例如:
FileInputStream fis = new FileInputStream("c:/a.txt");
int by = fis.read();
System.out.print(by);
fis.close();
如果a.txt文件里面开头写有一个“a”,并且文件是gbk编码(文件类型为ANSI),那么将输出97。
FileInputStream fis = new FileInputStream("c:/a.txt");
byte[] bt = new byte[2];
int by = fis.read(bt);
System.out.print(by);
fis.close();
如果a.txt文件里面只含有一个“a”, 并且文件是gbk编码(文件类型为ANSI),那么将输出1。虽然指定的接收对象bt定义为2字节大小,但是实际只能接收到1个字节,所以输出1。
两种读取方法,失败了都将返回-1,这个可以作为读取结束的标识。
FileInputStream fis = new FileInputStream("c:/a.txt");
byte[] bt = new byte[2];
int by;
while((by = fis.read(bt)) != -1){
System.out.print(new String(bt, 0, by));
}
fis.close();
至于BufferedInputStream,使用方法跟FileInputStream一样。只是创建对象的时候如下
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("c:/a.txt"));
ps:1,如果文件不存在,将报异常。
2,读取结束后一定要记得关闭流对象。
写文件(输出流)
写入比较简单,直接上代码了
FileOutputStream fos = new FileOutputStream("c:/io/a.txt");
fos.write("晃同".getBytes());
fos.close();
至于BufferedOutputStream,使用方法跟FileOutputStream一样。只是创建对象的时候如下
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("c:/a.txt"));
ps:1,如果目录不存在,将报异常。
2,如果文件不存在,目录存在,将创建文件。
3,如果文件文件存在,将覆盖文件。
4,记得关闭流对象。
字节输入流和字节输出流结合使用可以实现文件复制,具体怎么实现,自己思考一下。
三,字符流
字符流主要掌握着这6个类。同字节流一样,Buffered开头的含有缓冲区,是高效的。
读文件(输入流)
读取主要使用两种方法
字节流使用的数组是字节数组。byte[] bt
字符流使用的数组是字符数组。char[] chs
1,int read()
2,int read(char[] chs)
与字节流相似。方法1返回的是直接读取的到的字符,方法2返回的是读取到的字符的个数。
两种读取方法,读取到文件结尾都将返回-1,这个可以作为读取结束的标识。
方法1实例:
FileReader fr = new FileReader(“c:/a.txt”);
int ch = 0;
while((ch=fr.read())!=-1){
System.out.print((char)ch);
}
Fr.close();
方法2实例:
FileReader fr = null;
try{
fr=new FileReader(“c:/a.txt”);
char[] buf=new char[1024];
int len=0;
while((len=fr.read(buf))!=-1){
System.out.println(new String(buf,0,len));
}
}catch(IOException e){
System.out.println(e.toString());
}finally{
if(fr!=null)
try{
fr.close();
}catch(IOException e){
System.out.println(e.toString());
}
}
目录分隔有两种方式,“//”或者“/”
BufferedReader特有的方法readLine();文件末尾返回null
BufferedReader bufr = new BufferedReader(new FileReader(“c:/a.txt”));
写文件(输出流)
FileWrite fw = new FileWriter(“c:/a.txt”);
fw.write(“aaaaa”);
fw.close();
文件存在则覆盖,不存在则新建
可以采用续写模式
FileWriter fw = new FileWriter(“c:/a.txt”,true);
BufferedWriter特有的方法,跨平台的换行符newLine();
FileWriter含有默认编码表,如果要制指定编码表,需要使用BufferedWriter
四,字节流和字符流的转换
InputStreamReader(InputStream in,String charSet):字节到字符的转换
OutputStreamWriter(OutputStream in,String charSet):字符到字节的转换
如果不指定第二参数,则使用的是本系统(运行环境)的码表。
String charSet = System.getProperty(“file.encoding”);获取系统码表
常用码表有ASCII、ISO8859-1、GB2312、GBK、UNICODE、UTF-8
编码转换
字符串——字节数组:编码,通过getBytes(charset)
字节数组——字符串:解码,通过String(byte[],charset)
实例:
把iso8859-1转换成gbk
Byte[] b1 = s1.getBytes(“iso8859-1”);
String s2 = new String(b1,”gbk”);
System.out.println(s2);