文件

文件介绍

image.png
image.png

常见的文件操作

创建文件

image.pngimage.png

方式一

  1. public static void main(String[] args) {
  2. File newFile2 = new File("d:\\news2.txt"); //一个 \ 为转义字符
  3. try {
  4. newFile2.createNewFile(); //会抛出一个异常 ,返回值是一个布尔值
  5. System.out.println("文件创建成功");
  6. } catch (IOException e) {
  7. e.printStackTrace();
  8. }
  9. }

注意这里的File对象,只是一个对象,只有在执行createNewFile方法,才会真正创建文件。

方式二

  1. public static void main(String[] args) {
  2. File newFile1 = new File("d:\\","news2.txt"); //注意不能写成d,可以写成d:/
  3. try {
  4. newFile1.createNewFile(); //会抛出一个异常
  5. System.out.println("文件创建成功");
  6. } catch (IOException e) {
  7. e.printStackTrace();
  8. }
  9. }

方式三(不常用)

  1. public static void main(String[] args) {
  2. File file = new File("d:\\");
  3. File newFile3 = new File(file,"news3.txt");
  4. try {
  5. newFile3.createNewFile();
  6. } catch (IOException e) {
  7. e.printStackTrace();
  8. }
  9. }

其它常用方法

  1. public static void main(String[] args) {
  2. File file = new File("d:\\news1.txt");
  3. System.out.println(file.getName()); //获取文件名 news1.txt
  4. System.out.println(file.getParent()); //文件父级目录 d:\
  5. System.out.println(file.length()); // 文件大小(字节)
  6. System.out.println(file.exists()); // 文件是否存在 (因为上面已经创建所以为T)
  7. System.out.println(file.isFile()); // 是不是一个文件 T
  8. System.out.println(file.isDirectory()); //是不是一个目录 F
  9. }

image.png

删除

  1. public static void main(String[] args) {
  2. File file = new File("d:\\news1.txt");
  3. if(!file.exists()){
  4. System.out.println("d:\\nes1.txt");
  5. }else{
  6. if(file.delete()){ // delete删除文件
  7. System.out.println("删除成功");
  8. }else{
  9. System.out.println("删除失败");
  10. }
  11. }
  12. }

创建一级目录

  1. public static void main(String[] args) {
  2. // 注意在Java里目录(文件夹)也算是文件
  3. File file = new File("d:\\demo02");
  4. if(file.exists()){
  5. System.out.println("文件夹存在");
  6. }else{
  7. file.mkdir(); //创建单极目录,当然mkdirs也行
  8. }
  9. }

创建多级目录

  1. public static void main(String[] args) {
  2. // 注意在Java里目录(文件夹)也算是文件
  3. File file = new File("d:\\demo02\\demo03");
  4. if(file.exists()){
  5. System.out.println("文件夹存在");
  6. }else{
  7. file.mkdirs(); //创建多级目录
  8. }
  9. }

IO流

原理

image.png
image.png
image.png
注:1. Java的IO流总共涉及40多个类,实际上非常规则,都是从上面的四个抽象基类派生的。
2. 由这四个类派生出来的子类名称都是以其父类名作为子类名后缀。
流与文件的类似关系:
image.png

类图

InputStream

image.png

OutStream

image.pngimage.png

Reader

image.png

Writer

image.png

节点流和处理流

image.png

节点流图解

image.png

包装流图解

image.pngimage.png
image.png

对包装流的模拟

  1. class BufferReader_{ //这个就是个包装类
  2. private Reader_ reader_; //包装了一个Reader_类型的属性
  3. public Test(Reader_ reader_) {
  4. this.reader_ = reader_;
  5. } //构造器
  6. public static void main(String[] args) {
  7. BufferReader_ test = new BufferReader_(new StringReader_());
  8. //根据多态可以传入各种 节点流
  9. test.reader_.readString(); //调用相关方法
  10. }
  11. }
  12. abstract class Reader_{
  13. public void readFile(){}
  14. public void readString(){}
  15. } //定义抽象类,后面在调用时,用动态绑定机制
  16. class FileReader_ extends Reader_{ //文件读取类
  17. @Override
  18. public void readFile(){
  19. System.out.println("对文件进行读取");
  20. }
  21. }
  22. class StringReader_ extends Reader_{ //字符串读取类
  23. @Override
  24. public void readString() {
  25. System.out.println("对字符串进行读取");
  26. }
  27. }

