• Java


    Java - IO 文件操作

    基本操作

    若是要对文件以及文件内容进行操作,应该使用的是:java.Io 包

    Java.IO包:(5+1 核心)

    • File类
    • InputStream类
    • OutputStream类
    • Reader类
    • Writer类
    • Serializable接口

    File类(文件本身的操作)

    在java.IO包中,File 类是唯一一个与文件本身操作有关的类,但是不涉及到文件的具体内容。文件本身指的是:创建、删除等操作

    设置完整路径

    • 构造方法:
    public File(String pathnamc);
    

    根据完整的路径来完成对文件的本身操作

    设置父与子文件路径

    • 构造方法:
    public File(File parent , String child);
    

    主要用于在Android系统中

    操作文件

    创建文件
    public boolean createNewFile();
    
    • 创建成功:
    import java.io.File;
    import java.io.IOException;
    
    public class TestDemo {
    	public static void main(String [] args) throws IOException {
    		File file = new File("F:\demo.txt"); //设置文件的路径(文件并不存在)
    		System.out.println(file.createNewFile());//创建文件
    	}
    }
    

    在第六行中,只是给了file一个路径(转义斜杠),第七行使用 createNewFile() 创建的file路径的文件;方法返回布尔值,创建成功则返回 true 反之则返回 false。

    删除文件
    public boolean delete() ;
    
    • 删除文件:
    public class TestDemo {
    	public static void main(String [] args) throws IOException {
    		File file = new File("F:\demo.txt"); //设置文件的路径(文件并不存在)
    		System.out.println(file.delete());
    	}
    }
    

    我们在 code 第 4 行引用了delete() 方法,删除file指定路径的文件

    是否存在
    public boolean exists();
    

    文件存在则返回true 反之返回 false

    • 改进"删除文件" 的代码(加入判断机制)
    public class TestDemo {
    	public static void main(String [] args) throws IOException {
    		File file = new File("F:\demo.txt"); //设置文件的路径(文件并不存在)
    		if (file.exists()) {
    			file.delete();
    		} else {
    			System.out.println("文件不存在");
    		}
    	}
    }
    

    不同系统的路径分隔符问题

    windows 和 Linux 系统的环境下,路径的分隔符号有所不同

    • Windows使用的是反斜杠" " 作为路径分隔符
    • 所有基于Linux的系统使用的都是斜杠“ / ” 作为路径分隔符

    所以,如果路径写死,就会影响程序的可移植性

    解决方法:
    • File类中提供一个常量成员
    public static final String separator;
    
    • 解决方案:
    	public class TestDemo {
    		public static void main(String [] args) throws IOException {
    			File file = new File("F:" + File.separator + "demo.txt");
    		}
    	}
    

    通过 File中的常量 separator 来代替自定义的文件路径分隔符,可以较完美的解决路径分隔符带来的系统不兼容的问题

    子目录的创建

    • 获取父路径
    public File getParentFile() ;  // 返回File便于File类对其操作
    public String getParenFile() ; // 返回String数据,便于输出路径名
    
    • 判断父路径是否存在
    public class TestDemo {
    	public static void main(String [] args) throws IOException {
    		File file = new File("F:" + File.separator + 
    				"demo" + File.separator + 
    				"demo.txt");
    		System.out.println(file.getParentFile().exists());// 返回 false
            // 获取父类地址,判断是否存在
    	}
    }
    

    file.getParentFile() 返回的是父类目录,使用 exists() 方法进行判断是否存在目录或文件

    • 创建目录:
    public boolean mkdir(); // 处理一级目录
    public boolean mkdirs();// 处理多级目录
    
    • 处理一级目录
    public class TestDemo {
    	public static void main(String [] args) throws IOException {
    		File file = new File("F:" + File.separator + 
    				"demo" + File.separator + 
    				"demo.txt");
    		if (!file.getParentFile().exists()) {
    			System.out.println(file.getParentFile().mkdir()); //创建目录(父路径)
    		}
    	}
    }
    
    • 处理多级目录
    public class TestDemo {
    	public static void main(String [] args) throws IOException {
    		File file = new File("F:" + File.separator + 
    				"demo" + File.separator + 
    				"txt" + File.separator +
    				"demo.txt");
    		if (!file.getParentFile().exists()) {
    			System.out.println(file.getParentFile().mkdirs()); //创建多级目录(父路径)
    		}
    	}
    }
    

    文件信息内容的操作方法

    获取文件大小
    public long length();
    
    • 实例:
    public class TestDemo {
    	public static void main(String [] args) throws IOException {
    		File file = new File("F:" + File.separator + 
    				"demo" + File.separator + 
    				"txt" + File.separator +
    				"demo.txt");
    //		if (!file.getParentFile().exists()) {
    //			System.out.println(file.getParentFile().mkdirs()); //创建目录(父路径)
    //		}
    //		System.out.println(file.createNewFile());
    		
    		System.out.println((double)file.length());
    	}
    }
    
    判断是否为File
    public boolean isFile(); 
    
    判断是否为目录
    public boolean isDirectory();
    
    • 实例:
    public class TestDemo {
    	public static void main(String [] args) throws IOException {
    		File file = new File("F:" + File.separator + 
    				"demo" + File.separator + 
    				"txt" + File.separator +
    				"demo.txt");
    		System.out.println("是否是文件" + file.isFile());
    		System.out.println("是否是目录" + file.isDirectory());
    		System.out.println(file.length());
    	}
    }
    
    返回最近的修改时间
    public long lastModified();
    
    • 返回的是时间字符串,需要转为 Date 型
    new Date ( [File].lastModified() ) ;  // 标准格式
    new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") ;  //日期格式化
    
    • 实例:
    public class TestDemo {
    	public static void main(String [] args) throws IOException {
    		File file = new File("F:" + File.separator + 
    				"demo" + File.separator + 
    				"txt" + File.separator +
    				"demo.txt");
    		// SimpleDateFormat 将日期格式化输入
            // new Date()构造转换为标准日期格式
    		System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(file.lastModified())));
    		// 返回结果:2019-07-06 21:21:12
    	}
    }
    

    目录操作

    列出目录下的信息
    public String [] list() ;
    
    列出所有的信息
    • File 对象进行包装
    public File [] listFiles();
    
    实例
    • 列出所有信息:
    public class TestDemo {
    	public static void main(String [] args) throws IOException {
    		File file = new File("F:" + File.separator + 
    				"00 JavaSE 笔记"); 
    		System.out.println(file.getPath());
    		String [] list = file.list();
    		for (int x = 0; x < list.length; x++) {
    			System.out.println("|--" + list[x]);
    		}
    	}
    }
    
    • 列出全部的信息
    public class TestDemo {
    	public static void main(String [] args) throws IOException {
    		File file = new File("F:" + File.separator + 
    				"00 JavaSE 笔记"); 
    		System.out.println(file.getPath());
    		File [] list = file.listFiles();
    		for (int x = 0; x < list.length; x++) {
    			System.out.println("|--" + list[x]);
    		}
    	}
    }
    
    • 列出子目录中的全部
    public class TestDemo {
    	public static void main(String [] args) throws IOException {
    		File file = new File("F:" + File.separator + 
    				"00 JS 笔记"); 
    		System.out.println(file.getPath());
    		print(file);
    	}
    	public static void print(File file) {
    		if (file.isDirectory()) {
    			File list [] = file.listFiles();
    			for (int x = 0; x < list.length; x++) {
    				print(list[x]);
    			}
    		} else {
    			System.out.println("|--" + file);
    		}
    	}
    }
    

    文件夹/文件存在无法打开的,可以使用Null条件过滤掉

    • ps:如果将输出,变为删除,就是一个遍历删除的恶意程序了!!嘻嘻嘻嘻

    总结:

    • File类本身只是操作文件,不涉及到操作内容

    • File类:

      • 设置完整的路径: public File(String pathname)

      • 删除文件:public void delete()

      • 判断文件是否存在: public boolean exists()

      • 获取父目录:public File getParentFile()

      • 创建目录: public boolean mkdirs()

      • 判断文件或文件夹:public boolean isFile() / public boolean isDirectory()

      • 其他

    • File类中路径分隔符最好使用File类中的 separator 常量

    字节与字符流

    • File类 只是对文件本身的操作,不能操作文件的内容,如果要操作文件的具体内容就需要使用:字节流与字符流

    文件的输入输出操作

    • 简单的实现步骤:

      一、通过File类定义文件的路径

      二、通过字节流或字符流的子类对象为父类对象实例化

      三、进行数据读/写(输入/输出)操作

      四、数据流属于资源操作,资源操作 必须关闭

    java.IO包的定义的两类流

    字节流
    • InputStream:字节输入流
    • OutputStream:字节输出流
    字符流
    • Reader
    • Writer

    字节输出流:OutputStream

    public abstract class OutputStream
    extends Object
    implements Closeable,Flushable
    

    OutputStream类实现了:Closeable 和 Flushable 接口

    Closeable接口

    public interface Closeable extends AutoCloseable{
        public void close() throws IOException; //关闭
    }
    

    AutoCloseable:是一个jdk1.7之后定义的自动关闭的机制(建议不用)

    Flushable接口

    public interface Flushable {
        public void flush() throws IOException; // 缓存刷新
    }
    

    OutputStream 类是在JDK1.0就提供了 close() 和 flush() 两个方法

    输出方法

    输出单个字节:write(int b)
    public abstract void write(int b) throws IOException;
    
    输出全部字节数组:write(byte[] b)
    public void write(byte [] b) throws IOException;
    
    输出部分字节数组:write(byte[] b,int off,int len)
    public void write(byte[] b , int off , int len) throws IOException;
    

    OutputStream:属于抽象类,如果想实现对抽象类进行对象的实例化操作,那么一定要使用抽象类中的子类。

    进行文件操作可以使用FileOutputStream子类
    • 创建/覆盖已有文件
    public FileOutputStream(File file) throws FileNotFoundException;
    
    • 对文件进行内容追加
    public FileOutputStream(File file,boolean append);
    

    实例

    • 全部输出并覆盖
    package helloworld;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    
    public class TestDemo {
    	public static void main(String [] args) throws IOException {
    		File file = new File("F:" + File.separator +
    				File.separator +
    				"demo" +
    				File.separator +
    				"demo.txt");
    		if (!file.getParentFile().exists()) { //文件目录不存在
    			file.getParentFile().mkdirs(); //创建目录
    		}
    		// 使用OutputStream和FileOutputStream子类进行对象实例化
    		OutputStream out = new FileOutputStream(file);
    		String str = "Hello,World!";
    		byte data [] = str.getBytes(); // 利用byte类,将字符串转为byte字节数组
    		out.write(data); // 将内容输出到demo.txt文件中
    		out.close(); // 关闭操作
    		
    	}
    }
    
    • 单字节输出并覆盖
    package helloworld;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    
    public class TestDemo {
    	public static void main(String [] args) throws IOException {
    		File file = new File("F:" + File.separator +
    				File.separator +
    				"demo" +
    				File.separator +
    				"demo.txt");
    		if (!file.getParentFile().exists()) { //文件目录不存在
    			file.getParentFile().mkdirs(); //创建目录
    		}
    		// 使用OutputStream和FileOutputStream子类进行对象实例化
    		OutputStream out = new FileOutputStream(file);
    		String str = "Hello,World!";
    		byte data [] = str.getBytes(); // 利用byte类,将字符串转为byte字节数组
    		for (int x = 0; x < data.length; x++) {// 将内容输出到demo.txt文件中
    			out.write(data[x]); //单字节输出
    		}
    		out.close(); // 关闭操作		
    	}
    }
    
    • 输出部分内容
    package helloworld;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    
    public class TestDemo {
    	public static void main(String [] args) throws IOException {
    		File file = new File("F:" + File.separator +
    				File.separator +
    				"demo" +
    				File.separator +
    				"demo.txt");
    		if (!file.getParentFile().exists()) { //文件目录不存在
    			file.getParentFile().mkdirs(); //创建目录
    		}
    		// 使用OutputStream和FileOutputStream子类进行对象实例化
    		OutputStream out = new FileOutputStream(file);
    		String str = "Hello,World!";
    		byte data [] = str.getBytes(); // 利用byte类,将字符串转为byte字节数组
    		out.write(data,0,5);//部分:从下标0开始的5个数组单元
    		out.close(); // 关闭操作		
    	}
    }
    
    • 如果需要对文件不覆盖,仅是追加内容:
    package helloworld;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    
    public class TestDemo {
    	public static void main(String [] args) throws IOException {
    		File file = new File("F:" + File.separator +
    				File.separator +
    				"demo" +
    				File.separator +
    				"demo.txt");
    		if (!file.getParentFile().exists()) { //文件目录不存在
    			file.getParentFile().mkdirs(); //创建目录
    		}
    		// 使用OutputStream和FileOutputStream子类进行对象实例化
    		OutputStream out = new FileOutputStream(file,true);
    		// true:进行追加	false:不进行追加并覆盖
    		String str = "Hello,World!
    ";// 换行使用 
     进行操作
    		byte data [] = str.getBytes(); // 利用byte类,将字符串转为byte字节数组
    		out.write(data);
    		out.close(); // 关闭操作		
    	}
    }
    

    字节输入流:inputStream

    public abstract class InputStream
    extends Object
    implements Closeable
    

    输入方法

    读取单个字节:read()
    public abstract int read() throws IOException;
    
    • 返回值:当数据没有可读的时候,返回 -1 ;可以利用wheil循环操作
    读取的数据保存在字节数组里:read(byte[] b)
    public int read(byte[] b) throws IOException;
    
    • 返回值:返回读取的数据长度 ; 如果数据没有了,返回 -1
    读取部分数据并保存在数组中:read(byte[] b,int off,int len)
    public int read(byte[] b,int off,int len) throws IOException;
    
    • 返回值:返回部分数据的长度 ; 如果数据读取到结尾了,返回 -1
    继承类
    • 由于InputStream是抽象类,所以想要进行文件读取(输入)操作使用:FileInputStream 子类。
    实例
    • 向数组里读取数据
    public class TestDemo {
    	public static void main(String [] args) throws IOException {
    		File file = new File("F:" + File.separator +
    				File.separator +
    				"demo" +
    				File.separator +
    				"demo.txt");
    		if(file.exists()) {
    			InputStream  in = new FileInputStream(file);
    			byte [] data = new byte[1024];
    			in.read(data);
    			in.close();
    			System.out.println("{" + new String(data) + "}");
    		}
    	}
    }
    

    从程序中可以看见一个大问题!我们在不清楚文件字节大小的情况下读取到数组中,而数组过大,会导致出现输出问题;由此我们可以在内容读取到数组的时候,设置参数读取内容读取到数组的数据大小。

    • 读取部分数据
    public class TestDemo {
    	public static void main(String [] args) throws IOException {
    		File file = new File("F:" + File.separator +
    				File.separator +
    				"demo" +
    				File.separator +
    				"demo.txt");
    		if(file.exists()) {
    			InputStream  in = new FileInputStream(file);
    			byte [] data = new byte[1024];
    			int len = in.read(data);
    			in.close();// 关闭
    			System.out.println("{" + new String(data,0,len) + "}");
                // String(byte[] b , int off , int length)
    		}
    	}
    }
    
    • 读取单字节数据(
    public class TestDemo {
    	public static void main(String [] args) throws IOException {
    		File file = new File("F:" + File.separator +
    				File.separator +
    				"demo" +
    				File.separator +
    				"demo.txt");
    		if(file.exists()) {
    			InputStream  in = new FileInputStream(file);
    			byte [] data = new byte[1024];
    			int foot = 0 ; int temp = 0 ;
    			while((temp = in.read())!= -1) {
    				data[foot ++] = (byte) temp;
    			}
    			in.close();
    			System.out.println("{" + new String(data,0,foot) + "}");
    		}
    	}
    }
    

    字符输出流:Writer

    public abstract class Writer
    extends Object
    implements Appendable,Closeable,Flushable
    

    Appendable接口

    public interface Appendable() {//函数式接口
        public Appendable append(char c);
        	// 添加指定字符c
        public Appendable append(CharSequence csq);
        	// 添加指的字符序列 csq
        public Appendable append(CharSequence csq,int start,int end);
        	// 添加指定字符序列的子序列
    }
    

    在Appendable接口里面定义了追加的操作,而且追加的数据都是字符或字符序列

    输出方法

    输出全部字符数组
    public void write(char[] cbuf) throws IOException;
    
    输出字符串*
    public void write(String str) throws IOException;
    

    FileWriter

    • Writer是一个抽象类,如果想实例化对象,应该使用 FileWriter 子类
    public FileWriter(File file);
    public FileWriter(File file,boolean append);
    

    实例

    • 输出字符
    public class TestDemo {
    	public static void main(String [] args) throws IOException {
    		File file = new File("F:" + File.separator +
    				File.separator +
    				"demo" +
    				File.separator +
    				"demo.txt");
    		if (!file.getParentFile().exists()) {
    			file.getParentFile().mkdirs();
    			//getParentFile()方法,获取父路径
    		}
    		Writer out = new FileWriter(file);
    		String str = "Hello,World!";
    		out.write(str);
    		out.close();
    	}
    }
    

    字符输入流:Reader

    public abstract class Reader
    extends Object 
    implements Readable , Closeable
    

    Readable接口

    输入方法

    读取内容到字符数组
    public int read(char[] cbuf) thows IOException;
    

    FileReader子类

    实例

    public class TestDemo {
    	public static void main(String [] args) throws IOException {
    		File file = new File("F:" + File.separator +
    				File.separator +
    				"demo" +
    				File.separator +
    				"demo.txt");
    		if (file.exists()) {
    			Reader in = new FileReader(file);
    			char [] data = new char[1024];
    			int len = in.read(data);
    			in.close();
    			System.out.println(new String(data, 0, len));
    		}
    	}	
    }
    

    字节流 与 字符流 两者的区别

    最大的区别:

    • 字节流:直接与终端进行数据交互
    • 字符流:需要经过中间的缓存进行交互

    在使用字节流输出/输入数据的时候,直接与终端进行数据交互,即使不关闭输出流,也不会对操作有所影响。但 字符输出/输入流,如果不关闭,就会是数据交互受到影响;不关闭输出/输入流,数据就会呆在缓冲区中,只有关闭了输出/输入流,缓存区的内容会被强制清空并输出/输入。如果不关闭输出流的情况下,可以使用 flush() 方法强制清空缓存区

    处理范围:

    在实际开发中,字节流数据处理的范围较广;例如:图片、音乐、视频、文字等。而字符流处理的数据主要是:进行中文的有效处理。

    所以,在处理中文的问题时,优先使用字符流方法。

    转换流

    • 字符流虽需要缓存区进行处理,但是问题不可忽略;字符输出流,可以直接输出一个字符串数据;在某特定情况下,不得不进行字节流与字符流的操作转换
    • java.io 包中提供:InputStreamReader、OutputStreamWriter 两个类

    InputStreamReader

    public class InputStreamReader
    extends Reader
    
    • 构造方法
    publit InputStreamReader(InputStream in)
    

    OutputStreamWriter

    public class OutputStremWriter
    extends Writer
    
    • 构造方法
    public OutputStreamWriter(OutpurStream out)
    

    实例

    • 输出的字节与字符流的转换
    public class TestDemo {
    	public static void main(String [] args) throws IOException {
    		File file = new File("F:" + File.separator +
    				File.separator +
    				"demo" +
    				File.separator +
    				"demo.txt");
    		if (!file.getParentFile().exists()) {
    			file.getParentFile().mkdirs();
    		}
    		OutputStream out = new FileOutputStream(file); // 字符流
    		Writer Out = new OutputStreamWriter(out); // 字节流转字符流
    		Out.write("Hello,World!");
    		Out.flush();//强制清空缓存区(不关闭输出流可使用flush()方法强制)
    	}	
    }
    

    总结

    • 熟练三种输入输出的字节字符流操作:
      • OutputStream 和 InputStream 类中的 write() 和 read() 方法 *
  • 相关阅读:
    如果男人是计算机,女人是软件(在开发过程中的偶然随想)
    C/C++ 可变参数函数的原理和应用
    Python学习记录Hello Word
    Unity 把数字,英文图片变成字体
    unity+Android+PC加载本地图片
    Python学习记录安装
    Android学习 问题与答案
    Android 第三方 APK 包的静默安装
    Android学习 问题与答案 (2)
    JNI 之 HelloWorld
  • 原文地址:https://www.cnblogs.com/wangyuyang1016/p/11153204.html
Copyright © 2020-2023  润新知