JAVA中的I/O流以及文件操作
一 JAVA语言中主要通过流来完成IO操作。
流:计算机的输入输出之间流动的数据序列,也是类的对象。java中的流方式就像是建立在数据交换源和目的之间的一条通信路径。
数据源:计算机中的数据源是指可以提供数据的地方,包括键盘,磁盘文件,网络接口等。
输入流:从程序外部传向程序的流。输入流只能从中读数据。
输出流: 从程序传到外部的流。输出流只能向其写入数据。
所谓的输入和输出是以程序为中心的,数据流向程序即输入流,数据从程序中流出即输出流。
二 字节流
字节流是以字节为传输单位的数据读写形式,用于直接读取二进制数据,如图像和声音文件等。
InputStream和OutputStream分别为面向字节的输入流类的父类和输出流类的父类。InputStream和OutputStream都是抽象类。
FileInputStream和FileOutputStream是文件流类,他们是InputStream和OutputStream的子类。
FileInputStream类的一般用法是:先创建一个FileInputStream对象关联到要读取的文件,然后调用read方法读取字节数据到程序中,再进行其他处理。因为read方法是按字节的读入的,所以汉字被读入时会出现乱码。
FileOutputStream类的一般用法是:先创建一个FileOutputStream对象关联到要写入的文件,然后调用write方法将字节数据写到程序中。如果进行写操作的文件不存在,则自动创建该文件,但是如果文件所在的路径也不存在,则运行时会报错。
例如 FileOutputStream fos = new FileOutputStream("D:\\test.txt");是不会报错的,
FileOutputStream fos = new FileOutputStream("D:\\tmp\\test.txt");如果之前在D盘中没有tmp这个文件夹,那么此时运行这条语句会报错。
代码如下
package 文件操作_FileInputStream和FileOutputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException; public class FileDemo {
public static void main(String[] args) {
try {
FileInputStream fis = new FileInputStream("D:\\test.txt");
int ch = fis.read();
while (ch != -1) {
System.out.print((char) ch);
ch = fis.read();
}
// byte[] buffer = new byte[8];
// fis.read(buffer);
// for (int i = 0; i < buffer.length; i++) {
// System.out.print((char) buffer[i]);
// }
FileOutputStream fos = new FileOutputStream("D:\\test1.txt");
byte[] b = {'a', 'c', 'd', 'e', 'x'};
fos.write(b);
fis.close();
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} }
缓存流 BufferedInputStream 和 BufferedOutputStream
使用缓存流可以提高大文件的读写效率。例如从文件读入数据时,每次从输入流中读取较大的数据量存入内存缓冲区,具体的读操作针对该缓冲区进行;执行缓冲输出时,每次将输出流中的数据写入到内存缓冲区,知道缓冲区写满,才将数据写入到最终的介质中。
使用缓存流的缺点:当计算机突然关闭时,可能会丢失数据。通过清空缓冲区的数据可以减少这种情况的发生,使用flush()方法即可。
代码如下
package 文件操作_BufferedInputStream; import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException; public class BufferDemo {
public static void main(String[] args) {
try {
FileInputStream fis = new FileInputStream("D:\\test.txt");
BufferedInputStream bis = new BufferedInputStream(fis); //默认的输入缓冲区是2048B
int ch = bis.read();
while (ch != -1) {
System.out.print((char)ch);
ch = bis.read();
} } catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} }
三 字符流
Reader 和 Writer类是所有字符流的父类。一次读取或是写入两个字节,16位,即一个Unicode字符,因此可以使用字符流直接读写汉字内容。
BufferedReader 和 BufferedWriter类的用法示例
package 文件操作_字符流_BufferedReader和BufferedWriter; import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException; public class BufferedDemo {
public static void main(String[] args) {
try {
FileReader fr = new FileReader("D:\\test.txt");
BufferedReader br = new BufferedReader(fr);
FileWriter fw = new FileWriter("D:\\test1.txt");
BufferedWriter bw = new BufferedWriter(fw);
String str = br.readLine();
while (str != null) {
bw.write(str);
bw.newLine();
str = br.readLine();
}
br.close();
bw.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} }
四 File文件类
File aa = new File(aaName); 这里的aa可以指向文件,也可以指向文件夹
在进行文件的操作时,若操作的对象是文件,那么在进行文件的创建,删除,复制之前,
(1)需要判断文件是否存在,
(2)以及File所指向的对象是一个文件还是一个文件夹(目录)
(3)该文件所在的文件夹是否存在,file.getParentFile().exists()
(4)若文件所在的文件夹不存在,需要建立其父文件夹,若未建立成功,返回false
if (!file.getParentFile().mkdirs()) return false;
在对文件夹(目录)进行操作时,
(1)首先判断 dirName 是不是以文件分隔符 File.separator结尾,如果不是,
则 dirName += File.separator;
(2)需要判断 File dir = new File(dirName) 中的dir是不是存在以及指向的是不是一个文件夹 dir.exists() dir.isDirctory();
(3) 在对文件夹进行复制,删除等操作时,一般会用到递归,因为文件夹里面有时候会存在子文件夹。
程序示例1 删除指定目录下的文件
package 输入输出流_删除指定目录下的文件; import java.io.File; //delete()方法可以删除文件和文件夹,当成功删除文件或文件夹后,返回true 否则返回false
//在使用delete()方法时,如果此路径名表示一个文件夹(目录),则此目录必须为空才能删除
//(若要删除文件夹,需要先删除文件夹中的文件和文件夹,才能删除该文件夹)
public class FileDemo_05 { public static boolean deleteFilesOrDir (String fileName) {//判断将指定文件或文件夹删除是否成功
File file = new File(fileName);
if (!file.exists()) { //指定的文件或文件夹不存在,返回false
System.out.println("文件删除失败,因为文件" + fileName + "不存在");
return false;
} else { //指定的文件或是文件夹存在
if (file.isFile()) { //若file 是文件
return FileDemo_05.deleteFiles(fileName);
} else { //若file是文件夹
return FileDemo_05.deleteDir(fileName);
}
} } public static boolean deleteFiles(String fileName) { //判断删除指定文件是否成功
File file = new File(fileName);
if ( file.exists() && file.isFile() ) {
if (file.delete()) {
System.out.println("文件" + fileName + "删除成功!");
return true;
} else {
System.out.println("文件" + fileName + "删除失败!");
return false;
}
} else {
System.out.println("文件删除失败 : " + fileName + "文件不存在!");
return false;
} } public static boolean deleteDir(String dir) { //判断删除指定文件夹以及文件夹下的文件是否成功
if (!dir.endsWith(File.separator)) {
dir += File.separator;
}
File dirFile = new File(dir);
if (!dirFile.exists() || !dirFile.isDirectory()) {
System.out.println("文件夹删除失败!" + dir + "文件夹不存在");
return false;
}
boolean flag = true;
File[] files = dirFile.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isFile()) { //删除文件
flag = FileDemo_05.deleteFiles(files[i].getAbsolutePath());
if (!flag) {
break;
}
} else if (files[i].isDirectory()) { //删除子文件夹,此处为递归
flag = FileDemo_05.deleteDir(files[i].getAbsolutePath());
if (!flag) {
break;
}
}
}
if (!flag) {
System.out.println("删除文件夹失败");
}
if (dirFile.delete()) {
System.out.println("文件夹" + dir + "删除成功!");
return true;
} else {
return false;
}
} }
程序示例2 移动指定目录下的文件,该程序用到了 程序示例1
package 输入输出流_移动指定目录下的文件;
import java.io.File;
public class FileDemo_06 {
//英东某个指定的文件,但移动成功后不会覆盖已存在的文件
public static boolean moveA_File(String sourceFileName, String targetFileName) {
return FileDemo_06.moveA_File(sourceFileName, targetFileName, false);
}
//移动某个指定的文件,但移动成功后可以根据isOverlay的值来决定是否覆盖已存在的目标文件
public static boolean moveA_File(String sourceFileName, String targetFileName,
boolean isOverlay) {
File sourceFile = new File(sourceFileName);
if (!sourceFile.exists()) {
System.out.println("文件" + sourceFileName + "不存在,移动失败");
return false;
} else if (!sourceFile.isFile()) {
System.out.println(sourceFileName + "不是文件,移动失败");
return false;
}
File targetFile = new File(targetFileName);
if (targetFile.exists()) {
if (isOverlay) {
System.out.println("目标文件已经存在,准备删除它");
if (!FileDemo_05.deleteFilesOrDir(targetFileName)) {
System.out.println("文件移动失败,文件" + targetFileName + "删除失败");
return false;
}
} else {
System.out.println("文件移动失败,因为文件" + targetFileName + "已经存在");
return false;
}
} else {
if (!targetFile.getParentFile().exists()) {
System.out.println("文件" + targetFile + "所在的目录不存在,正在创建");
if (!targetFile.getParentFile().mkdirs()) {
System.out.println("移动文件失败,因为创建文件坐在的文件夹失败");
return false;
}
}
}
//移动源文件至目标文件
if (sourceFile.renameTo(targetFile)) {
System.out.println("移动源文件" + sourceFileName + "到" + targetFileName
+ "成功" );
return true;
} else {
System.out.println("移动源文件" + sourceFileName + "到" + targetFileName
+ "失败" );
return false;
}
}
public static boolean moveDir(String sourceDirName, String targetDirName) {
//默认为不覆盖目标文件
return FileDemo_06.moveDir(sourceDirName, targetDirName, false);
}
//移动某个指定的目录,但移动成功后可以根据isOverlay的值来决定是否覆盖当前已存在的目标目录
public static boolean moveDir(String sourceDirName, String targetDirName,
boolean isOverlay) {
//判断原目录是否存在
File sourceDir = new File(sourceDirName);
if (!sourceDir.exists()) {
System.out.println("源目录" + sourceDirName + "不存在,移动目录失败");
return false;
} else if (!sourceDir.isDirectory()) {
System.out.println("移动目录失败," + sourceDirName + "不是目录");
return false;
}
//如果目标文件名不是以文件分割符结尾,自动添加文件分隔符
if (!targetDirName.endsWith(File.separator)) {
targetDirName += File.separator;
}
File targetDir = new File(targetDirName);
//如果目标文件夹存在
if (targetDir.exists()) {
if (isOverlay) {
//允许删除则删除已存在的目标目录
System.out.println("该目录已经存在,准备删除它");
if (!FileDemo_05.deleteFilesOrDir(targetDirName)) {
System.out.println("移动目录失败,因为目标目录已经存在。 删除目录" +
targetDirName + "失败!" );
}
} else {
System.out.println("移动目录失败:该目录" + targetDirName + "已存在!");
return false;
}
} else {
//创建目标目录
System.out.println("该目录不存在,正在创建");
if (!targetDir.mkdirs()) {
System.out.println("移动目录失败: 创建目标目录失败");
return false;
}
}
boolean flag = true;
//移动原目录下的文件和子目录到目标目录下
File[] files = sourceDir.listFiles();
for (int i = 0; i < files.length; i++) {
//移动子文件
if (files[i].isFile()) {
flag = FileDemo_06.moveA_File(files[i].getAbsolutePath(),
targetDirName + files[i].getName(), isOverlay);
if (!flag) {
break;
}
} else if (files[i].isDirectory()) { //移动子目录
flag = FileDemo_06.moveDir(files[i].getAbsolutePath(),
targetDirName + files[i].getName(), isOverlay);
if (!flag) {
break;
}
}
}
if (!flag) {
System.out.println("目录" + sourceDirName + "移动到" + targetDirName + "失败");
return false;
}
//删除原目录
if (FileDemo_05.deleteDir(sourceDirName)) {
System.out.println("目录" + sourceDirName + "移动到" + targetDirName + "成功");
return true;
} else {
System.out.println("目录" + sourceDirName + "移动到" + targetDirName + "失败");
return false;
}
}
public static void main(String[] args) {
//移动文件,如果目标文件存在,则替换
System.out.println("调用moveA_File方法的结果如下");
String sourceFileName = "D:\\aa\\temp\\key.txt";
String targetFileName = "D:\\bbb\\ddd\\";
FileDemo_06.moveA_File(sourceFileName, targetFileName);
//移动目录,如果目标目录存在,则不覆盖
System.out.println("\n调用moveDir方法的结果如下");
String sourceDir = "D:\\aa";
String targetDir = "C:\\mm";
FileDemo_06.moveDir(sourceDir, targetDir,false);
}
}
JAVA中的I/O流以及文件操作的更多相关文章
- Java中字节流和字符流复制文件
字节流和字符流复制文件的过程: 1.建立两个流对象 绑定数据源和目的地 2.遍历出需复制的文件写入复制过后的新文件中(只不过是遍历的时候是区分字节和字符的) 3.访问结束后关闭资源 字节流复制文件: ...
- Java 基础-IO、stream 流、文件操作
输入输出流的分类 在 java.io 包中,包含了输入输出操作所需的类. I/O 流可以安装不同的标准分类: 按照流的方向分类: 输入流:将信息从代码外部输入代码 输出流:将代码得到的数据输出到文件. ...
- java中Optional和Stream流的部分操作
package test9; import java.util.DoubleSummaryStatistics; import java.util.Optional; import java.util ...
- java IO流 对文件操作的代码集合
Io流 按照分类 有两种分类 流向方向: 有输入流和输出流 按照操作类型有:字节流和字符流 按照流向方向 字节流的一些操作 //读文件 FileInputStream fis = new FileIn ...
- java中File的delete()方法删除文件失败的原因
java中File的delete()方法删除文件失败的原因 学习了:http://hujinfan.iteye.com/blog/1266387 的确是忘记关闭了: 引用原文膜拜一下: 一般来说 ja ...
- java中如何创建带路径的文件
请教各位大侠了,java中如何创建带路径的文件,说明下 这个路径不存在 ------回答--------- ------其他回答(2分)--------- Java code File f = new ...
- Java中list如何利用遍历进行删除操作
转: Java中list如何利用遍历进行删除操作 2018年03月31日 10:23:41 Little White_007 阅读数:3874 Java三种遍历如何进行list的便利删除: 1.f ...
- java中对对象进行判空的操作--简洁编码
java中对对象进行判空的操作 首先来看一下工具StringUtils的判断方法: 一种是org.apache.commons.lang3包下的: 另一种是org.springframework.ut ...
- java中字节流和字符流的区别
流分类: 1.Java的字节流 InputStream是所有字节输入流的祖先,而OutputStream是所有字节输出流的祖先.2.Java的字符流 Reader是所有读取字符串输入流的祖先,而 ...
随机推荐
- POJ 2524 :Ubiquitous Religions
id=2524">Ubiquitous Religions Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 231 ...
- 查询oracle表字段信息
表字段的信息咱们可以称之为元数据,今天有人问怎么把表字段的信息导出来,说实话我还不会用plsql develper把表的结构导出来,像下图所示: 在写数据库设计说明书的时候,想要把这个表格拷贝出来,这 ...
- XSS漏洞的分类
XSS漏洞依照攻击利用手法的不同,有下面三种类型: 类型A,本地利用漏洞,这样的漏洞存在于页面中client脚本自身.其攻击步骤例如以下所看到的: Alice给Bob发送一个恶意构造了Web的URL. ...
- 在MyEclipse中编写Web Project,编码设置全集合
1.window-->preference-->general-->content type 然后在<Content Types>中展开每一颗子项,并在<Defau ...
- WPF换肤之六:酷炫的时区浏览小精灵
原文:WPF换肤之六:酷炫的时区浏览小精灵 由于工作需要,经常要查看到不同地区的 当前时间,以前总是对照着时区表来进行加减运算,现在有了这个小工具以后,感觉省心了不少.下面是软件的截图: 效果图赏析 ...
- app服务器
http://heipark.iteye.com/blog/1847421http://heipark.iteye.com/blog/1847421http://wenku.baidu.com/vie ...
- Qt之QComboBox(基本应用、代理设置)
QComboBox下来列表比较常用,用户可以通过选择不同的选项来实现不同的操作,如何实现自己的下拉列表呢? 很多人在问QComboBox如何设置选项的高度.代理等一些问题!今天就在此分享一下自己的一些 ...
- 使用VBA将批量的WORD文档转换为PDF
Sub BatchConvertToPDF() Dim destFolderPath As String destFolderPath = GetFolderPath If destFolderPat ...
- log4net和一般的记录日志方法
下载 http://files.cnblogs.com/crazyair/log4net.zip 1 在web项目中新建一个 Log4Net.config <?xml version=" ...
- 编译gRPC
编译gRPC 目录 一.概述 二.编译gRPC 三.C#中使用gRPC 四.C++中使用gRPC 无论通过哪种语言调用gRPC,都必须要编译gRPC,因为生成proto访问类时,除了产生标准的数据定义 ...