也可以在 BufferReader_中 添加各种读取方法:

  1. public void readFiles(int num){
  2. for(int i=0;i<num;i++){
  3. reader_.readFile();
  4. }
  5. }

image.png

FileInputStream

用read读取单个字节 read()

  1. public static void main(String[] args) { //用read读取单个字节
  2. int readData = 0; //注意这里,readData初始化为int类型,因为读入的是字符码
  3. FileInputStream fis = null; //不初始化会报错
  4. try {
  5. //创建 FileInputStream对象,用于读取文件
  6. fis = new FileInputStream("d:\\test1.txt");
  7. //从该输入流读取一个字节的数据,如果没有输入可用,此方法返回-1,表示读取完毕
  8. while((readData = fis.read()) != -1){ //持续读入
  9. System.out.print((char)readData); //输出时转换为char类型
  10. }
  11. } catch (IOException e) {
  12. //IOException包括一切IO异常,用别的read和FileInputStream只能管一个
  13. e.printStackTrace();
  14. } finally {
  15. //关闭文件流,释放资源
  16. try {
  17. fis.close();
  18. } catch (IOException e) {
  19. e.printStackTrace();
  20. }
  21. }
  22. }

但是这种方法不适用于汉字的读取,因为在UTF-8中,一个汉字是由二到三个字符码编成的,如果按字节读取,会导致乱码。
用read方法读取多个字节:read(byte[]) 每次能读取byte数组容量(N)个字节

  1. public static void main(String[] args) {
  2. int readLen;
  3. byte[] buf = new byte[8]; //一次读取8个字节
  4. FileInputStream fis = null; //不初始化会报错
  5. try {
  6. //创建 FileInputStream对象,用于读取文件
  7. fis = new FileInputStream("d:\\test1.txt");
  8. //从该输入流读取一个字节的数据,如果没有输入可用,此方法返回-1,表示读取完毕
  9. while((readLen = fis.read(buf)) != -1){ //如果读取正常,返回实际读取的字节数
  10. System.out.print(new String(buf,0,readLen));
  11. //注意不能用buf.length,会有额外字节
  12. }
  13. } catch (IOException e) {
  14. //IOException包括一切IO异常,用别的read和FileInputStream只能管一个
  15. e.printStackTrace();
  16. } finally {
  17. //关闭文件流,释放资源
  18. try {
  19. fis.close();
  20. } catch (IOException e) {
  21. e.printStackTrace();
  22. }
  23. }
  24. }

FileOutputStream

  1. public static void main(String[] args) {
  2. String filePath = "d:\\a.txt";
  3. //如果不存在这个文件,会自动创建
  4. FileOutputStream fos = null;
  5. String str = "Hello,world!";
  6. try {
  7. fos = new FileOutputStream(filePath);
  8. // fos.write('a'); 输入一个字符
  9. // 写入字符串方法:str.getBytes() 可以把 字符串-> 字节数组
  10. fos.write(str.getBytes());
  11. fos.write(str.getBytes(),2,3);
  12. //从索引为2的地方开始追加3个字节。
  13. } catch (IOException e) {
  14. e.printStackTrace();
  15. } finally {
  16. try {
  17. fos.close();
  18. } catch (IOException e) {
  19. e.printStackTrace();
  20. }
  21. }
  22. }

注:1. write(byte[] b,int off,int len){} 将len个字节从off索引开始写入文件
2. new FileOutputStream(filePath) 这样的创建方式会把写入的内容覆盖原来的内容。
3. new FileOutputStream(filePath,true) 这样的创建方式,当写入内容会追加到文件后面。
4. FileOutputStream和FileInputStream都是字节处理流,可以处理二进制文件和文本文件。
复制一个文件(图像等)

  1. public static void main(String[] args) {
  2. FileInputStream fileInputStream = null; //输入流
  3. FileOutputStream fileOutputStream = null; //输出流
  4. try {
  5. fileOutputStream = new FileOutputStream("d:\\test2.txt");
  6. fileInputStream = new FileInputStream("d:\\test1.txt");
  7. byte[] b = new byte[1024]; //边读边写
  8. int len;
  9. while((len = fileInputStream.read(b)) != -1){
  10. fileOutputStream.write(b,0,len); //不能用b,因为可能有没有用到的空间
  11. }
  12. } catch (IOException e) {
  13. e.printStackTrace();
  14. }finally {
  15. try {
  16. fileOutputStream.close();
  17. fileInputStream.close();
  18. } catch (IOException e) {
  19. e.printStackTrace();
  20. }
  21. }
  22. }

