文件在程序中是以流的形式存在的
创建文件
代码:
import java.io.File; import java.io.IOException; /** * @author ZHR * @version 1.0 **/ public class newFile { public static void main(String[] args) { //使用方式一创建 File file = new File("c:/IO/newFile1.txt"); try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } System.out.println("创建成功"); //使用方式二创建 File parentFile = new File("c:/IO"); File child = new File(parentFile,"file2.txt"); try { child.createNewFile(); } catch (IOException e) { e.printStackTrace(); } System.out.println("创建成功"); //使用方式三创建 File file3 = new File("c:/IO","file3.txt"); try { file3.createNewFile(); System.out.println("创建成功"); } catch (IOException e) { e.printStackTrace(); } } }
注意事项:
1.目录分隔符可以用 / 也可以用 \\,两个效果一样
2.使用 file.createNewFile() 方法才是创建文件的步骤,但是这里需要添加异常的判断,此处用的是try-catch
3.由于我的笔记本只有C盘,创建文件由于权限导致失败,这里,我在C盘里面创建一个IO文件夹,增加了一层目录,解决了问题
File的常用方法
import java.io.File; /** * @author ZHR * @version 1.0 **/ public class FileMethod { public static void main(String[] args) { //演示文件的常用方法 //创建文件 File file = new File("c:/IO\\newFile1.txt"); //调用相应的方法: System.out.println("文件的名字是:"+file.getName()); System.out.println("文件的绝对路径是:"+file.getAbsolutePath()); System.out.println("文件的父级目录是:"+file.getParent()); System.out.println("文件的大小(字节)是:"+file.length()); System.out.println("文件是否存在:"+file.exists()); System.out.println("是不是一个文件:"+file.isFile()); System.out.println("是不是一个目录:"+file.isDirectory()); } }
这里文件的大小采用 Utf-8 的编码,中文占三个字符,英文占一个字符。
文件删除
这里既可以删除文件,也可以删除目录。
代码:
public void m(){ File file = new File("c:\\IO/io1"); //使用boolean delete()方法进行删除 //首先判断是否找到 if(file.exists()){ //判断是否删除成功 if(file.delete()){ System.out.println("成功删除"); } else{ System.out.println("删除失败"); } } else{ System.out.println("没找到该文件"); } }
注意:如果目录里面有文件,则删除失败
创建目录
public void m1(){ File file = new File("c:/IOstream/io1"); if (file.exists()){ System.out.println("该文件已经存在"); } else{ if(file.mkdirs()){ System.out.println("创建成功"); } else{ System.out.println("创建失败"); } } }
注意:这里要使用mkdirs()方法创建多级目录,mkdir()只能创建一级目录
这里演示将文本文件中的内容显示到屏幕上
使用read()方法
import org.junit.Test; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; /** * @author ZHR * @version 1.0 **/ //演示字节输入流 public class FileInputStream_ { public static void main(String[] args) { //创建一个txt文件,读取txt文件中的内容并且输出到控制台上 File file = new File("c:/io/file.txt"); //创建FileInputStream对象时会报异常,需要处理 int read = 0; FileInputStream fileInputStream = null; try { fileInputStream = new FileInputStream(file); //从该输入流读取一个字节的数据,如果没有输入可用,则方法会阻止,如果返回-1,表示读取完毕 while((read=fileInputStream.read())!=-1){ //需要将int类型的read转换为char System.out.print((char)read); } } catch (IOException e) { e.printStackTrace(); }finally { //这里需要关闭流,否则将会资源浪费 try { fileInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } }
使用read(Byte[] byte)方法
/** * @author ZHR * @version 1.0 **/ import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; public class demo { public static void main(String[] args) { File file = new File("c:/io/file.txt"); FileInputStream fileInputStream = null; byte[] bytes = new byte[8]; int readLen = 0; try { fileInputStream = new FileInputStream(file); while((readLen = fileInputStream.read(bytes))!=-1){ System.out.print(new String(bytes,0,readLen)); } } catch (IOException e) { e.printStackTrace(); } finally { try { fileInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } }
注意事项:
1.创建 FileInputStream对象时需要以 File对象为参数
2.为了避免资源的浪费,需要在finally中将资源释放,所以需要将 FileInputStream对象定义在try外面,设置为空
3.在创建FileInputStream对象和使用read()方法时都会抛出异常,这里就选取共同的父类异常IOException
4.最后使用close()方法也会抛出异常
5.int read()方法从输入流读取一个字符并返回该字符,输出时需要强转为char类型;int read(Byte[] byte),是一次性读取byte.length个字符并将这些字符的ASCII码保存到数组byte中,返回读取字符的个数(可能不够byte.length个字符),这里需要记录一个当前读取字符的个数,再通过String的构造器输出;上述两方法如果读到文件末尾,返回-1
代码:
/** * @author ZHR * @version 1.0 **/ import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class FileOutputStream_ { public static void main(String[] args) { //在写文件的时候,如果文件不存在,会自动创建文件 File file = new File("src/write.txt"); FileOutputStream fileOutputStream = null; try { //以这种方式创建是覆盖 //fileOutputStream = new FileOutputStream(file); //以这种方式创建是追加到文件末尾 fileOutputStream = new FileOutputStream(file,true); //写入一个字节 使用void write(int b) fileOutputStream.write('a');//这里会发生转换 //写入字符串 使用void write(byte[] b) String str = "hello"; fileOutputStream.write(str.getBytes());//调用字符串的方法getBytes()将字符串转换为byte[]数组 //写入字符串 使用void write(byte[] b ,int off , int len) fileOutputStream.write(str.getBytes(),2,3); fileOutputStream.write('\n'); } catch (IOException e) { e.printStackTrace(); }finally { try { fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } }
注意:
1.以这种方式创建对象是覆盖上次写的文件
fileOutputStream = new FileOutputStream(file);
以这种方式创建对象是追加到文件末尾
fileOutputStream = new FileOutputStream(file,true);
2.在写文件的时候,如果文件不存在,会自动创建
3.注意上述的三种写方法,注意在字符串的写方法时,需要调用str.getBytes()方法将字符串转换为byte数组
文件拷贝
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; /** * @author ZHR * @version 1.0 **/ public class FileCopy { public static void main(String[] args) { String filePath1 = "c:/io/copy.jpg"; String filePath2 = "c:/io/copy1.jpg"; FileOutputStream fileOutputStream = null; FileInputStream fileInputStream = null; try { fileOutputStream = new FileOutputStream(filePath2); fileInputStream = new FileInputStream(filePath1); byte[] buf = new byte[1024]; int readLen = 0; while ((readLen=fileInputStream.read(buf))!=-1) { fileOutputStream.write(buf,0,readLen); } } catch (IOException e) { e.printStackTrace(); }finally { try { fileInputStream.close(); fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } }
注意:
这里演示的是图片的拷贝,由于图片太大了,所以采取byte[] 数组的读方法;在写入新文件的时候,需要记录当前读取的字符个数,然后用write(byte[] b , int off ,int len)方法写入,因为读取的字符大小不一定等于b.length
FileReader演示
使用fileReader.read()方法输出
import java.io.FileReader; import java.io.IOException; /** * @author ZHR * @version 1.0 **/ public class FileReader_ { public static void main(String[] args) { FileReader fileReader = null; int ch = ' ' ; try { fileReader = new FileReader("c:/io/file.txt"); //注意:这里fileReader.read()返回的是int值,下面输出的时候需要强转成char while((ch=fileReader.read())!=-1){ System.out.print((char)ch); } }catch (IOException e){ e.printStackTrace(); }finally { try { fileReader.close(); } catch (IOException e) { e.printStackTrace(); } } } }
注意:这里fileReader.read()返回的是int值,下面输出的时候需要强转成char
使用fileReader.read(chars)方式输出
import java.io.FileReader; import java.io.IOException; /** * @author ZHR * @version 1.0 **/ public class FileReader_ { public static void main(String[] args) { FileReader fileReader = null; int readLen = 0; char[] chars = new char[8]; try { fileReader = new FileReader("c:/io/file.txt"); //注意:这里fileReader.read()返回的是int值,下面输出的时候需要强转成char while((readLen=fileReader.read(chars))!=-1){ System.out.print(new String(chars,0,readLen)); } }catch (IOException e){ e.printStackTrace(); }finally { try { fileReader.close(); } catch (IOException e) { e.printStackTrace(); } } } }
FileWriter演示
import java.io.FileWriter; import java.io.IOException; /** * @author ZHR * @version 1.0 **/ public class FileWriter_ { public static void main(String[] args) { FileWriter fileWriter = null; try { fileWriter = new FileWriter("c:/io/demo.txt",true); //写入一个字符 fileWriter.write('a'); fileWriter.write('\n'); //写入指定char数组 char[] chars = {'a','b','c','d'}; fileWriter.write(chars); fileWriter.write('\n'); //写入char数组的指定部分 fileWriter.write(chars,0,2); fileWriter.write('\n'); //写入字符串进去 fileWriter.write("你好java!"); fileWriter.write('\n'); //写入字符串的部分指定部分 fileWriter.write("北京上海天津",0,2); }catch (IOException e){ e.printStackTrace(); }finally { //对于FileWriter,一定要关闭流或者flush才能真正把数据写入文件(会创建文件,但是不会写入文件) try { fileWriter.flush(); } catch (IOException e) { e.printStackTrace(); } } } }
注意:对于FileWriter,一定要关闭流或者flush才能真正把数据写入文件(会创建文件,但是不会把数据写入文件),可以理解close为flush+关闭
处理流(包装流)和节点流的区别和联系
1.节点流是底层流,直接与数据源相连
2.处理流包装节点流,可以消除不同节点流的实现差异,可以提供更加方便的方法来完成输入和输出
3.处理流不与数据源相连,可以屏蔽底层差异
处理流在创建时需要把节点流当作实参传进去,从而实现包装节点流的效果
BufferedReader代码演示
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; /** * @author ZHR * @version 1.0 **/ public class BufferReader_ { public static void main(String[] args) throws IOException{ //BufferedReader读取文本文件,其他文件可能会出现损失 BufferedReader bufferedReader = null; bufferedReader = new BufferedReader(new FileReader("c:/io/demo.txt")); String s; //注意下面这个写法! while((s = bufferedReader.readLine())!=null){ System.out.println(s); } bufferedReader.close(); } }
BufferedWriter代码演示
import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; /** * @author ZHR * @version 1.0 **/ public class BufferedWriter_ { public static void main(String[] args) throws IOException { //在FileWriter构造器中后面加true,实现了追加效果 BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("c:/io/demo1.txt",true)); //使用write方法写入 bufferedWriter.write("123456"); //插入一个换行 bufferedWriter.newLine(); bufferedWriter.write("456456"); bufferedWriter.close(); } }
注意:
1.BufferedReader和BufferedWriter属于字符流,关闭流时只需要关闭外层流即可,包装流会对节点流进行操作,自动关闭节点流
2.BufferedWriter在FileWriter构造器中后面加true,实现了追加效果
3.跟FileWriter一样,需要close()后才能将文件写入
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("c:/io/demo1.txt",true));
文件拷贝
注意:BufferedReader和BufferedWriter是按照字符操作的,不要操作二进制文件,会引起文件的损坏
代码演示
import java.io.*; /** * @author ZHR * @version 1.0 **/ public class BufferedCopy { public static void main(String[] args) throws IOException { //BufferedReader和BufferedWriter是按照字符操作的,不要操作二进制文件,会引起文件的损坏 BufferedReader bufferedReader = new BufferedReader(new FileReader("c:/io/demo.txt")); BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("c:/io/demoCopy.txt")); //这里使用一行一行的读取,一行一行的写入 String s; while((s = bufferedReader.readLine())!=null){ bufferedWriter.write(s); bufferedWriter.newLine(); } bufferedReader.close(); bufferedWriter.close(); } }
注意这种代码的写法
String s; while((s = bufferedReader.readLine())!=null){ bufferedWriter.write(s); bufferedWriter.newLine(); }
这里演示二进制文件(图片,视频)的拷贝
import java.io.*; /** * @author ZHR * @version 1.0 **/ public class BufferStream { public static void main(String[] args) throws IOException { BufferedInputStream bufferedinputStream= new BufferedInputStream(new FileInputStream("c:/io/copy.jpg")); BufferedOutputStream bufferedoutputstream = new BufferedOutputStream(new FileOutputStream("c:/io/copyNew.jpg")); byte[] b = new byte[1024]; int readLen = 0; while((readLen = bufferedinputStream.read(b))!=-1){ bufferedoutputstream.write(b,0,readLen); } bufferedoutputstream.close(); bufferedinputStream.close(); } }
ObjectOutputStream
import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.Serializable; /** * @author ZHR * @version 1.0 **/ public class ObjectOutputStream_ { public static void main(String[] args) throws IOException { //序列化后,保存的文件格式,不是文本格式,而是按照它的格式 ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("c:/io/oos.dat")); objectOutputStream.write(1); //int-> Integer (实现了Serializable接口) objectOutputStream.writeUTF("我是张浩然"); //String (实现了Serializable接口) objectOutputStream.writeBoolean(true); //boolean ->Boolean (实现了Serializable接口) objectOutputStream.writeChar('a'); //char -> Char (实现了Serializable接口) objectOutputStream.writeObject(new Dog("丢丢",4)); objectOutputStream.close(); } } //这里需要注意,要写入自定义类时,需要实现接口Serializable class Dog implements Serializable{ private String name; private int age; public Dog(String name, int age) { this.name = name; this.age = age; } }
注意:
1.要写入自定义类时,需要实现接口Serializable
2.这里不能使用write()方法,该方法只输入数据,不指明数据类型
ObjectInputStream
import java.io.FileInputStream; import java.io.IOException; import java.io.ObjectInputStream; /** * @author ZHR * @version 1.0 **/ public class ObjectInputStream_ { public static void main(String[] args) throws IOException, ClassNotFoundException { ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("c:/io/oos.dat")); //读取(反序列化)的顺序一定要和保存(序列化)顺序一致 System.out.println(objectInputStream.readInt()); System.out.println(objectInputStream.readUTF()); System.out.println(objectInputStream.readBoolean()); System.out.println(objectInputStream.readChar()); //这里需要添加异常ClassNotFoundException Object dog1 = objectInputStream.readObject(); System.out.println(dog1); //如果想要Dog类的方法,需要向下转型 Dog dog = (Dog)dog1; System.out.println(dog.toString()); objectInputStream.close(); } }
注意:
1.读取(反序列化)的顺序一定要和保存(序列化)顺序一致
2.需要添加异常ClassNotFoundException
3.如果想要Dog类的方法,需要向下转型
细节:
目的是为了指定编码格式对文件进行操作
InputStreamReader
举例:先将字节流转换成字符流,指定编码格式(gbk),然后通过处理流进行包装,完成操作
import java.io.*; /** * @author ZHR * @version 1.0 **/ public class InputStream_ { public static void main(String[] args) throws IOException { //显示乱码 BufferedReader bf = new BufferedReader(new FileReader("c:/io/demo.txt")); System.out.println(bf.readLine()); bf.close(); //通过转换流,接除乱码问题 //将字节流转换为字符流 InputStreamReader is = new InputStreamReader(new FileInputStream("c:/io/demo.txt"),"gbk"); //对字符流进行包装 BufferedReader bf1 = new BufferedReader(is); System.out.println(bf1.readLine()); //只需要关闭外层流 bf1.close(); } }
OutputStreamWriter
指定编码格式写入文件
import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; /** * @author ZHR * @version 1.0 **/ public class OutputStreamWriter_ { public static void main(String[] args) throws IOException { String charset = "gbk"; OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("c:/io/osw.txt"),charset); osw.write("hi,我是张浩然"); osw.close(); } }
打印流只有输出,没有输入!
字节打印流 PrintStream
import java.io.IOException; import java.io.PrintStream; /** * @author ZHR * @version 1.0 **/ public class PrintStream_ { public static void main(String[] args) throws IOException { //在默认情况下,PrintStream输出的位置是标准输出,即显示器 PrintStream ps = System.out; ps.println("hi,你好"); //因为print底层使用的是write,所以我们可以直接调用write进行打印/输出 ps.write("你好".getBytes()); //我们可以修改打印输出的位置 System.setOut(new PrintStream("c:/io/demo.txt")); System.out.println("\nhi,ps"); ps.close(); } }
字符打印流 PrintWriter
import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; /** * @author ZHR * @version 1.0 **/ public class PrintWriter_ { public static void main(String[] args) throws IOException { //写到该文件里面 PrintWriter printWriter = new PrintWriter(new FileWriter("c:/io/demo.txt")); printWriter.println("hi"); //如果没有关闭,字符流是没有办法写进去的 printWriter.close(); } }
Properties读取文件
import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.Properties; /** * @author ZHR * @version 1.0 **/ public class Propertier_ { public static void main(String[] args) throws IOException { //properties读配置文件 //1.创建对象 Properties properties = new Properties(); //2.加载配置文件 properties.load(new FileReader("src/mysql.properties")); //3.把k-v显示控制台 properties.list(System.out); //4.根据key获取对应的值 System.out.println(properties.getProperty("pwd")); } }
Properties来创建/修改配置文件
import java.io.*; import java.util.Properties; /** * @author ZHR * @version 1.0 **/ public class Propertier_ { public static void main(String[] args) throws IOException { //properties来创建配置文件 //1.创建对象 Properties properties = new Properties(); //2.创建 properties.setProperty("charset","utf8"); properties.setProperty("user","Tom"); properties.setProperty("pwd","123456"); //3.将k-v存储文件中 properties.store(new FileOutputStream("src/mysql2.properties"),null); } }
setProperty如果没有该key,就是创建;如果有,就是修改