Java IO流
一、File类的使用
1、File类的一个对象代表一个文件或一个文件目录。
2、File类声明在java.io包下。
3、创建File类的实例
3.1、构造器一:File(String pathname)。
3.2、构造器二:File(String parent, String child)。
3.3、构造器三:File(File parent, String child)。
@Test public void test(){ //构造器一 //通过文件相对路径创建File类实例 File file = new File("hello.txt");//相对于当前类文件所在module的根目录 //通过文件绝对路径创建File类实例 File file1 = new File("F:\\program\\LearnJava\\IOTest\\hello.txt"); //构造器二 File file2 = new File("F:\\program\\LearnJava","IOTest"); //构造器三 File file3 = new File(file2,"hello.txt"); }
4、创建File实例的注意点:
4.1、路径
4.1.1、绝对路径:包含盘符在内的文件或文件目录的路径。
4.2.2、相对路径:相对于某个路径下指明的路径
4.2、路径分隔符
4.2.1、Windows:\\
4.2.2、Unix:/
5、File类的功能
5.1、File类的获取功能
5.1.1、public String getAbsolutePath():获取绝对路径
5.1.2、public String getPath():获取路径
5.1.3、public String getName():获取名称
5.1.4、public String getParent():获取上层文件目录,若没有,返回null
5.1.5、public long length():获取文件长度
5.1.6、public long lastModified():获取最后一次修改时间,返回时间戳
5.1.7、public String[] list():获取文件目录中的内容,返回String数组(相对路径)
5.1.8、public File[] listFiles():获取文件目录中的内容,返回File数组(绝对路径)
5.2、File类的重命名功能
5.2.1、public boolean renameTo(File dest):把文件重命名为指定的文件路径
5.3、File类的判断功能
5.3.1、public boolean isDirectory():判断是否是文件目录
5.3.2、public boolean isFile():判断是否是文件
5.3.3、public boolean exists():·判断是否存在
5.3.4、public boolean canRead():判断是否可读
5.3.5、public boolean canWrite():判断是否可写
5.3.6、public boolean isHidden():判断是否隐藏
5.4、File类的创建功能
5.4.1、public boolean createNewFile():创建文件
5.4.2、public boolean mkdir():创建文件夹
5.4.5、public boolean mkdirs():创建文件夹,如果上级文件夹不存在,一并创建
5.5、File类的删除功能
5.5.1、public boolean delete() :删除文件或文件夹
@Test public void test1() throws IOException { File file = new File("hello.txt"); File file1 = new File("F:\\program\\LearnJava\\IOTest\\hello.txt"); //获取绝对路径 System.out.println(file.getAbsolutePath());//F:\program\LearnJava\IOTest\hello.txt //获取路径 System.out.println(file.getPath());//hello.txt //获取名称 System.out.println(file.getName());//hello.txt //获取上层文件目录,若没有,返回null System.out.println(file.getParent());//null //获取文件长度 System.out.println(file.length());//10 //获取最后一次修改时间,返回时间戳 System.out.println(new Date(file.lastModified()));//Thu May 27 23:37:48 CST 2021 System.out.println("**********************************"); System.out.println(file1.getAbsolutePath());//F:\program\LearnJava\IOTest\hello.txt System.out.println(file1.getPath());//F:\program\LearnJava\IOTest\hello.txt System.out.println(file1.getName());//hello.txt System.out.println(file1.getParent());//F:\program\LearnJava\IOTest System.out.println(file1.length());//10 System.out.println(file1.lastModified());//1622129868338 File file2 = new File("F:\\program\\LearnJava"); String[] list = file2.list(); //遍历文件目录中的内容(相对路径) System.out.println(Arrays.toString(list));//[.idea, compareTest, DateTimeTest, IOTest, jihe, LearnJava.iml, Lock, out, StringTest, Thread] File[] files = file2.listFiles(); ////遍历文件目录中的内容(绝对路径) System.out.println(Arrays.toString(files));//[F:\program\LearnJava\.idea, F:\program\LearnJava\compareTest, F:\program\LearnJava\DateTimeTest, F:\program\LearnJava\IOTest, F:\program\LearnJava\jihe, F:\program\LearnJava\LearnJava.iml, F:\program\LearnJava\Lock, F:\program\LearnJava\out, F:\program\LearnJava\StringTest, F:\program\LearnJava\Thread] File file3 = new File("he.txt"); //把文件重命名为指定的文件路径 // System.out.println(file.renameTo(file3)); //判断是否是文件目录 System.out.println(file.isDirectory());//false //判断是否是文件 System.out.println(file.isFile());//true //判断是否存在 System.out.println(file.exists());//true //判断是否可读 System.out.println(file.canRead());//true //判断是否可写 System.out.println(file.canWrite());//true //判断是否隐藏 System.out.println(file.isHidden());//false File file4 = new File("hahaha.txt"); if (!file4.exists()) { //创建文件 System.out.println(file4.createNewFile());//true } File file5 = new File("win"); if (!file5.exists()) { //创建文件夹 System.out.println(file5.mkdir());//true } File file56 = new File("wins/test"); if (!file56.exists()) { //创建文件夹,如果上级文件夹不存在,一并创建 System.out.println(file56.mkdirs());//true } //删除文件或文件夹 System.out.println(file56.delete());//true }
6、File类中涉及到关于文件或文件夹创建、删除、重命名、修改时间、文件大小等方法,并未涉及到写入或读取文件内容的操作,如果需要读取或写入文件内容,必须使用IO流完成。
7、后续File类的对象会作为参数传递到流的构造器中,指明读取或写入的“终点”。
二、流的分类
1、按操作的数据单位划分:字节流、字符流。
2、按数据的流向划分:输入流、输出流。
3、按流的角色划分:节点流、处理流。
三、流的体系结构
| 抽象基类(及用到的方法) | 节点流(文件流) | 缓冲流(处理流的一种) | |
| 字节流 | InputStream | FileInputStream(read(byte[] buffer)) | BufferedInputStream(read(byte[] buffer)) |
| 字节流 | OutPutStream | FileOutPutStream(write(byte[] buffer , 0 , len)) | BufferedOutPutStream(write(byte[] buffer , 0 , len),flush()刷新缓冲区) |
| 字符流 | Reader | FileReader(read(char[] cbuf)) | BufferedReader(read(char[] cbuf),readLine()) |
| 字符流 | Writer | FileWriter(write(char[] cbuf, 0 , len)) | BufferedWriter(write(char[] cbuf, 0 , len),flush()刷新缓冲区) |
1、FileReader
1.1、read( )的理解:返回读入的一个字符,如果达到文件末尾,返回负一。
1.2、异常处理:为保证溜资源一定可以执行关闭操作,需要使用try-catch-finally处理。
1.3、读入的文件一定要存在,否则会抛出FileNotFoundException。
@Test public void testFileReader() { //实例化File对象 File file = new File("hello.txt"); FileReader fr = null; try { //数据流实例化 fr = new FileReader(file); //数据读入 //返回读入的字符,如果到达文件末尾,返回-1 //方式一: /* int read = fr.read(); while (read != -1) { System.out.println(fr.read()); read = fr.read(); }*/ //方式二: int data; while ((data = fr.read()) != -1) { System.out.println((char) data); } } catch (IOException e) { e.printStackTrace(); } finally { //手动关闭连接资源 try { if (fr != null) fr.close(); } catch (IOException e) { e.printStackTrace(); } } }
1.4、使用read( char [ ] cbuf )读入数据
@Test public void readCharTest() { FileReader fr = null; try { File file = new File("hello.txt"); fr = new FileReader(file); char[] cbuf = new char[5]; int len; while ((len = fr.read(cbuf)) != -1) { //方式一、 /* for (int i = 0; i < len; i++) { System.out.print(cbuf[i]);//hello File }*/ //方式二 System.out.println(new String(cbuf,0,len)); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fr != null) { try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } } }
2、FileWriter
2.1、输出操作:对应的File文件可以不存在。并不会抛异常。
2.2、File对应的硬盘路径中的文件如果存在:
如果调用的构造器是FileWriter(File file)或FileWriter(File file, boolean append)append为false,则会对原有文件进行覆盖。
如果调用的构造器是FileWriter(File file, boolean append)append为true,则会对原有文件内容进行追加。
@Test public void fileWriterTest() { FileWriter fw = null; try { File file = new File("hello.txt"); //fw = new FileWriter(file); fw = new FileWriter(file,true); fw.write("I have a dream!"); } catch (IOException e) { e.printStackTrace(); } finally { if (fw != null) { try { fw.close(); } catch (IOException e) { e.printStackTrace(); } } } }
3、使用FileReader和FileWriter进行文件复制
@Test public void readAndWriteTest() { FileReader fileReader = null; FileWriter fileWriter = null; try { //创建File类对象,指定读取和写入的文件位置。 File reF = new File("hello.txt"); File wrF = new File("hi.txt"); //创建输入输出对象 fileReader = new FileReader(reF); fileWriter = new FileWriter(wrF); //数据的读入和写出 char[] cbuf = new char[5]; int len; while ((len = fileReader.read(cbuf)) != -1) { fileWriter.write(cbuf, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally { //关闭输入输出流。 if (fileReader != null) { try { fileReader.close(); } catch (IOException e) { e.printStackTrace(); } } if (fileWriter != null) { try { fileWriter.close(); } catch (IOException e) { e.printStackTrace(); } } } }
4、FileInputStream和FileOutPutStream
4.1、Stream处理文本文件可能会出现乱码,如果只是复制则不会乱码。
4.2、字节流多用于读取和传输非文本文件,比如:jpg,doc,pdf等。
4.3、字节流读写非文本文件:
@Test public void testCopy(){ copyFile("F:\\program\\LearnJava\\IOTest\\360wallpaper.jpg","F:\\program\\LearnJava\\IOTest\\360wallpaper23.jpg"); } public void copyFile(String oldFilePath,String newFilePath){ FileInputStream inputStream = null; FileOutputStream fileOutputStream = null; try { //通过匿名对象创建文件对象,创建字节流对象 inputStream = new FileInputStream(new File(oldFilePath)); fileOutputStream = new FileOutputStream(new File(newFilePath)); //读写 byte[] bytes = new byte[1024]; int len; while ((len = inputStream.read(bytes)) != -1) { fileOutputStream.write(bytes,0,len); } } catch (IOException e) { e.printStackTrace(); } finally { //关闭资源 if (inputStream!=null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (fileOutputStream!=null) { try { fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } }
5、处理流之一:缓冲流的使用
5.1、缓冲流 :BufferedInputStream
BufferedOutputStream
BufferedReader
BufferedWriter
5.2、作用:提高流的读取,写入速度。
提高速度的原因:内部提供了一个缓冲区。
5.3、字节缓冲流复制文件
@Test public void testCopy() { long startTime = System.currentTimeMillis(); copyFileWithBuffered("E:\\工具\\CentOS-7-x86_64-DVD-1810.iso", "E:\\copy\\CentOS-7-x86_64-DVD-1810.iso"); long endTime = System.currentTimeMillis(); System.out.println("耗时" + (endTime - startTime)); } public void copyFileWithBuffered(String oldFilePath, String newFilePath) { BufferedInputStream bufferedInputStream = null; BufferedOutputStream bufferedOutputStream = null; try { //通过匿名对象创建文件对象,创建字节流对象 FileInputStream inputStream = new FileInputStream(new File(oldFilePath)); FileOutputStream fileOutputStream = new FileOutputStream(new File(newFilePath)); // bufferedInputStream = new BufferedInputStream(inputStream); bufferedOutputStream = new BufferedOutputStream(fileOutputStream); //读写 byte[] bytes = new byte[1024]; int len; while ((len = bufferedInputStream.read(bytes)) != -1) { bufferedOutputStream.write(bytes, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally { //关闭资源 if (bufferedInputStream != null) { try { bufferedInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } if (bufferedOutputStream != null) { try { bufferedOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } }
5.4、字符缓冲流复制文本文件
@Test public void test() { BufferedReader reader = null; BufferedWriter writer = null; try { reader = new BufferedReader(new FileReader(new File("hello.txt"))); writer = new BufferedWriter(new FileWriter(new File("hello1.txt"))); //方式一: /* char[] chars = new char[1024]; int len; while ((len = reader.read(chars)) != -1) { writer.write(chars, 0, len); }*/ //方式二: String data; while ((data = reader.readLine()) != null) { //方法一: // writer.write(data + "\n");//data中不包含换行符 //方法二: writer.write(data); writer.newLine(); } } catch (IOException e) { e.printStackTrace(); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } if (writer != null) { try { writer.close(); } catch (IOException e) { e.printStackTrace(); } } } }
6、转换流的使用
6.1、转换流:属于字符流
InputStreamReader:将一个字节的输入流,转换成字符的输入流。
OutputStreamWriter:将一个字节的输出流,转换为字符的输出流。
6.2、作用:提供字节流与字符流之间的转换。
6.3、编码:字节、字节数组 --------> 字符数组、字符串
解码:字符数组、字符串 --------> 字节、字节数组
@Test public void test() { InputStreamReader reader = null; OutputStreamWriter writer = null; try { reader = new InputStreamReader(new FileInputStream(new File("hello.txt")), "UTF-8"); writer = new OutputStreamWriter(new FileOutputStream(new File("hello1.txt")), "UTF-8"); char[] chars = new char[20]; int len; while ((len = reader.read(chars)) != -1) { System.out.println(new String(chars, 0, len)); writer.write(chars, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } if (writer != null) { try { writer.close(); } catch (IOException e) { e.printStackTrace(); } } } }
6.4、字符集
6.4.1、ASCII:美国标准信息交换码,用一个字节的7位表示。
6.4.2、ISO8859-1:拉丁码表,欧洲码表,用一个字符的8位表示
6.4.3、GB2312:中国的中文编码表,最多两个字节编码所有字符。
6.3.4、GBK:中国的中文编码表升级,融合了更多的中文文字符号,最多两个字节编码。
6.3.5、Unicode:国际标准编码,融合了人类使用的所有字符,为每个字符分配唯一的字符码,所有的文字都用两个字节来表示。
6.3.6、UTF-8:变长的编码方式,可用1~4个字节表示一个字符。
7、对象流的使用
7.1、ObjectOutputStream和ObjectInputStream
7.2、作用:用于存储和读取基本数据类型数据或对象的处理流,他的强大之处就是可以把Java对象写入到数据源中,也可将对象从数据源中还原回来。
@Test public void test() { //序列化过程 :将内存中的Java对象保存到磁盘中,或通过网络传输出去。 //使用ObjectOutputStream ObjectOutputStream outputStream = null; try { outputStream = new ObjectOutputStream(new FileOutputStream(new File("object.dat"))); outputStream.writeObject(new Date()); outputStream.flush(); } catch (IOException e) { e.printStackTrace(); } finally { if (outputStream != null) { try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } @Test public void test1(){ //反序列化过程 :将磁盘中的Java对象读取到内存中,或通过网络接收。 //使用ObjectInputStream ObjectInputStream inputStream = null; try { inputStream = new ObjectInputStream(new FileInputStream(new File("object.dat"))); Object object = inputStream.readObject(); System.out.println((Date)object); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { if (inputStream!= null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } }
7.3、自定义类实现序列化和反序列化
7.3.1、要求:自定义类必须实现Serializable接口
7.3.2、当前类必须提供一个全局变量serialVersionUID
7.3.3、除了当前类实现Serializable接口外,还需保证类中所有元素的类型都是可序列化的。
7.3.4、不能序列化static和transient修饰的成员变量。
public class Person implements Serializable { private static final long serialVersionUID = -6878978784564667710L; private String name; private Integer age; //··········· }
8、RandomAccessFile的使用
8.1、RandomAccessFile直接继承与java.long.Object类,实现了DataInput和DataOutput接口。
8.2、RandomAccessFile既可以作为输入流,也可以作为输出流。
8.3、如果RandomAccessFile作为输出流时,写出到的文件如果不存在,则在执行过程中自动创建。
如果写出到文件,则会对原有文件内容进行覆盖(默认情况下从头覆盖)。
@Test public void test() { RandomAccessFile randomAccessFile = null; RandomAccessFile randomAccessFile1 = null; try { randomAccessFile = new RandomAccessFile(new File("360wallpaper.jpg"), "r"); randomAccessFile1 = new RandomAccessFile(new File("360wallpaper1.jpg"), "rw"); byte[] bytes = new byte[1024]; int len; while ((len = randomAccessFile.read(bytes)) != -1) { randomAccessFile1.write(bytes, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally { if (randomAccessFile != null) { try { randomAccessFile.close(); } catch (IOException e) { e.printStackTrace(); } } if (randomAccessFile1 != null) { try { randomAccessFile1.close(); } catch (IOException e) { e.printStackTrace(); } } } }
操作文本
@Test public void test1() { RandomAccessFile randomAccessFile1 = null; try { randomAccessFile1 = new RandomAccessFile(new File("hello.txt"), "rw"); //通过seek方法设置写入位置 randomAccessFile1.seek(new File("hello.txt").length()); randomAccessFile1.write("hahahahahahahaha".getBytes(StandardCharsets.UTF_8)); } catch (IOException e) { e.printStackTrace(); } finally { if (randomAccessFile1 != null) { try { randomAccessFile1.close(); } catch (IOException e) { e.printStackTrace(); } } } }

浙公网安备 33010602011771号