文件这一块其实在我看来是一个稍微还比较简单的东西,不管是学C语言也好,学其他的语言也罢,操作文件这部分的内容都是必不可少的。操作文件涉及到一个很重要的知识点也就是IO流。那么学习IO流的用处到底在哪里呢?
首先以一个很简单的例子说一下我个人对文件的理解,数据在计算机里面都是以二进制的形式进行存储的。而我们需要关注的有两种文件形式,一种是纯文本形式,存储纯文本文件;另一种是二进制文件,可以存储任何形式的文件,包括音频文件、视频文件等多种类型的文件。(这里不知道我表述准不准确)转换成二进制的形式来存储的,在我们平时操作windows的文件管理器时,我们都是直接用鼠标点击,但其实在我们打开文本文件或者是新建一个文本文件的时候,就是一个读写文件的过程。点击查看文件的属性,我们可以知道文件的类型、大小、位置、占用空间等信息。在这里面我们最需要关注的信息就是文件大小。
我们表示文件大小的单位有很多,其中计算机存储文件的最小单位是
bit:也叫比特位,每个二进制的0或者1就表示1个bit,
byte:字节。1B=8bit,1个字节表示1B,而一个字符表示2个字节,也就是2B
kbytes:KB 1KB = 1024B=2^10B
MB:1MB=1024KB=2^20B
同样依次还有GB、TB、PB、EB、ZB。
这个时候就可以说说学IO流的作用了。当我们面临一个巨大的文件,比如4个G的大文件,这个时候我们用普通的方法不能打开它,怎么办呢??这个时候我们就需要把文件进行分割。需要对这个文件进行操作,那么操作的本质是什么呢,其实就是IO流操作。IO流的操作有很多应用,比如我们在编程的时候,在控制台上打印结果,其实也是一种IO流操作。对文件的操作随处可见,比如说网络上文件的拷贝,用户修改头像,上传下载文件等等这些都需要用到IO流。好了,接下来进入正题!
一、文件File类
位于java.io包下,File类:文件的分隔符在不同的系统下是不一样的,比如在linux下是左斜杠 /而在windows下可能是两个右斜杠\\,因此推荐用左斜杠/,也可以利用pathSeparator路径分隔符获得当前系统下的文件分隔符。
1、两个常量:路径分隔符:a)pathSeparator 路径分隔符 b)名称分隔符 (windows下\ Linux /)推荐使用"/"如C:/Users/Lively
2、文件的常用方法:
1)文件名*getName()
*getPath()路径名
*getAbsolutePath()返回绝对路径
*getParent()返回上一级目录
2)判断信息
是否存在exists
是否可写canWrite()
是否可读canRead()
是否是文件isFile()
是否是目录isDirectory()
3)长度
4)创建和删除文件
createNewFile()
deleteFile()
deleteOnExit()退出即删除文件(临时文件)
5、操作目录
mkdir()创建目录,必须确保父目录存在,如果不存在则创建失败
mkdirs()
list()文件;目录字符串形式
listFiles()
staticlistRoots()根路径
应用:用listRoots可以遍历整个磁盘,listFiles遍历根目录下的子目录
递归遍历小示例:
/** * 打印路径 */ public static void printName(File src){ if(null == src||!src.exists()){ return; } System.out.println(src.getAbsolutePath()); if(src.isDirectory()){ for (File sub:src.listFiles()){ printName(sub); } } }
二、IO流
一、概念
流:流动,流向,从一端到另一端,源头与目的地。计算机将数据的集合称为数据流,这些数据流可以从一端流到另一端,从源头流向目的地,我们从计算机内存中读出数据,在程序中进行处理,把内存中的数据读到;相反我们将数据用程序写入内存中,把程序中的数据写入。流的本质就是数据传输,为了编程的方便,因此我们把数据传输流抽象成各种类。
程序与文件|数组|网络连接|数据库,以程序为中心
二、IO流分类
1、按流向:分为输入与输出流InputStream、OutputStream
2、按数据:字节流:二进制,可以处理一切文件,包括纯文本 doc 音频 视频
字符流:文本文件,只能处理纯文本
3、按功能:节点:包裹源头
处理:增强功能,提高性能
三、字符流与字节流(核心重点)与文件
字节流:InputStream输入流 Outputstream输出流
Fileinputstream()
FileOutputstream()
需要掌握的方法:read() 、read(byte b[],int off,int len) +close()
Write() write(byte b[],int off,int len) +flush +close()
字符流:Reader输入流 Writer输出流
read() 、read(byte b[],int off,int len) +close()
Write() write(byte b[],int off,int len) +flush +close()
四、操作IO流的步骤
1、读取文件 ----->
2、建立与文件联系---->file对象
3、选择对应流 -->>inputstream outputstream
4、操作 数组大小 读取|写出文件 read、write
5、释放资源 close
字节流简单示例:
import java.io.*; public class IOStream { public static void main(String[] args) { File src =new File("f:/Java/a.txt"); InputStream in = null; try { in = new FileInputStream(src); byte[] b = new byte[1024]; int len = 0 ; while (-1 != (len = in.read(b))){ String s = new String(b,0,len); System.out.println(s); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } }
几乎所有的IO流操作都是一个套路,四个步骤:首先读取文件,然后选择合适的流,再对文件进行操作,包括读出,写入等,最后关闭流。
其中字节流对应的有:InputStream输入流 Outputstream输出流 Fileinputstream() FileOutputstream() 需要掌握的方法有:读文件:read() 、read(byte b[],int off,int len) +close() 关闭流
写文件:write(),write(byte b[],int off,int len) +flush +close() 刷新,关闭流(注意,每次写入到一个文件都必须调用flush方法刷新!!!)
字符流对应的 方法有:Reader输入流 Writer输出流
字符流读取示例:
public void fileReader(String file){ File f = new File(file); BufferedReader r = null; Reader fileReader = null; try { fileReader = new FileReader(f); char[] b= new char[1024]; int len = 0; // r = new BufferedReader(new FileReader(f)); // while (null != r.readLine()){ // System.out.println(r.readLine()); // } while (-1!= fileReader.read(b)){//每次读1024个字符 System.out.println(b); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { fileReader.close(); } catch (IOException e) { e.printStackTrace(); } } }
这种方法读取的时候是按照字符读取,每次读指定的字符,这种方法的缺点是文件的实际大小可能不是1024的整数倍。这就会造成会读出来的数据不准确。比如下面这个情况,
文件a本身只有5k,但它实际大小只有4.82kB(4942字节),读出来后写入另一个文件之后实际就变成5.05KB(5180字节)了。所以我们尽量还是用字节流比较好,或者在边界做出一些相关判断。
以上就是对文件和IO流的简单操作的介绍,后续还会说一下缓冲流、文件复制、分割等相关操作。