Java中的IO流是实现输入/输出的基础。
按照流的方向不同:分为输入流和输出流。
按照处理数据单位的不同:分为字节流(8位)和字符流(16位)。
按照功能不同:分为节点流和处理流
所有面向字节的流类都继承于InputStream类(输入流)
或OutputStream类(输出流),这两个类是抽象类,我们可以利用它的子类来完成不同的功能。
InputStream、OutputStream都是抽象类
InputStream抽象了应用程序读取数据的方式
OutputStream抽象类应用程序写出数据的方式
文件输入流 FileInputStream 继承了InputStream,FileInputStream 具体实现了在文件上读取数据。
int b = in.read() 读取一个 byte 无符号填充到 int 低八位,-1 是 EOF
in.read(byte[] buf) 读取数据填充到 buf 中
in.read(byte[] buf, int start, int size) 读取数据填充到 buf 中
FileOutputStream
输出流的基本方法:
out.write(int b) 写出一个 byte 到流 b 的低八位写出
out.write(byte[] buf) 将缓冲区 buf 都写入到流
out.write(byte[] buf, int start, int size) 将 buf 的一部分写到流中
out.flush() 清理缓冲
out.close();
注意他们两个都是字节流--用于读取诸如图像数据之类的原始字节流
案例1:使用FileInputStream读取文件
File file=new File("c:","sql.properties");
FileInputStream fis=new FileInputStream(file);
int n=0;
byte[] b=new byte[1024];
while((n=fis.read(b))!=-1){
System.out.println(newString(b,0,n));//System.out.println(new String(b,"gbk"));--控制格式
}
fis.close();
String s="hello world"
s.getBytes()--byte[]
FileOutputStream fo=new FileOutputStream(f2);
fo.write(byte[]);
案例3:图像的复制
BufferedInputStream && BufferedOutputStream 为 IO 操作提供了缓冲区,一般打开文件进行
写入戒读取操作时,都加上缓冲流,这种流模式是为了提高 IO(输入输出)的性能。
在FileInputStream里有一个说明是说此方法将阻塞,意思就是说在你读一个文件输入流的时候,当读到某个位置的时候,如果做一些其他处理(比如说接受一部分字节做一些处理等等)这个时候输入流在什么位置就是什么位置,不会继续往下读,而BufferedInputStream虽然也有一个read方法,但是从名字就可以看出,它带有一个缓冲区,它是一个非阻塞的方法,在你读到某个位置的时候,做一些处理的时候,输入流可能还会继续读入字节,这样就达到了缓冲的效果。
假设一个文件的长度是100个字节,要将之读取到内存中,再假设您每次只读取10个字节,那么读完整个文件是不是读取10次的呀?
假设老板让你完成100件事情,老板说,你每天只完成10件就可以了,难道你非得等到第十天才完成第100件事情吗?有一天您在中午下班前就完成了10件事情,下午您不妨多干一点,那么也许在第9天的时候就完成了100件事情。
同理,BufferedInputStream有可能会读取比您规定的更多的东西到内存,以减少访问IO的次数,
总之您要记住一句话,访问IO的次数越少,性能就越高,原因就在于CPU和内存的速度》》》》远大于硬盘或其他外部设备的速度。
File f=new File("c:/wode.txt");
byte[] b=new byte[(int) f.length()];
BufferedInputStream bu=new BufferedInputStream(new FileInputStream(f));
int i=0;
while((i=bu.read(b))!=-1){
System.out.println(new String(b,"gbk"));
}
字符流:
字符流(Reader Writer)
字符的处理,一次处理一个字符(unicode 编码)
2) 字符的底层仍然是基本的字节流
3) 字符流的基本实现
? InputStreamReader 完成 byte 流解析为 char 流, 按照编码解析
? OutputStreamWriter 提供 char 流到 byte 流, 按照编码处理
主要使用它们两个FileReader FileWriter
Reader类中两个常用类:
FileReader:以字符流的形式读取文件,与FileInputStream用法基本一致。
BufferedReader:将流读入缓冲区,然后从缓冲区读取,并且提供了readLine()方法,可以从文本文件中整行的读取数据。
Writer类中两个常用类:
FileWriter:以字符流的形式写入文件,与FileOutputStream用法基本一致。
BufferedWriter:将缓冲区输出到流。
它和我我们字节流的区别:
InputStream和OutputStream主要用来处理可以被直接读作bytes的数字。
Reader和Writer用来处理文本。
实验1:写出文件:
File file=new File("c:\\test.txt");
FileWriter fw=new
FileWriter(file);//在这里加入参数true会实现对文件的续写
String s="举头望明月,低头写代码";//\r\n为window下边的换行
fw.write(s);
fw.close();
案例2:读取文件
File f ile=new File("c:\\test.txt");
BufferedReader br=new BufferedReader(new FileReader(file));
String strline =br.readLine();
System.out.println(strline);
--但是我们发现,这样只读取了一行数据
File file=new File("c:\\test.txt");
FileReader fr=new FileReader(file);
int ch=0;
while((ch=fr.read())!=-1){
System.out.print((char)ch);
}
java.io.File用于表示文件(目录),也就是说程序员可以通过File类在程序中操作硬盘上的文件和目录。
File类只用于表示文件(目录)的信息(名称、大小等),丌能对文件的内容进行访问。
File f=new File(".");
System.out.println(f.getCanonicalPath());
f.getCanonicalPath()---获取当前路径
创件一个新的文件
File d=new File(f,"demo");
if(!d.exists()){
d.mkdir();
}
创件新的文件对象
File text=new File(d,"text");
if(!text.exists()){
text.createNewFile();
}
获取文件
File f=new File("c:");
System.out.println(f.getCanonicalPath());
f.getCanonicalPath();
File[] files=f.listFiles();
System.out.println(Arrays.toString(files));
FileFilter类是对操作文件的过滤
File f=new File("src/test");
File[] files=f.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.getName().endsWith(".java")&&pathname.isFile();
}
});
for(File file:files){
System.out.println(file.getName());
}
listFiles()方法会将dir中每个文件交给accept()方法检测,如果返回true,就作为方法的返回结果元素