IO流
Java的IO流是实现输入输出的基础,将不同的输入\输出源(键盘、文件、网络连接)均抽象的称之为流。按照流的流向分,站在内存的角度,分为输入流和输出流。按照数据类型又可分为可以读写任何文件的字节流,和只能读取文本文件的字符流。两者的区别在于字节流操作的字节单元是8个字节,字符流是16个。
IO流基类
字节流基类–InputStream 和 OutputStream
构造方法
FileOutputStream(File file)
FileOutputStream(String name)
FileOutputStream的三个write()方法
public void write(int b): 写一个字节也可以是字符,超过一个字节只写最后一个
public void write(byte[] b):写一个字节数组输出到指定输出流
public void write(byte[] b,int off,int len):写一个字节数组的一部分,off起始len长度,含头不含尾
注意事项:
创建字节输出流对象了做了几件事情?
a:调用系统资源创建a.txt文件
b:创建了一个fos对象
c:把fos对象指向这个文件
别忘了释放资源,举例:
FileOutputStream out = new FileOutputStream("b.txt",true); // true不覆盖,续写
out.write("去年今日此园中".getBytes());
// \r\n windows 中用这个字符换行,Linux 和Mac 分别用一个
out.write("\r\n".getBytes());
out.write("人与桃花相映红".getBytes());
out.write("\r\n".getBytes());
out.write("人面不知何处去".getBytes());
out.write("\r\n".getBytes());
out.write("桃花依旧笑春风".getBytes());
out.write("\r\n".getBytes());
//释放资源
out.close();
InputStream和Reader是所有输入流的抽象类,本身并不能创建实例来执行输入,但它们成为所有输入流的模板,方法为所有输入流所用。
int read() //从输入流读取单个字节
int read(byte[] b) // 都区最多b.length个字节
int read(byte[] b,int off,int len) // 输入位置off,最多读取len个字节数据
因为它们都是抽象类,本身不能创建实例,分别有一个用于读取文件的输入流FileInputStream和FileReader,且都是==节点流==,会直接和指定文件关联。
举例:
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream("c.txt");
byte[] bytes = new byte[1024];
//一次读取字节数组的一部分 1024的设计,实际上对达不到1024字节的文件,一次就读完了。
//对于较小长度的字节数组,因为文件保存使用“GBK”编码,每个中文字符占两个字节,当read方法只读取到半个字符,这将导致该中文乱码
int len = in.read(bytes, 0, 3);
System.out.println(len);
for (byte aByte : bytes) {
System.out.println(aByte);
}
String s = new String(bytes, 0, len);
System.out.println(s);
in.close();
//程序里打开IO资源不属于内存中的资源,gc机制无法回收,所以应该显示关闭。但JAVA7之后IO资源类都实现了AutoCloseable接口,所以可以通过自动关闭资源的try语句来关闭。
BuffedInputStream读取
缓冲流,字节流一次读写一个数组的速度明显比一次读写一个字节的速度快很多,
这是加入了数组这样的缓冲区效果,java本身在设计的时候,也考虑到了这样的设计思想(装饰设计模式后面讲解),所以提供了字节缓冲区流。举例:
public static void main(String[] args) throws IOException {
// new BufferedOutputStream()
// new BufferedInputStream()
long start = System.currentTimeMillis();
//test1(); //耗时:34742 毫秒 耗时:11 毫秒
// test2(); //耗时:16269 毫秒 耗时:14 毫秒
long end = System.currentTimeMillis();
System.out.println("耗时:"+(end-start)+" 毫秒");
}
private static void test2() throws IOException {
//创建一个 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。
BufferedInputStream in = new BufferedInputStream(new FileInputStream("C:\\Users\\ShenMouMou\\Desktop\\a.mp3"));
//创建一个新的缓冲输出流,以将数据写入指定的底层输出流。
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("E:\\test\\b.mp3"));
byte[] bytes = new byte[1024 * 8];
int len = 0;
while ((len = in.read(bytes)) != -1) {
out.write(bytes,0,len);
out.flush();
}
in.close();
out.close();
}
private static void test1() throws IOException {
FileInputStream in = new FileInputStream("C:\\Users\\ShenMouMou\\Desktop\\a.mp3");
FileOutputStream out = new FileOutputStream("E:\\test\\b.mp3");
//字节加入了缓冲区
byte[] bytes = new byte[1024 * 8];
int len=0;
while ((len=in.read(bytes))!=-1){
out.write(bytes,0,len);
out.flush();
}
in.close();
out.close();
}
复制多级文件夹
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
//复制文件目录,并将.jpg后缀改成.png
public class Table {
public static void main(String[] args)throws IOException {
File srcFolder = new File("C:\\Users\\");
File targetFloder = new File("E:\\demo");
if (!targetFloder.exists()) {
targetFloder.mkdirs();
}
copyFolder(srcFolder, targetFloder);
System.out.println("复制完成");
}
private static void copyFolder(File srcFolder, File targetFloder) throws IOException {
File[] files = srcFolder.listFiles();
for (File f : files) {
if(f.isFile()&&f.getName().endsWith(".jpg")){
copyFiles(f, targetFloder);
String subString=f.getAbsolutePath().substring(0,f.getAbsolutePath().lastIndexOf("."));
File newfile = new File(subString + ".png");
f.renameTo(newfile);
}else{
copyFolder(srcFolder,targetFloder);
}
}
}
private static void copyFiles(File f, File targetFloder) throws IOException {
FileInputStream in = new FileInputStream(f);
FileOutputStream out = new FileOutputStream(new File(targetFloder, f.getName()));
byte[] bytes = new byte[1024 * 8];
int len=0;
while ((len=in.read(bytes))!=-1){
out.write(bytes,0,len);
out.flush();
}
in.close();
out.close();
}
}