Java输入输出
Java语言中File类是唯一表示文件对象和目录对象的数据类型。在Java语言中文件路径分隔符使使用’/’或’\\’。
文件可以存储字节或字符;目录不能直接存储字节或字符,只能存储文件后子目录。
文件可以被读取和写入,而目录不能执行读写操作,只能建立,删除及获取其中包含的子目录及文件。
对于文件和目录通常要严格区分,File类提供方法可以判断此File对象是文件还是目录。
File(File dir,String child)
根据parent抽象路径名和child路径名字字符串创建一个新File实例。
File(String pathName)
通过将给定路径名字符串转换为抽象路径名来创建一个新File实例。
File(String parent,String child)
根据parent路径名字符串和child路径名字符串创建一个新File实例。
File(URI uri)
通过将给定的file:URI转换为一个抽象路径名来创建一个新的File实例。
File类常用方法
public boolean canWrite() //判断文件是否可以写入
public boolean canRead() //判断文件是否可以读取
public boolean createNewFile() throws IOException //文件不存在时创建该文件
public boolean delete() //删除该文件
public boolean exists() //判断文件是否存在
public String getAbsolutePath() //获取文件的绝对路径
public String getName() //获取文件名,文件的后缀也会获取
public String getParent() //获取文件的父目录
public String getPath() //和getAbsolutePath()类似
public boolean isDirectory() //判断是否是目录,如果是文件,返回假
public boolean isFile() //判断是否是文件
public File[] listFiles() //返回包含的所有文件列表,此方法通常只对目录起作用
public boolean mkdir() //创建目录
public boolean mkdirs() //创建目录,如果路径中间目录缺失,会自动创建
File文件流分类
方向
输入(Input)流——读取文件
输出(Output)流——写入文件
内容
字节(Byte)流——读写二进制文件
字符(Char)流——读写文本文件
方式
节点流——针对文件建立
处理流——针对其它文件流建立
输入流
- 输入流是指建立在文件或其他文件流上的用来对目标文件进行读取的文件流。
- 输入流只能对文件进行读取。
- 读取二进制文件使用字节输入流,读取文本文件使用文本输入流。
字节输入流
InputStream——FileInputStream——BufferedInputStream
InputStream——FileInputStream——DataInputStream
InputStream——ObjectInputStream
InputStream——ByteArrayInputStream
字节输入流常用方法
public abstract int read()throws IOException //返回读取到的字节数,基本没啥用
public int read(byte[] b)throws IOException //返回读取到的内容字节数组,不常用
public int read(byte[] b.int off,int len)throws IOException //int off是从哪里开始读数组,一般是0,int len是试图读取的长度,通常会取一个字节数组的长度
public void close() throws IOException //读写完毕以后关闭流,释放资源
字符输入流
Reader——InputStreamReader——FileReader
Reader——StringReader
Reader——CharArrayReader
Reader——BufferedReader
字符输入流常用方法
public int read()throws IOException
public int read(char[] cbuf)throws IOException
public abstract int read(char[] cbuf,int off,int len)throws IOException
public void close()throws IOException
输出流
- 输出流是指建立在文件或其他文件流上的用来对目标文件进行写入的文件流。
- 输出流只对目标文件进行写入操作。
- 写入二进制文件使用字节输出流,写入文本文件使用文本输出流。
字节输出流
OutputStream——FileOutputStream——BufferedOutputStream
OutputStream——FileOutputStream——DataOutputStream
OutputStream——ObjectOutputStream
OutputStream——ByteArrayOutputStream
字节输出流常用方法
public void write(int b)throws IOException //这个方法没什么意义
public void write(byte[] b)throws IOException //写入byte[]这个字节数组
public void write(byte[]b,int off,int len)throws IOException //用的最多的方法,第二个参数是从哪里开始写入,第三个参数是写入的长度
public void close() throws IOException //关闭输出流
字符输出流
Writer——OutputStreamWriter——FileWriter
Writer——StringWriter
Writer——CharArrayWriter
Writer——BufferedWriter
字符输出流主要方法
public void write(int b)throws IOException
public void write(char[] b)throws IOException
public abstract void write(chars[] b,int off,int len)throws IOException
public void write(String str)throws IOException
public void close()throws IOException
文件复制
将给定的文件复制到目标新文件
序列化读写
Java不仅提供了以字节和字符形式读写文件的功能,而且也提供了对任何Java数据类型进行读写的能力。
将一个数据以Java对象的形式存储到文件中或从目标文件中获取一个Java对象的操作被称为序列化操作,能够被序列化的对象称之为序列化的对象。
序列化对象
Java规定任何实现Serializable接口的类,被看做是序列化类,此类的实例即是一个序列化对象。
序列化对象可以通过序列化输入和输出流进行读写操作,通常序列化类必须提供一个公共无参的构造器,在反序列化(读取序列化对象)中JVM使用公共无参构造器创建Java的对象。
序列化文件流
ObjectOutputStream //序列化流,将一个Java对象保存到目标文件中
ObjectInputStream //反序列化流,从目标文件中读取序列化Java对象到内存
package until; import Interfaces.FileBasicSupport; import java.io.*; public class FileManager implements FileBasicSupport { /* 按照给定的目录名称,在硬盘上创建此目录 */ @Override public void createFolder(String folderPath) { //new一个文件路径对象 File dirFile = new File(folderPath); if (!dirFile.exists()){ //如果目录不存在则创建目录 boolean bool = dirFile.mkdirs(); System.out.println(dirFile+" 目录不存在,尝试创建该目录,创建是否成功:"+bool); }else{ System.out.println("目录 "+dirFile+" 已存在"); } } /* 按照给定的父目录名称及文件名称,创建目标文件并返回此文件对象*/ @Override public File createTargetFile(String parent, String fileName) { //new一个文件路径对象 File dirFile = new File(parent); if (!dirFile.exists()){//如果目录不存在则创建目录 boolean bool = dirFile.mkdirs(); System.out.println(dirFile+" 目录不存在,尝试创建该目录,创建是否成功:"+bool); if (bool){//如果文件目录创建成功,则在此目录下创建文件 File f = new File(dirFile,fileName); //创建文件对象,dirFile是路径,连接上第二个参数fileName文件名 try { f.createNewFile();//在硬盘上创建文件 } catch (IOException e) { e.printStackTrace(); } return f; } } else { System.out.println("目录"+parent+"已存在"); File f = new File(dirFile,fileName); //创建文件对象,dirFile是路径,连接上第二个参数fileName文件名 try { f.createNewFile();//在硬盘上创建文件 } catch (IOException e) { e.printStackTrace(); } return f; } return null; } /* 将给定的字符串内容写入到目录文件中,返回写入的字节数 */ @Override public long writeFile(File file, String content) { OutputStream out = null; //建立一个字节输出流 BufferedOutputStream bs = null; //建立一个缓冲输出流 byte[]bys = content.getBytes(); //建立一个字节数组,存入要输入的内容 if (file.exists()){ try { System.out.println("文件的路径是"+file.getAbsolutePath()); out = new FileOutputStream(file.getAbsolutePath()+"/七绝.txt"); bs = new BufferedOutputStream(out);//基于OutputStream建立一个缓冲输出流 bs.write(bys,0,bys.length);//写入目标文件 } catch (IOException e) { e.printStackTrace(); }finally { try { bs.close(); //关闭缓冲输出流 out.close(); //关闭字节输出流 } catch (IOException e) { e.printStackTrace(); } } } return bys.length; } /* 按照给定的硬盘目录文件路径及名称,读取目标文件并返回*/ @Override public File readFile(String path) { /*1.建立目标要读取的文件对象*/ File file = new File(path); /* 2.建立一个文本输入流 上半部分*/ FileReader read = null; /* 3.建立一个文本缓冲流 上半部分*/ BufferedReader br = null; if (file.exists()){ //如果文件存在 try { read = new FileReader(file); //基于文件建立普通文本输入流 下半部分 br = new BufferedReader(read); //基于Reader建立文本缓冲流 下半部分 char chs[] = new char[50]; //建立一个char数组接收输入的文本内容 int count = 0; //定义一个变量计算文本读取的字节数 while ((count = br.read(chs,0,chs.length))!=-1){ String s = new String(chs,0,count); System.out.println(s); } } catch (IOException e) { e.printStackTrace(); }finally { try { br.close(); //关闭文本缓冲流 read.close(); //关闭字节输入流 System.out.println("关闭字符输入流对象"); } catch (IOException e) { e.printStackTrace(); } } } else{ System.out.println("文件不存在!"); } return file; } }
/** * 2 在任务1的基础上,定义编写一个新接口FileAdvancedSupport 继承FileBasicSupport,并新添加以下抽象方法: * * 对给定的目录进行迭代,并返回此目录下的所有包含子文件目录下的所有文件 * * 并返回List<File> * * public abstract List<File> folderIteration(File directory); * * 将给定的源文件拷贝到目标目录文件 * * public abstract void copyFile(File sourceFile,String savePath,String fileName); * * 编写一个类实现上述FileAdvancedSupport接口并对接口中的抽象方法进行功能实现. * * 编写测试类包含main方法实现功能测试. */ package until; import Adaptor.FileAdvancedSupportAdaptor; import Interfaces.FileAdvancedSupport; import java.io.*; import java.util.*; public class FileManager2 extends FileAdvancedSupportAdaptor { /* 对给定的目录进行迭代,并返回此目录下的所有包含子文件目录下的所有文件 * 并返回List<File> */ @Override public List<File> folderIteration(File directory,List<File> list) { //获取目录下所有文件和目录的绝对路径,存入数组fs中 File[] fs = directory.listFiles(); //迭代这个路径 for (File f:fs){ if (f.isDirectory()){ //如果是目录,就递归调用自己 folderIteration(f,list); //调用自己 }else{ list.add(f); //判断如果是文件,就加入集合 } } return list; } /* 将给定的源文件拷贝到目标目录文件*/ @Override public void copyFile(File sourceFile, String savePath, String fileName) { InputStream in = null; //文件输入流 OutputStream out = null; //文件输出流 File copyFile = null; //目标写入的文件对象 File path = new File(savePath); //新建一个文件路径对象 if (sourceFile.exists()){ //判断目标文件是否存在 if (!path.exists()){ //判断要拷贝的目录是否存在 path.mkdirs(); //如果不存在就新建这个目录 } try { in = new FileInputStream(sourceFile); //基于目标文件建立文件输入流 /** * 避免文件重名被覆盖,可以使用系统时间的毫秒作为文件的前缀 */ //建立目标写入的文件对象 copyFile = new File(path+"/"+fileName); out = new FileOutputStream(copyFile); //建立基于目标文件的输出流 byte bys[] = new byte[1024]; //临时存储字节数据的缓冲区 int count = 0; //记录读取内容的临时变量 while((count = in.read(bys,0,bys.length))!=-1){ out.write(bys,0,count); //将临时缓冲区的内容写入到目标文件中 } System.out.println("文件复制完成"); } catch (IOException e) { e.printStackTrace(); }finally { try { out.close(); in.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
/** * 1 使用Eclipse IDE 编写一个控制台应用程序, 此应用主要提供一个自定义文件管理接口FileBasicSupport(接口名自定义), 定义以下抽象方法: * * 按照给定的目录名称,在硬盘上创建此目录 *public abstract void createFolder(String folderPath); * * 按照给定的父目录名称及文件名称,创建目标文件并返回此文件对象 *public abstract File createTargetFile(String parent,String fileName); * * 将给定的字符串内容写入到目录文件中,返回写入的字节数 *public abstract long writeFile(File file,String content); * * 按照给定的硬盘目录文件路径及名称,读取目标文件并返回 *Public abstract File readFile(String path); * *编写一个类实现上述FileBasicSupport接口并对接口中的抽象方法进行功能实现. * *编写测试类包含main方法实现功能测试. * */ package main; import until.FileManager; import java.io.File; public class TestIO { public static void main(String[] args) { FileManager fil = new FileManager(); /* 按照给定的目录名称,在硬盘上创建此目录 */ String dir = "e:/files3/"; //调用创建目录的方法 fil.createFolder(dir); System.out.println("-----------分割线--------------"); /* 按照给定的父目录名称及文件名称,创建目标文件并返回此文件对象*/ String dir1 ="e:/files3/testFile/"; String fileName = "这是一个测试文件.txt"; //建立一个文件对象f接收调用创建目标文件的方法的返回值 File f = fil.createTargetFile(dir1,fileName); System.out.println("文件对象:"+f); System.out.println("-----------分割线--------------"); /* 将给定的字符串内容写入到目录文件中,返回写入的字节数 */ File file = new File("e:/files3/"); String str = "孩儿立志出乡关,\n学不成名誓不还,\n埋骨何须桑梓地。\n人生无处不青山"; //建立一个long1变量接收调用写入方法返回的写入的字节数 long long1 = fil.writeFile(file,str); System.out.println("写入的字节数是:"+long1); System.out.println("-----------分割线--------------"); /* 按照给定的硬盘目录文件路径及名称,读取目标文件并返回*/ String path = "e:/files3/七绝.txt"; //建立一个文件对象file2接收调用创建目标文件的方法的返回值 File file2 = fil.readFile(path); System.out.println("目标文件 "+file2); System.out.println("-----------分割线--------------"); } }
/** * 2 在任务1的基础上,定义编写一个新接口FileAdvancedSupport 继承FileBasicSupport,并新添加以下抽象方法: * * 对给定的目录进行迭代,并返回此目录下的所有包含子文件目录下的所有文件 * * 并返回List<File> * * public abstract List<File> folderIteration(File directory); * * 将给定的源文件拷贝到目标目录文件 * * public abstract void copyFile(File sourceFile,String savePath,String fileName); * * 编写一个类实现上述FileAdvancedSupport接口并对接口中的抽象方法进行功能实现. * * 编写测试类包含main方法实现功能测试. */ package main; import until.FileManager2; import java.io.File; import java.util.ArrayList; import java.util.List; public class TestCopy { public static void main(String[] args) { FileManager2 fil = new FileManager2(); /* 对给定的目录进行迭代,并返回此目录下的所有包含子文件目录下的所有文件 * 并返回List<File> */ //建立一个文件路径对象 File directory = new File("e:/files3/"); //创建一个数组,用来作为递归的参数 List<File> list = new ArrayList<>(); //调用迭代的方法,定义一个File类型的List接收返回值 List<File> list2 = fil.folderIteration(directory,list); //输出目标路径下所有文件的路径和文件名称 for (File f:list){ System.out.println(f.getAbsolutePath()); } System.out.println("------------分割线--------------"); /* 将给定的源文件拷贝到目标目录文件*/ File sourceFile = new File("e:/files3/七绝.txt"); //给定的源文件 String savePath = "e:/files3/copyFile/"; //目标的目录 String fileName = "复制的文件.txt"; //目标的文件名称 //调用复制文件的方法 fil.copyFile(sourceFile,savePath,fileName); } }
package Interfaces; import java.io.File; public interface FileBasicSupport { /* 按照给定的目录名称,在硬盘上创建此目录 */ public abstract void createFolder(String folderPath); /* 按照给定的父目录名称及文件名称,创建目标文件并返回此文件对象*/ public abstract File createTargetFile(String parent , String fileName); /* 将给定的字符串内容写入到目录文件中,返回写入的字节数 */ public abstract long writeFile(File file,String content); /* 按照给定的硬盘目录文件路径及名称,读取目标文件并返回*/ public abstract File readFile(String path); }
package Interfaces; import java.io.File; import java.util.List; public interface FileAdvancedSupport extends FileBasicSupport{ /* 对给定的目录进行迭代,并返回此目录下的所有包含子文件目录下的所有文件 * 并返回List<File> */ public abstract List<File> folderIteration(File directory,List<File> list); /* 将给定的源文件拷贝到目标目录文件*/ public abstract void copyFile(File sourceFile,String savePath,String fileName); }
package Adaptor; import Interfaces.FileAdvancedSupport; import java.io.File; import java.util.List; public class FileAdvancedSupportAdaptor implements FileAdvancedSupport { @Override public List<File> folderIteration(File directory,List<File> list) { return null; } @Override public void copyFile(File sourceFile, String savePath, String fileName) { } @Override public void createFolder(String folderPath) { } @Override public File createTargetFile(String parent, String fileName) { return null; } @Override public long writeFile(File file, String content) { return 0; } @Override public File readFile(String path) { return null; } }