一,File类
File类位于java.io包下,用来表示文件(目录)。
File类只用于表示文件(目录)的信息(文件名称,文件大小),不能用于文件内容的访问
1,File的基本操作
package com.amazing.jdk.learn2IO_0821.FileAPI; import java.io.File; import java.io.IOException; /** * Created by yaming on 17-8-21. */ public class FileDemo { public static void main(String[] args) { //window,linux系统文件分割符不同,可以使用File.separator设置分隔符。适用window和linux File fileSeparator=new File("e:"+File.separator+"javaio"+File.separator+"test"); /** * 1,操作目录 */ File file=new File("/home/yaming/Desktop/filedemo"); //查看目录是否存在,不存在就创建 System.out.println(file.exists()); if(!file.exists()) file.mkdir(); else file.delete(); //判断是否是一个目录,如果是目录返回true.如果不是目录或目录不存在,返回false boolean flag1 = file.isDirectory(); //判断是否是一个文件 boolean flag2 = file.isFile(); /** * 操作文件 */ //判断文件是否存在 File file2=new File("/home/yaming/Desktop/日记.txt"); //不存在就创建文件 if (!file2.exists()){ try { file2.createNewFile(); } catch (IOException e) { e.printStackTrace(); } }else { file2.delete(); } /** * 常用File对象的API */ //打印file,打印的是file.toString()的内容 System.out.println(file); //目录绝对路径 System.out.println(file.getAbsoluteFile()); //打印目录最后一级的名字 System.out.println(file.getName()); //打印文件名字 System.out.println(file2.getName()); //访问父目录,目录路径 String parentPath = file.getParent(); } }
2,File类常用操作
遍历目录:
package com.amazing.jdk.learn2IO_0821.FileAPI; import java.io.File; import java.io.IOException; /** * Created by yaming on 19-5-4. */ public class FileUtils { /** * 列出指定目录下(包括子目录)的所有文件 * @param dir * @throws IOException */ public static void listDirectory(File dir)throws IOException{ if(!dir.exists()){ throw new IllegalArgumentException("目录不存在"); } if (!dir.isDirectory()){ throw new IllegalArgumentException(dir+"不是目录"); } File[] files = dir.listFiles();//返回的是直接子目录(文件)的抽象 if (files != null && files.length >0){ for (File file : files){ if (file.isDirectory()){ //递归 listDirectory(file); }else { System.out.println(file); } } } } }
二,RandomAccessFile类的使用
java提供的对文件内容的访问,既可以读文件,也可以写文件。
RandomAccessFile支持随机访问文件,可以访问文件的任意位置
1,java文件模型:
在硬盘上的文件是byte byte byte存储的,是数据的集合
2,打开文件
有两种模式 "rw"(读写模式), "r" (只读模式)
RandomAccessFile raf = new RandomAccessFile(file,"rw")
文件指针,打开文件时指针在开头 pointer = 0; 读写操作后,指针向后移动(写和读的时候指针都会移动)
3,写方法
raf.write(int) ---->只写一个字节(后8位),同时指针指向下一个位置,然后再次写入
4,读方法
int b = raf.read() ----> 读一个字节
5,文件读写完成后一定要关闭
6,代码:
package com.amazing.jdk.learn2IO_0821.FileAPI; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.util.Arrays; /** * Created by yaming on 19-5-4. */ public class RafDemo { public static void main(String[] args)throws IOException { File demo=new File("demo"); if (!demo.exists()){ demo.mkdir(); } File file = new File(demo,"raf.dat"); if (!file.exists()){ file.createNewFile(); } RandomAccessFile raf = new RandomAccessFile(file,"rw"); //指针的位置 System.out.println(raf.getFilePointer()); raf.write('A');//只写了一个字节 System.out.println(raf.getFilePointer()); raf.write('B'); int i = 0x7fffffff;//这是最大的整数 //写一个Int值,用write方法每次只能写一个字节,如果要把i写进去就得写4次 raf.write(i >>> 24);//高8位 raf.write(i >>> 14);//高8位 raf.write(i >>> 8);//高8位 raf.write(i);//最低8位 System.out.println(raf.getFilePointer()); //打印:6 //可以直接写一个int raf.writeInt(i); //写中文 String s = "中"; byte[] gbk = s.getBytes("gbk"); //转成gbk,一个汉字两个字节 raf.write(gbk); System.out.println(raf.length());//打印:12 /** * 读文件 * */ //1,必须把指针移动到头部 raf.seek(0); //一次性读取,把文件中的内容都读取到字节数组中 byte[] buf = new byte[(int) raf.length()]; raf.read(buf); System.out.println(Arrays.toString(buf)); } }
三,字节流
1,文件输入流
1.1,InputStream,OutputStream
InputStream抽象了应用程序读取数据的方式
OutputStream抽象了应用程序写出数据的方式
1.2,EOF = end 读到-1就读到结尾
1.3,输入流基本方法
我们把键盘作为一个文件,键盘是输入,比如往记事本里写数据。实际上是从键盘文件读取了数据,然后写入到了txt文件。
所以键盘是一个输入文件,是用来读的。我们从键盘上读的东西,写到了文本文件里。所以输入流的基本方法是读
int b = in.read();读取一个字节,无符号填充到int的低八位,高八位补零。 -1是EOF
in.read(byte[] buf);读取数据填充到字节数组buf
in.read(byte[],int start,int size);读取数据到字节数组buf中,从buf的start位置开始,存放size长度的数据
1.4,输出流基本方法
out.write(int b);写出一个byte到流,b的低8位。
out.write(byte[] buf);将buf字节数组都写入到流
out.write(byte[] buf ,int start, int size);字节数组buf从start位置开始写size长度的字节到流
1.5,FileInputStream --->具体实现了在文件上读取数据
代码:
package com.amazing.jdk.learn2IO_0821.stream; import java.io.*; /** * Created by yaming on 17-8-21. * 工具类 */ public class IOUtils { /** *需求:读取指定文件内容,按照16进制输出到控制台 * 并且每输出10个byte换行。读到最后一个 */ public static void printHex(String fileName) throws IOException { //构建输入流对象,把文件作为字节流进行读操作 FileInputStream in = new FileInputStream(fileName); int b; int i=1; while ((b=in.read())!=-1){ if(b<=0xf){ //单位的数补零 System.out.print("0"); } //将整形b转换成16进制表示的字符串 System.out.print(Integer.toHexString(b)+" "); if(i++%10==0){ //换行 System.out.println(); } } //IO操作后必须关闭 in.close(); } }
1.6,FileOutputStream --->实现了向文件中写出byte数据的方法
拷贝文件代码:
package com.amazing.jdk.learn2IO_0821.stream; import java.io.*; /** * Created by yaming on 17-8-21. * 工具类 */ public class IOUtils { /** * 文件拷贝,字节批量读取 * 拷贝速度最快 * 复制文件功能,一个是读操作,另一个是写操作 * @param srcFile * @param destFile */ public static void copyFile(File srcFile,File destFile)throws IOException{ //文件不存在 if(!srcFile.exists()){ throw new IllegalArgumentException("文件"+srcFile+"不存在"); } if(!destFile.exists()){ throw new IllegalArgumentException(destFile+"不是文件"); } FileInputStream in=new FileInputStream(srcFile); FileOutputStream out=new FileOutputStream(destFile); byte[] buf=new byte[8*1024];//字节数组,相当于开辟了内存空间 int b; //从输入流中读到一个字节数组里 while ((b=in.read(buf,0,buf.length))!=-1){ //写到字节数组中去 out.write(buf,0,b); out.flush(); } in.close(); out.close(); } /** * 文件拷贝,单字节不带缓冲 * 拷贝速度最慢 * @param srcFile * @param destFile */ public static void copyFileByByte(File srcFile,File destFile)throws IOException{ //文件不存在 if(!srcFile.exists()){ throw new IllegalArgumentException("文件"+srcFile+"不存在"); } if(!destFile.exists()){ throw new IllegalArgumentException(destFile+"不是文件"); } FileInputStream fis=new FileInputStream(srcFile); FileOutputStream fos=new FileOutputStream(destFile); int d; while ((d=fis.read())!=-1){ fos.write(d); fos.flush();//也可以不刷新 } fis.close(); fos.close(); } }
1.7,DataOutputStream / DataInputStream
对 流 功能的扩展,可以更加方便的读取int ,long,字符等类型数据
比如:writeInt() / writeDouble / writeUTF()
示例代码:
package com.amazing.jdk.learn2IO_0821.stream; import java.io.*; /** * Created by yaming on 17-8-22. */ public class DataStream { public static void main(String[] args)throws IOException { String file="/home/yaming/Desktop/test"; DataOutputStream dos=new DataOutputStream(new FileOutputStream(file)); dos.writeInt(10); dos.writeInt(-10);//对write方法进行了包装 dos.writeDouble(1.7); //采用utf-8编码写出 dos.writeUTF("中国"); //utf-16be编码 dos.writeChars("中国"); dos.close(); IOUtils.printHex(file); System.out.println(); DataInputStream dis=new DataInputStream(new FileInputStream(file)); int i=dis.readInt();//对read方法进行了包装 System.out.println(i); i=dis.readInt(); System.out.println(i); double d=dis.readDouble(); System.out.println(d); String s=dis.readUTF(); System.out.println(s); dis.close(); } }
1.7,BufferedInputStream / BufferedOutputStream
这两个流类为IO提供了带缓冲区的操作,一般打开文件进行写入或读取操作时,都会加上缓冲,这种流模式提高了IO的性能
从应用程序中把输入放入文件,相当于将一缸水倒入另外一个缸中;
FileOutputStream ----->write()方法相当于一滴一滴的把水 转移 过去
DataOutputStream ----->writeXxx()方法会方便一些,相当于一瓢一瓢的把水 转移 过去
BufferedOutputStream ---->write方法更方便,相当于一瓢一瓢先放入桶中,再从桶中倒入到另一个缸中,性能提高
代码:
package com.amazing.jdk.learn2IO_0821.stream; import java.io.*; /** * Created by yaming on 17-8-21. * 工具类 */ public class IOUtils { /** * 文件拷贝,利用带缓冲的字节流 * 复制文件功能,使用buffer缓冲区 * @param srcFile * @param destFile */ public static void copyFileByBuffer(File srcFile,File destFile)throws IOException{ //文件不存在 if(!srcFile.exists()){ throw new IllegalArgumentException("文件"+srcFile+"不存在"); } if(!destFile.exists()){ throw new IllegalArgumentException(destFile+"不是文件"); } BufferedInputStream bis=new BufferedInputStream(new FileInputStream(srcFile)); BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(destFile)); int c; while ((c=bis.read())!=-1){ bos.write(c); bos.flush();//带缓冲的,必须刷新缓冲区 } bis.close(); bos.close(); } }
四,字符流
1,认知文本和文本文件
java的文本(char)是16位无符号整数,是字符的unicode编码(双字节编码)
文件是byte byte byte ....的数据序列
文本文件是文本(char)序列按照某种编码方案(utf-8,utf-16be,gbk)序列化为byte的存储结构
2,字符流(Reader, Writer)
字符的处理,一次处理一个字符
字符的底层仍然是基本的字节序列
3,字符流的基本实现
InputStreamReader 完成byte流解析为char流,按照编码解析
OutputStreamWriter 提供char流到byte流,按照编码处理
package com.amazing.jdk.learn2IO_0821.stream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; /** * Created by yaming on 17-8-23. */ public class IsrAndOswDemo { public static void main(String[] args)throws IOException { FileInputStream fis=new FileInputStream("/home/yaming/Desktop/今天"); //操作文本文件,操作一个mp3文件就没有意义了 InputStreamReader isr=new InputStreamReader(fis);//默认使用项目的编码.操作的时候要写文件默认的编码,这样读出来才不会乱码 //一次读一个字符 /* int c; while ((c=isr.readme())!=-1){ System.out.print((char) c); } */ //一次读一个字符数组 char[] buffer=new char[8*1024]; int c; //批量读取,放入buffer字符数组中,从第0个位置放,最多放buffer.length个 //返回的是读到的字符个数 while ((c=isr.read(buffer,0,buffer.length))!=-1){ String s=new String(buffer,0,c); System.out.print(s); } } }
4,FileReader / FileWriter
package com.amazing.jdk.learn2IO_0821.stream; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; /** * Created by yaming on 17-8-24. */ public class ReaderWriter { public static void main(String[] args)throws IOException { /** * 字符流 */ Long time1=System.currentTimeMillis(); FileReader fr=new FileReader("/home/yaming/Desktop/txt1"); FileWriter fw=new FileWriter("/home/yaming/Desktop/txt2"); /*char[] buffer=new char[1024]; int c; while ((c=fr.readme(buffer,0,buffer.length))!=-1){ fw.write(buffer,0,c); fw.flush(); } //8毫秒 */ int a; while ((a=fr.read())!=-1){ System.out.print(a); fw.write(a); fw.flush(); } //93毫秒 fr.close(); fw.close(); Long time2=System.currentTimeMillis(); System.out.println("readme()时长:"+(time2-time1)); } }
5,字符流的过滤器
BufferedReader ---->readLine 一次读一行
BufferedWriter/PrintWriter ----->一次写一行
package com.amazing.jdk.learn2IO_0821.stream; import java.io.*; /** * Created by yaming on 17-8-24. */ public class BufferedReaderWriter { public static void main(String[] args)throws IOException { /** * 字符缓冲流 */ BufferedReader br=new BufferedReader( new InputStreamReader( new FileInputStream("/home/yaming/Desktop/test"))); /*BufferedWriter bw=new BufferedWriter( new OutputStreamWriter( new FileOutputStream("/home/yaming/Desktop/test2") ) );*/ PrintWriter pw=new PrintWriter("/home/yaming/Desktop/test2");//可以用来替换BufferedWriter,比较简单 String line; while ((line=br.readLine())!=null){ System.out.println(line);//一次读一行,不能识别换行 /* bw.write(line); //单独写换行操作 bw.newLine(); bw.flush(); */ pw.println(line); pw.flush(); } br.close(); //bw.close(); pw.close(); } }