1.概述
IO流的主要作用是用来处理设备之间的数据传输,例如可以使用IO流将一台电脑硬盘里面的照片传输到另一台电脑上面,即将照片转换为字节,然后将字节传到另一台电脑上面,另一台电脑接收后,可以将这些字节还原为照片
2.分类
按照流向分类:
输入流(InputStream和Reader):从硬盘或者别的地方读到内存里面
输出流(OutputStream和Writer):从内存里面向硬盘或者别的地方输出
按照操作类型分类:
字节流(InputStream和OutputStream) : 字节流可以操作任何数据,因为在计算机中的数据都是以字节的形式存储的。
字符流(Reader和Writer) : 字符流只能操作纯字符数据,防止乱码。
注意:InputStream,OutputStream,Reader和Writer都是抽象类
3.File
File类:文件和目录路径名的抽象表现形式
作用:通过File对象实现对文件或者文件夹的操作
常用构造方法:
File(String URL)
常用方法:
String getName() — 获取当前文件对象的名字
long length() — 获取文件对象的大小 单位:字节
boolean isFile()/isDirectory()— 判断文件/文件夹
boolean canRead()/canWrite()— 判断文件可读/可写
boolean isHidden() — 判断file对象是否为隐藏
long lastModified() — 获取当前file对象最后修改时间
常用变量:File.separator –目录分隔符(/)
常用方法:
boolean exists() – 判断文件是否存在
void createNewFile() – 创建新文件
void mkdir()/mkdirs() – 创建新文件夹
delete() – 删除文件或者文件夹
File[] listFiles() – 获取当前文件夹下所有的子项,如果当前文件下为空则返回null值
注意:mkdir()和mkdirs()的区别
public static void main(String[] args) {
File file=new File("E://a.txt");
try {
file.createNewFile();
} catch (Exception e) {
e.printStackTrace();
}
File file2=new File("E://b/c");
//file2.mkdir(); //创建文件夹,如果父目录不在,则不会创建成功
file2.mkdirs();//父目录不存在,会连父目录一起创建
//file相关方法
System.out.println("获取文件或者文件夹的名字:"+file.getName());
System.out.println("获取文件的大小,单位字节:"+file.length());
System.out.println("判断文件是否可读:"+file.canRead());
System.out.println("判断文件是否可执行:"+file.canExecute());
System.out.println("判断文件是否隐藏:"+file.isHidden());
System.out.println("获取文件最后的修改时间,返回值是毫秒:"+file.lastModified());
//删除文件 delete
// file.delete();
// file2.delete();
System.out.println("判断文件是否存在:"+file.exists());
File file3 = new File("E://b/c");
//获取g盘下的所有文件或者文件夹,如果目录下没有相关文件,则返回null
File[] files = file3.listFiles();
for (File file4 : files) {
System.out.println(file4);//打印目录下所有的文件
}
System.out.println("file类的常量:"+File.separator);
}
4.FileFilter和FilenameFilter
FileFilter接口:
public boolean accept(File pathname)
FilenameFilter接口:
public boolean accept(File dir, String name)
File file=new File("E://");
File[] listFiles = file.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
System.out.println(pathname);
if(pathname.toString().endsWith("t")) {
return true;
}
return false;
}
});
System.out.println(listFiles);//[Ljava.io.File;@15db9742
System.out.println(Arrays.toString(listFiles));
System.out.println("================================");
//根据文件名
File[] files2 = file.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
System.out.println(dir);//磁盘
System.out.println(name);//文件名
if (name.startsWith("S")) {
return true;
}
return false;
}
});
System.out.println(Arrays.toString(files2));
5.字节输入流 inputStream
输入流的概念:输入的概念是指从外存读取数去输入到内存中read()
输入流提供的read方法是从输入流中读取数据的方法,InputStream提供多个重载的方法。
close()输入流提供的close方法作用是在输入流
用完后关闭流的动作。
public static void main(String[] args) {
FileInputStream fis=null;
try {
fis=new FileInputStream("E:/MyWork/Java/eclipse/Demo/src/cn/gok/testIO/TestFileInputStream.java");
byte[] byte1=new byte[1024];
// System.out.println(fis.available());
int len=-1;
while((len=fis.read(byte1))!=-1) {
System.out.println(new String(byte1,0,len));
}
} catch (Exception e) {
e.printStackTrace();
}
finally {
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
6.字节输出流 OutputStream
把流写入到文件。
构造方法
FileOutputStream(File file) FileOutputStream(File file, boolean append)
FileOutputStream(String name) FileOutputStream(String name, boolean append)
append:如果文件已经存在,append=true表示往文件追加内容,否则会覆盖文件。
注意:
使用File.separator解决不同系统的路径问题
在windos中的文件路径是以"“来分隔
在linux中的文件路径是以”/"来分隔
如果将上面代码部署到linux中会读取不到文件,为了保证编写的代码跨平台需要使用java.io包下的File.separator来替代文件路径的分隔符,如下
public static void main(String[] args) {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis=new FileInputStream("E:/MyWork/Java/eclipse/Demo/src/cn/gok/testIO/TestFileOutPutStream.java");
fos=new FileOutputStream("E://a.txt");
int len=-1;
byte[] buff=new byte[1024];
while((len=fis.read(buff))!=-1) {
fos.write(buff,0,len);
fos.flush();
// System.out.println(new String(buff, 0, len));
}
} catch (Exception e) {
e.printStackTrace();
}
finally {
try {
fos.close();
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
7.流的嵌套
流类可以分为
底层流 :包含以字节的形式读写的方法
高层过滤器流 :用于读写高层信息
高层流要求底层流作为基础
常用高层字节流:DataInputStream BufferedInputStream ObjectInputStream
Java中提供了BufferedInputStream和BufferedOutputStream缓冲流用来读取和写出, BufferedInputStream读取时会创建一个长度为8192的byte类型数组,程序一次读取8192个字节数据到数组中 使用缓冲流之后就不用再自定义byte类型数组了
BufferedInputStream bis=null;
BufferedOutputStream bos=null;
try {
bis=new BufferedInputStream(new FileInputStream("E:/MyWork/Java/eclipse/Demo/src/cn/gok/testIO/TestBufferedStream.java"));
bos=new BufferedOutputStream(new FileOutputStream("E://a.txt"));
int len=-1;
byte[] b=new byte[1024];
while((len=bis.read(b))!=-1) {
System.out.println(new String(b,0,len));
bos.write(b, 0, len);
bos.flush();
}
} catch (Exception e) {
e.printStackTrace();
}
finally {
try {
bis.close();
bos.close();
} catch (Exception e2) {
// TODO: handle exception
}
}
public static void main(String[] args) {
write();
read();
}
private static void write() {
try {
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("E://b"));
User user=new User(1,"swag");
oos.writeObject(user);
oos.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void read() {
try {
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("E://b"));
Object readObject = ois.readObject();
if(readObject instanceof User) {
User user=(User)readObject;
System.out.println(user.getId());
System.out.println(user.getName());
}
} catch (Exception e) {
e.printStackTrace();
}
}
使用字节流读取文件乱码问题
写出中文
向txt文件中写出中文,通过下面代码的演示,因为一个中文占2个字节,所以按照字节写出中文时会出现乱码的情况。
要想解决乱码的问题,可以使用字符流Reader和Writer