image.png

FileReader

image.png
image.png

FileWriter

image.png
image.png
FileWriter和FileReader是节点流中的字符流,处理字符,不能处理二进制文件,只能处理文本文件。


BufferedReader和BufferedWriter

Buffered和Object IO流都属于包装流。
image.png
image.png
注:1. readLine方法读取一行,读取完毕返回null。
2. BufferedReader的关闭只需要关闭包装流,节点流在包装流关闭后会自动关闭。
image.png
注:

  1. new FileWriter(filePath,true); //表示以追加的方式写入
  2. new FileWriter(filePath); // 表示以覆盖的方式写入

BufferedReader 和 BufferedWriter 是安装字符操作。不要去操作二进制文件(声音,视频,doc等),可能造成文件损坏。

BufferedInputStream和BufferedOutputStream

image.pngimage.pngimage.png
前面的Buffered使用writer和reader,这个Buffered使用 FileInputStream和FileOutputStream
image.png
image.png
image.png

ObjectInputStream和ObjectOutputStream

假如说我们只想把”10”这个数存到文件里,那么只是保存值,用不上ObjectInputStream。但如果想把值和数据类型都保存,比如Dog类或者”int a = 10”,那么就需要用到了。
image.png
image.png
ObjectOutputStream提供 序列化功能。 ObjectInputStream提供 反序列化功能。
image.png
image.pngimage.png
image.png
注:Dog类需要实现Serializable接口

  1. class Dog implements Serializable{ ... }

image.png
image.png
值得注意的是:1. 读取顺序必须和write顺序一致。 2. 读取自定义类时,这个类需要能被访问到。
3. ObjectInputStream和ObjectOutputStream都是只关闭外流就可以了。
image.pngimage.png

标准输入输出流

  1. public final static InputStream in = null;
  2. public final static PrintStream out = null;

System.in 编译类型:InputStream,运行类型:BufferedInputStream。表示的是标准输入 键盘
System.out 编译类型:PrintStream,运行类型:PrintStream。 表示的是标准输入 显示器

转换流

默认情况下,读取文件是按照UTF-8编码,如果文件按照别的方式编码,就很容易读取到乱码。
image.pngimage.png image.png
image.png
包装:其实就是转换。

  1. String filePath = "d:\\a.txt";
  2. InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath,"gbk"));
  3. //注意文件编码格式是啥,就转化成啥格式
  4. BufferedReader br = new BufferedReader(isr); //包装转换流,转换成字符流
  5. String s = br.readLine();
  6. br.close(); //关闭外层流

image.png

打印流

只有输出流,没有输入流。
image.pngimage.pngimage.pngimage.png

  1. PrintStream out = new PrintStream(System.out);
  2. out.println("hello");
  3. out.write("你好,世界".getBytes());
  4. //print底层调用的是write,所以可以直接调用write进行打印
  5. out.close(); //注意由于out是System.out,这个一结束,sout就不能用了
  6. System.out.println("wowowo"); //无法输出
  1. PrintStream out2 = new PrintStream("d:\\a.txt");
  2. System.setOut(out2);
  3. //修改打印流输出的位置
  4. System.out.println("1111"); //输出到文件当中
  1. public static void main(String[] args) throws IOException {
  2. FileWriter fileWriter = new FileWriter("d:\\a.txt");
  3. PrintWriter printWriter = new PrintWriter(fileWriter);
  4. printWriter.print("hello,world!!!!!!");
  5. printWriter.flush();
  6. //printWriter.close(); //flush或者close调用一个,才能输入进去
  7. }

Properties

image.png
注:键值对不需要有空格,值不需要用引号引起来,值的默认类型是String。
image.png
image.png
image.png
store方法的第二个参数是注释,null表示没有注释。在store方法中,如果没有这个文件就是创建,如果有这个文件就是修改。