package sc.IO; import java.io.File; import java.io.IOException; //Flie类:File类在java中表示(带路径的)文件或者目录。 public class FileTest { public static void main(String[] args) throws IOException { // 路径分隔符:在win系统(;)号 mac/unix/linux(:)号 System.out.println(File.pathSeparator);//输出结果:; /** * 名称分隔符 * win( \) 号 * mac/unix/linux(/) 号 */ System.out.println(File.separator);//输出结果:\(反斜杠) //File常用属性和方法 // 给定路径创建File对象 //[1]正规写法 File file=new File("D:"+File.separator+"gameproject"+File.separator+"a.txt"); System.out.println(file);//输出结果:D:\gameproject\a.txt //[2]两种方法结果一样,但正规写法是上面第一种 //File file1 = new File("D:\\gameproject\\b.txt"); //System.out.println(file1);//输出结果:D:\gameproject\a.txt // 测试文件基本属性 // 测试应用程序是否可以执行此抽象路径名表示的文件。 System.out.println(file.canExecute());//输出结果:true //测试应用程序是否可以读取此抽象路径名表示的文件。 System.out.println(file.canRead());//输出结果:true //测试应用程序是否可以修改此抽象路径名表示的文件。 System.out.println(file.canWrite());//输出结果:true //返回true 也就是说这个这个文件是存在的,可以读取和修改 // 文件的创建( exists()测试此抽象路径名表示的文件或目录是否存在。) //创建文件时会抛出检查时异常IOException //createNewFile()当且仅当不存在具有此抽象路径名指定名称的文件时,就创建一个新的空文件。 if(!file.exists()){ boolean r; try { r = file.createNewFile(); System.out.println(r);//输出结果:true } catch (IOException e) { e.printStackTrace(); } } //文件删除 //file.delete(); //File的路径相关 File file1 = new File("D:\\gameproject\\b.txt"); File file2 = new File("b.txt"); // 获取file的绝对路径 System.out.println(file1.getAbsolutePath());//输出结果:D:\gameproject\b.txt // 获取file的创建时的路径字符串 System.out.println(file1.getPath());//输出结果:D:\gameproject\b.txt // 获取文件或者目录的名字(此一级) System.out.println(file1.getName());//输出结果:b.txt // 获取文件或者目录的父目录(上一级,没有返回null) System.out.println(file1.getParent());//输出结果:D:\gameproject // 获取file的绝对路径 //注意:如果file是相对路径,相对路径的当前路径是工程目录 System.out.println(file2.getAbsolutePath());//输出结果:D:\gameproject\day03\b.txt(当前程序目录) // 获取file的创建时的路径字符串 System.out.println(file2.getPath());//输出结果:b.txt // 获取文件或者目录的名字(此一级) System.out.println(file2.getName());//输出结果:b.txt // 获取文件或者目录的父目录(上一级,没有返回null) System.out.println(file2.getParent());//输出结果:null // 创建目录(一次只能创建一个目录) File file5=new File("D:"+File.separator+"gameproject"+File.separator+"b"); if(!file5.exists()){ boolean r; r = file5.mkdirs(); System.out.println(r);//输出结果:true } //list():返回一个file表示的目录中的子目录或者文件,字符串数组类型 //listFiles():返回一个file表示的目录中的子目录或者文件,File数组类型 // 需求:遍历d:\gameproject目录 // list返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。 File file3=new File("D:"+File.separator+"gameproject"); String[] list6 = file3.list(); for(String list7:list6){ System.out.println(list7); //将此抽象路径名转换为一个路径名字符串。 File f = new File(file3.getPath()); // 测试此抽象路径名表示的文件是否是一个目录。 if(f.isDirectory()) { System.out.println(" 目录"); }else { System.out.println(" 文件"); } }//输出结果: // listFiles(); File fil=new File("D:"+File.separator+"gameproject"); File[] listFiles = fil.listFiles(); for (File f : listFiles) { System.out.print(f.getName()); if(f.isDirectory()) { System.out.println(" 目录"); }else { System.out.println(" 文件"); } } } }
package sc.IO; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; /*1.3InputStream/OutputStream InputStream 是所有字节输入流的抽象父类,提供了 read 读取一个字节 read(byte[] buf) 读取一定量的字节到缓冲区数组 buf中。 OutputStream 是所有字节输出流的抽象父类,提供了 write() 写入一个字节 write(byte[] buf) 写入一定量的字节到输出流 FileInputStream 文件字节输入流,专门用于从文件中读取字节到程序内存中。 FileOutputStream 文件字节输出流,专门用于从内存中写入字节到文件中。 * */ public class InputStreamOutputStream { public static void main(String[] args) { // 需求:读取一个文件中的一个字节(文件中有:abc) File file = new File("d:\\gameproject\\a.txt"); // 【1】创建管道 FileInputStream in=null; try { in=new FileInputStream(file); // 【2】从管道读取一个字节 int t; t = in.read(); System.out.println(t);//输出结果:97 //得到的是默认编码集的编码, System.out.println((char)t);//输出结果:a t = in.read();//输出结果:98 t = in.read();//输出结果:99 t = in.read(); System.out.println(t);//输出结果:-1 //如果以读完就返回-1 } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }
// 【3】关闭流管道(如果不关闭的话会一直占用通道)
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
package sc.IO; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; public class InputStreamOutputStream { public static void main(String[] args) { // 需求:读取一个文件中的一个字节(文件中有:abc) File file = new File("d:\\gameproject\\a.txt"); StringBuilder sb = new StringBuilder(); // 循环读取一个字节 FileInputStream in=null; int a; try { in=new FileInputStream(file); while((a=in.read())!=-1){ sb.append((char)a); } System.out.println(sb.toString());//输出结果:abc } catch (FileNotFoundException e1) { e1.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } try { in.close(); } catch (IOException e) { e.printStackTrace(); } } }
package sc.IO; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; public class InputStreamOutputStream { public static void main(String[] args) { // 需求:一次读取多个字节(文件中有:abc) File file = new File("d:\\gameproject\\a.txt"); StringBuilder sb = new StringBuilder(); // 【1】创建管道 FileInputStream in=null; try { in=new FileInputStream(file); //【2】从管道读取多个字节到缓冲区 //创建一个字节数组 byte[] buf = new byte[2]; int len; len = in.read(buf); for(byte b:buf) { System.out.println((char)b+"\t");//输出结果:a b } System.out.println(len);//输出结果:2 //在GBK中一个字母占一个字节,因为文件中有abc 我要求每次读取两个字节,所以第一次读取正常 len = in.read(buf); for(byte b:buf) { System.out.println((char)b+"\t");//输出结果:c b } System.out.println(len);//输出结果:1 //在GBK中一个字母占一个字节,因为文件中有abc 我要求每次读取两个字节,所以第一次读取已经读完2个,所以第二次读取1个, b为上次读取残留 len = in.read(buf); for(byte b:buf) { System.out.println((char)b+"\t");//输出结果:c b } System.out.println(len);//输出结果:-1 //在GBK中一个字母占一个字节,因为文件中有abc 我要求每次读取两个字节,所以第一次读取已经读完2个,所以第二次读取1个,第3次读取已经没了,所以返回-1 ,c b为上次读取残留 } catch (FileNotFoundException e1) { e1.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } try { in.close(); } catch (IOException e) { e.printStackTrace(); } // 【3】关闭流管道 try { in.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
package sc.IO; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; public class InputStreamOutputStream { public static void main(String[] args) { // 需求:一次读取多个字节(文件中有:abc) File file = new File("d:\\gameproject\\a.txt"); StringBuilder sb = new StringBuilder(); // 通过循环读取文件 FileInputStream in=null; int len; try { in=new FileInputStream(file); byte[] buf = new byte[2]; while( (len=in.read(buf)) != -1 ){ // 读取的内容是原始二进制流,需要根据编码的字符集解码成对于字符 //把buf中的前len个长度的字符转换为字符串 String str = new String(buf,0,len); sb.append(str); } System.out.println(sb.toString());//输出结果:abc } catch (FileNotFoundException e1) { e1.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } try { in.close(); } catch (IOException e) { e.printStackTrace(); } // 【3】关闭流管道 try { in.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
package sc.IO; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; public class InputStreamOutputStream { public static void main(String[] args) { // 需求:用utf8一次读取多个字节(文件中有:abc) File file = new File("d:\\gameproject\\aa.txt"); StringBuilder sb = new StringBuilder(); // 通过循环读取文件 FileInputStream in=null; int len; try { in=new FileInputStream(file); byte[] buf = new byte[2]; while( (len=in.read(buf)) != -1 ){ // 读取的内容是原始二进制流,需要根据编码的字符集解码成对于字符 //把buf中的前len个长度的字符转换为字符串 String str = new String(buf,0,len,"utf8"); sb.append(str); } System.out.println(sb.toString());//输出结果:abc(??是BOM乱码,没有通过平台创建的utf8文件有BOM) //BOM占三个字节,很多软件通过BOM来识别这个文件是否是UTF-8编码,所以win系统自动加上BOM } catch (FileNotFoundException e1) { e1.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } try { in.close(); } catch (IOException e) { e.printStackTrace(); } // 【3】关闭流管道 try { in.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
package sc.IO; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class FlieOut { public static void main(String[] args) throws IOException { File file=new File("D:\\gameproject\\a.txt"); FileOutputStream out = null; // 【1】创建输出流管道 out = new FileOutputStream(file); // 【2】写入数据到管道中 // 一次写入一个字节 /* out.write(97); out.write(98); out.write(99); */ // 一次写入多个字节 String str = "hello world"; // gbk /*字符数组转换为默认编码的byte字节数组 byte[] buf = str.getBytes(); out.write(buf); */ //字符数组转换为UTF-8编码的byte字节数组 byte[] buf = str.getBytes("UTF-8"); out.write(buf); System.out.println("写入完成!"); out.close(); } }
package sc.IO;
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class Fileout { public static void main(String[] args) throws IOException { //要求:把一张webwxgetmsgimg.gif(图,视频,音频)复制到D:\\gameproject\\显示它的复制进度 File oriFile=new File("C:\\Users\\asus\\Desktop\\新建文件夹\\webwxgetmsgimg.gif") ; File toFile=new File("D:\\gameproject\\webwxgetmsgimg.gif"); long to = oriFile.length(); // 文件大小 long cp = 0; // 已复制完成的大小 float pr = 0.0f; FileInputStream in = new FileInputStream(oriFile);//读取 FileOutputStream out = new FileOutputStream(toFile);//写出 // 一次读取1kb byte[] buf = new byte[1024]; int len; while( (len=in.read(buf)) != -1) { out.write(buf, 0, len); cp += len; pr = cp*1.0f/to; System.out.println(pr); } in.close();//关闭通道 out.close();//关闭通道 System.out.println("复制完成!"); } }
注意:
[1]字符串写入文件时一定会存在编码问题
[2]使用utf8编码写入文件时,如果不含中文时,win系统会对文件的编码造成误判。(因为没有BOM)
[3] 通过字节流写入文件时,向管道写入一个字节,该字节立即写入文件中。
总结
InputStream/OutputStream 用于字节的读写。主要用于读取二进制文件(图片、音频、视频),也可以读取文件性文件。
用字节流来读取文本性文件时,按字节读容易造成乱码。此时用字符来读取。
FileReader 文件字符输入流,专门用于读取默认字符编码文本性文件。
FileWriter 文件字符输出流,专门用于写入默认字符编码的文本性文件。
为了提高效率,FileWriter内部存在一个字节缓冲区,用于对待写入的字符进行统一编码到字节缓冲区,一定要在关闭流之前,调用flush方法刷新缓冲区。
package sc.IO; /*Reader/Writer Reader 是字符输入流的抽象父类,提供了 read 一次读取一个字符 read(char[] cbuf) 一次读取多个字符到字符缓冲区cbuf,返回长度表示读取的字符个数。 Writer 是字符输出流的抽象父类,提供了 write write(char[] cbuf) write(string) * */ import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.Arrays; public class file01 { public static void main(String[] args) throws IOException { File file = new File("D:\\gameproject\\a.txt"); // FileReader只能读取平台默认编码的文本性文件(hello world I Love You) FileReader reader = new FileReader(file); // [1]一次读取一个字符 int c; c = reader.read(); System.out.println((char)c);//输入结果:h c = reader.read(); c = reader.read(); c = reader.read(); System.out.println((char)c);//输入结果:l // 【2】一次读取多个字符到cbuf中 char[] cbuf = new char[2]; int len; len = reader.read(cbuf); System.out.println(Arrays.toString(cbuf));//输入结果[o, ] System.out.println(len);//输入结果2 len = reader.read(cbuf); len = reader.read(cbuf); len = reader.read(cbuf); System.out.println(Arrays.toString(cbuf));//输入结果[d, ] System.out.println(len);//输入结果:2 char[] cbuf1 = new char[2]; int len1; StringBuilder sb = new StringBuilder(); while( (len=reader.read(cbuf1)) != -1 ) { sb.append(cbuf1,0,len); } System.out.println(sb);//输入结果:I Love You } }
注意:
[1]win平台默认的utf8编码的文本性文件带有BOM,java转换流写入的utf8文件不带BOM。所以用java读取手动创建的utf8文件会出现一点乱码(?hello中国,?是bom导致的)
[2] 一句话:用字符集编码,一定用字符集解码!!
package sc.IO; import java.io.File; import java.io.FileWriter; import java.io.IOException; public class while01 { public static void main(String[] args) throws IOException { File file = new File("D:\\gameproject\\a.txt"); // 【1】创建管道 FileWriter writer = new FileWriter(file); // a.一次写入一个字符 writer.write('中'); writer.write('国'); // b.一次写入多个字符 char[] cbuf = {'h','e','l','l','o','中','国'}; writer.write(cbuf); // 【2】写入字符 // c.一次写入一个字符串 String str = "hello你好"; writer.write(str); // 【3】刷新字节缓冲区(就是把缓存区的字符写入文件) writer.flush(); // 【4】关闭流通道 writer.close(); System.out.println("写入完成"); //最后结果:中国hello中国hello你好 } }
package cn.sxt07.inputsteamreader; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; /**转换流 InputStreamReader 继承于Reader,是字节流通向字符流的桥梁,可以把字节流按照指定编码 解码 成字符流。 OutputStreamWriter 继承于Writer,是字符流通向字节流的桥梁,可以把字符流按照指定的编码 编码 成字节流。 * 把一个字符串以utf8编码写入文件 */ public class Test01 { public static void main(String[] args) throws IOException { String str = "hello中国"; File file = new File("d:\\javatest\\g.txt"); // 【1】创建管道 FileOutputStream out = new FileOutputStream(file);//字节输出流 OutputStreamWriter writer = new OutputStreamWriter(out, "utf8");//字符转换为utf8 // 【2】写入管道 writer.write(str); // 【3】刷新缓冲区 writer.flush(); // 【4】关闭管道 out.close(); writer.close(); System.out.println("写入完成"); } }
package cn.sxt07.outputstreamwriter; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; /** * 读取utf8编码的文本文件 */ public class Test01 { public static void main(String[] args) throws IOException { File file = new File("d:\\javatest\\h-win.txt"); // 【1】建立管道 FileInputStream in = new FileInputStream(file); InputStreamReader reader = new InputStreamReader(in, "UTF-8"); char[] cbuf = new char[2]; int len; StringBuilder sb = new StringBuilder(); while( (len=reader.read(cbuf))!=-1 ) { sb.append(cbuf, 0, len); } System.out.println(sb.toString()); } }
BufferedReader/BufferedWriter
BufferedReader 继承于Reader,提供了
read
read(char[] cbuf)
readLine() 用于读取一行文本,实现对文本的高效读取。
BufferedReader 初始化时需要一个reader,本质上BufferedReader在reader的基础上增加readLine()的功能。
BufferedWriter继承于Writer,提供了
write
write(char[] cbuf)
write(string)
newline() 写入一个行分隔符。
package cn.sxt08.bufferedreader; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; public class Test01 { public static void main(String[] args) throws IOException { // 按行读取gbk文本性文件 File file = new File("d:\\javatest\\i.txt"); // 【1】创建管道(默认的是GBK,要想读utf8就要用转换流) FileReader reader = new FileReader(file); BufferedReader br = new BufferedReader(reader); // 【2】读取一行(BufferedReader是读取文本的整一行) /* String line = br.readLine(); line = br.readLine(); line = br.readLine(); line = br.readLine(); */ String line;//f返回的不在是-1而是null while( (line=br.readLine()) != null) { System.out.println(line); } } }
package sc.IO; import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; public class test01 { public static void main(String[] args) throws IOException { File file = new File("D:\\gameproject\\a.txt"); // 【1】创建utf8管道 FileOutputStream out = new FileOutputStream(file); OutputStreamWriter writer = new OutputStreamWriter(out, "UTF-8"); BufferedWriter bw = new BufferedWriter(writer); // 【2】写入一行 bw.write("窗前明月光,"); bw.newLine();//换行 bw.write("疑似地上霜。"); // for win bw.write("\r\n");//换行 // for unix/linux/mac系统:bw.write("\n"); bw.write("举头望明月,"); bw.newLine(); // 【3】flush bw.flush(); // 【4】关闭管道 bw.close(); writer.close(); } }