IO流
IO流是输入输出流,即 inputStream、outputStream。
input是输入,读,把外部数据读到内存中;output是输出,写,把内存中的数据写到外部
Java保存数据仅限于程序运行期间的暂存,要使数据永久的保存下来,必须保存在硬盘里。而流就是用来写数据的。
一、首先要知道怎么对文件进行操作
要对文件进行操作,首先要获取到文件
1 File file = new File(pathname);
2 File file = new File(D:/文件路径);
3 File file = new File(D:\\文件路径);
File 隶属于 io 包,类的作用是获取到硬盘下的某个文件或文件夹,该类只能获取到文件或者文件夹的信息,而无法对文件进行任何读写操作。
file.exists() 判断文件或者文件夹是否存在
file.isFile() 判断是文件还是文件夹 文件返回true,文件夹返回false
file.getName() 获取文件名
file.getAbsolutePath() 获取绝对路径,全路径
file.getPath() 获取相对路径
file.getCanoicalPath() 获取标准路径,将统一平台间的路径写法差异
file.getParent() 父级目录
file.length() 文件大小
file.createNewFile() 创建文件,会提示有异常,可捕获或输出;要创建文件,前提是文件不存在
file.mkdir() 创建目录/文件夹,找不到就停
file.mkdirs() 递归创建目录/文件夹,找不到就创建
二、流的分类
输入流,输出流,字节流,字符流
输入流:外部数据加载到程序内;输出流:程序中的数据传输到外部
字节流:以字节 byte 为传递单位进行传递,所有文件都可用字节流(视频、音乐、图片压缩文件等)
字符流:以两个字节 2byte 为一个传递单位unicode,只有文本文件才能用字符流
注意:在最后一定要关闭流
(1) FileInputStream 文件输入流(字节流)
1 File file = new File(D:\\Love.java); 2 InputStream is = new FileInputStream(file); 3 byte[] b = new byte[(int)file.length()]; 4 is.read(b); 5 for(byte c:b){//byte是一个数组,循环输出的都是数字 6 System.out.println(c); 7 } 8 is.close();
read(byte[] b)方法,传一个 byte 数组,将文件读取进 byte 数组中去。
因为 read 方法的参数要传一个数组,所以必须要创建一个数组变量,数组的大小为文件的大小,且file.length()方法返回的是 long,在这里要强制转换成 int ;如果一个文件超过了 int ,就不能这样转换,会溢出,此时应该分开一部分一部分传,下载也应该分开传,byte 数组相当于缓冲区。
1 File file = new File("D:\\Love.java"); 2 InputStream is = new FileInputStream(file); 3 OutputStream os = new FileOutputStream(file); 4 byte[] b = new byte[1024]; 5 int i = is.read(b);//返回读了多少字节,当没有字节时,返回-1 6 while(i != -1){ 7 os.write(b,0,i); 8 i = is.read(b); 9 } 10 os.close(); 11 is.close();
将字节数组转换成字符串,可用 new String(byte[] bytes),转换成字符串后可以输出。
1 String str = new String(byte[] bytes);//传入字节数组参数后可转换为字符串
(2) FileReader 文件输入流(字符流)
1 File file = new File("D:\\Love.java"); 2 Reader r = new FileReader(file); 3 char[] c = new char[(int)file.length()]; 4 r.read(c); 5 for(char ch:c){ 6 System.out.println(ch); 7 } 8 r.close();
将字符串转换成字节数组,可用 String.getBytes
1 byte[] b = String.getBytes();//将字符串转换成字节数组
(3) FileOutputStream 文件输出流(字节流) ----- 如果文件不存在会自己创建,如果存在可以进行覆盖,也可以进行追加
1 OutputStream os = new FileOutputStream(file);//对象里没有追加的方法,会进行覆盖 2 OutputStream os = new FileOutputStream(file,true);//在构造方法中可以传一个boolean确认是否追加内容,在创建对象时告诉
1 File file = new File("D:\\You.java"); 2 OutputStream os = new FileOutputStream(file); 3 String str = "46489789fsfgregerf"; 4 byte[] b = str.getBytes(); 5 byte[] b2 = str.getBytes(charsetName);//也可以传入字符编码,UTF-8、GBK、gb2312(简)、big5(繁) 6 os.write(b);//传一个byte数组,将内容写入到输出流中 7 os.write(b2); 8 os.close();
(4) FileWriter 文件输出流(字符流) ----- 如果文件不存在会自己创建,如果存在可以进行覆盖,也可以进行追加
1 Write w= new FileWrite(file);//覆盖 2 Write w = new FileWrite(file,true);//追加内容 3 String str="1546rgtergae"; 4 w.write(str);// write方法可以直接传一个字符串,因为字符串底层是字符数组 5 w.close();//无论是字节流还是字符流,输入流还是输出流,最后一定要关闭
三、字节流和字符流的相互转换
字节流可以转字符流,但是字符流不可以转字节流
InputStreamReader 是一个转换器,构造方法中传一个字节流,就可以转换成字符流
1 InputStream is = new InputStream(file); 2 InputStreamReader isr = new InputStreamReader(is);//字节流转换成了字符流 3 char[] c = new char[(int)file.length()]; 4 isr.read(c); 5 for(char ch:c){ 6 System.out.ptintln(ch); 7 } 8 isr.close(); 9 is.close();
当有中文时,用 Reader 读到一个字符 char 数组里不太方便,因为中文不好控制,且用Reader读的时候读的是所有,如果想一行一行来读是做不到的
BufferReader 传一个字符流,生成一个更高级的字符流,可以按行来读
PrintStream 可以按行来输出
1 Reader r = new FileReader(file); 2 BufferReader br = new BufferReader(r);//传一个字符流 3 br.close(); 4 r.close(); 5 6 OutputStream os = new FileOutputStream(file); 7 PrintStream ps = new printStream(os); 8 ps.println(str);//可以按行来输出
现在读文件,尤其是字符,用 BufferReader,可以按行读取,读取出来的都是String,而且不用考虑char数组里有多少元素。
在BufferReader中,读取完一行后,就会有像游标一样的东西游到下一行,下次读取从下一行开始读取,如果没有读取的内容,会输出空指针null。
如果想要输出每一行,请看以下代码:
1 Reader r = new FileReader(file); 2 BufferReader br = new BufferReader(r); 3 4 /* 会出现隔行输出的问题 */ 5 while(br.readLine() != null){ 6 System.out.println(br.readLine()); 7 } 8 9 /* 正确的写法 */ 10 String str = br.readLine(); 11 while(str != null){ 12 System.out.println(str); 13 str = br.readLine(); 14 }
若有错误之处,欢迎指正。谢谢!