java之I/O流

一、输入/输入流

1、输入流

  • InputStream类是字节输入流的抽象类,是所有字节输入流的父类。java中的字符是Unicode编码,是双字节的,而InputStream类是用来处理字节的,并不适合处理字符文本。
  • Reader类是字符输入流的抽象类,所有的字符输入流都是它的子类。

2、输出流

  • outputStream类是字节输出流的抽象类,此抽象类是表示输出字节流的所有类的超类。
  • writer类是字符输出流的抽象类,所有字符输出类的实现都是它的子类。

二、File类

1、创建File对象

  1. File(String pathname)——通过将给定路径名字符串转换为抽象路径名来创建一个新File实例
    如:File file=new File(“d:/1.txt”);
  2. File(String parent,String child)——通过父路径和子路径字符串创建一个新的File对象
    如:new File(“D:/doc/,letter.txt”);其中parent为父路径字符串
  3. File(File f,String child)——通过parent抽象路径名和child路径名字符串创建一个新的File实例
    如:new File(File parent,String child);其中parent为父路径对象

2、文件操作
常见的文件操作主要有判断文件是否存在、创建文件、重命名文件、删除文件以及获取文件基本信息(文件名称、大小、修改时间、是否隐藏等)。

示例:在项目中创建FileTest类,在主方法判断test.txt是否存在,如果不存在,则创建文件;如果存在,则获取该文件的相关信息,包括文件是否可读、文件的名称、绝对路径、是否隐藏、字节数、最后修改时间,获得这些信息后,将该文件删除。

public class FileTest {

	public static void main(String[] args) {
		File file=new File("test.txt");
		if(!file.exists()) {//判断文件是否存在,第一次运行时会执行该语句块
			System.out.println("文件不存在,正在创建...");
			try {
				file.createNewFile();
			} catch (IOException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
			System.out.println("文件创建成功!");
		}else {
			System.out.println("文件存在");
			if(file.isFile()&&file.canRead()) {//该文件时标准文件且可读
				System.out.println("文件可读!正在读取文件");
				String fileName=file.getName();
				String filePath=file.getAbsolutePath();
				boolean hidden=file.isHidden();
				long len=file.length();
				
				System.out.println("文件名:"+fileName);
				System.out.println("文件的绝对路径:"+filePath);
				System.out.println("文件是否是隐藏文件:"+hidden);
				System.out.println("文件中的字节数:"+len);
				
				file.delete();
				System.out.println("文件已被删除");
			}
		}
	}
}

3、文件夹操作
常见的文件夹操作主要有判断文件夹是否存在、创建文件夹、删除文件夹、获取文件夹包含的子文件夹及文件等。

示例:在项目中创建类FolderTest,在主方法中判断C盘下是否存在Test文件夹,如果不存在,则创建该文件夹,并在文件夹下创建10个子文件夹;然后获取C盘根目录下的文件及文件夹并显示。

public class FolderTest {

	public static void main(String[] args) {
		String path="C:\\Test";
		for(int i=1;i<=10;i++) {
			File folder=new File(path+"\\"+i);
			if(!folder.exists()) {
				folder.mkdirs();//创建新的文件夹
			}
			System.out.println("文件夹创建成功,可在C盘中查看!\n\nC盘文件及文件夹目录如下:");
			File file=new File("C:\\");//根据路径名创建File对象
			File[] files=file.listFiles();//获得C盘所有文件和文件夹
			for(File test:files) {//遍历files数组
				if(test.isFile()) {
					System.out.println(test.getName()+"文件");
				}
				else if(test.isDirectory()) {
					System.out.println(test.getName()+"文件夹");
				}
			}
		}
	}
}

三、文件的输入/输出流

1、FileInputStream类和FileOutputStream类
FileInputStream类常用的构造方法如下:

  1. FileInputStream(String name):使用给定的文件名name创建一个FileInputStream对象
  2. FileInputStream(File file):使用File对象创建FileInputStream对象,该方法允许在把文件连接输入流之前对文件做进一步分析

FileOutputStream类常用的构造方法如下:

  1. FileOutputStream(File file):创建一个向指定File对象表示的文件中写入数据的文件输出流
  2. FileOutputStream(File file,boolean append):创建一个向指定File对象表示的文件写入数据的文件输出流,若第二个参数为true,表示字节写入文件末尾处而不是文件开始处
  3. FileOutputStream(String name):创建一个向具有指定名称的文件中写入数据的文件输出流
  4. FileOutputStream(String name,boolean append)创建一个向具有指定名称的文件写入数据的文件输出流,若第二个参数为true,表示字节写入文件末尾处而不是文件开始处

示例:使用FileOutputStream类向文件写入信息,并通过FileInputStream类将文件中的数据读取到控制台

public class FileStreamTest {

	public static void main(String[] args) {
		File file=new File("word.txt");
		try {
			FileOutputStream out=new FileOutputStream(file);
			String content="听说程序员都会秃顶";
			byte[] by=content.getBytes();//创建byte型数组,将要写入的文件的内容转换为字节数组
			out.write(by);
			out.close();
		} catch (FileNotFoundException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		
		try {
			FileInputStream in=new FileInputStream(file);
			byte byt[]=new byte[1024];//创建byte数组,用来存储读取到的内容
			int len=in.read(byt);//从文件中读取信息,并存入字节数组
			System.out.println("文件中的信息为:"+new String(byt,0,len));
			in.close();
		} catch (FileNotFoundException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
	}
}

2、FileReader类和FileWriter类
使用FileOutputStream类向文件中写入数据与使用FileInputStream类从文件中将内容读出来,都存在一点不足,即这两个类都只提供了对字节或字节数组的读取方法。由于汉字在文件中占用了两个字节,因此使用字节流,读取不当会导致出现乱码现象,此时采用字符流Reader或Writer类即可避免这种现象。
FileReader构造方法与FileInputStream类的构造方法相似;FileWriter构造方法与FileOutputStream类的构造方法相似。

示例:使用Filewriter类向文件写入信息,然后通过FileReader类将文件中的数据读取到控制台

public class ReaderAndWriter {

	public static void main(String[] args) {
		while(true) {
			File file=new File("word.txt");
			try {
				if(!file.exists()) {
					file.createNewFile();
				}
				System.out.println("请输入要执行的操作编号:1、写入文件;2、读取文件");
				Scanner sc=new Scanner(System.in);
				int choice=sc.nextInt();
				switch(choice) {
				case 1:
					System.out.println("请输入要写入的内容:");
					String tempStr=sc.next();
					FileWriter fw=null;
					try {
						fw=new FileWriter(file,true);
						fw.write(tempStr+"\r\n");
					} catch (IOException e) {
						// TODO 自动生成的 catch 块
						e.printStackTrace();
					}finally {
						fw.close();
					}
					System.out.println("上述内容已经写入到文本文件中");
					break;
				case 2:
					try {
						FileReader fr=null;
						if(file.length()==0) {
							System.out.println("文本中的字符数为0");
						}else {
							fr=new FileReader(file);
							char[] cbuf=new char[1024];
							int hasread=-1;
							while((hasread=fr.read(cbuf))!=-1) {
								System.out.println("文件中的内容为:\n"+new String(cbuf,0,hasread));
								break;
							}
						}
					} catch (Exception e) {
						// TODO 自动生成的 catch 块
						e.printStackTrace();
					}
				default:
					System.out.println("请输入有效的数字!1");
				}
			} catch (IOException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}
	}

}

四、带缓冲的输入/输出流

1、BufferedInputStream类和BufferedOutputStream类
BufferedInputStream类可以对所有InputStream类进行带缓冲区的包装达到性能的 优化
BufferedInputStream类的两个构造方法:

  1. BufferedInputStream(InputStream in):创建了一个带有32个字节的缓冲输入流
  2. BufferedInputStream(inputStream in,int size):按指定的大小来创建缓冲输入流

使用BufferedOutputStream输出信息和用OutputStream输出信息完全一样,只不过BufferedOutputStream用一个flush()方法将缓冲区的数据强制输出完
BufferedoutputStream类的两个构造方法:

  1. BufferedOutputStream(OutputStream out):创建了一个带有32个字节的缓冲输出流
  2. BufferedOutputStream(OutputStream out,int size):按指定的大小来创建缓冲输出流

注意:flush()方法就是用于及时在缓冲区没有满的情况下,也将缓冲区的内容强制写入外设,称为刷新。当调用close()方法时,系统在关闭流之前,也会将缓冲区的信息刷新到磁盘文件中。

示例:向文件中写入和读取数据时,分别借用BufferedInputStream类和BufferedOutputStream类实现

public class BufferedStreamTest {

	public static void main(String[] args) {
		String content[]= {"听说程序员都秃顶!","我是程序员,","所以我也秃顶?"};
		File file=new File("word.txt");
		FileOutputStream fos=null;
		BufferedOutputStream bos=null;
		FileInputStream fis=null;
		BufferedInputStream bis=null;
		
		try {
			fos=new FileOutputStream(file);
			bos=new BufferedOutputStream(fos);
			byte[] bContent=new byte[1024];//创建可以容纳1024个字节数的缓冲区
			for(int k=0;k<content.length;k++) {
				bContent=content[k].getBytes();//将遍历到的数组内容转换为字节数组
				bos.write(bContent);
			}
			System.out.println("写入成功!");
		} catch (FileNotFoundException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}finally {
			try {
				bos.close();
				fos.close();
			} catch (IOException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}
		try {
			fis=new FileInputStream(file);
			bis=new BufferedInputStream(fis);
			byte[] bContent=new byte[1024];
			int len=bis.read(bContent);
			System.out.println("文件中的信息为:"+new String(bContent,0,len));
		} catch (FileNotFoundException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}finally {
			try {
				bis.close();
				fis.close();
			} catch (IOException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}
		
	}

}

2、BufferedReader类和BufferedWriter类
BufferedReader类的常用方法:

  • read()——返回int,读取单个字符
  • readLine()——返回String,读取一个文本行,并将其返回为字符串。若无数据可读,则返回null

BufferWriter类的常用方法:

  • write(String s,int off,int len)——写入字符串的某部分
  • flush()——刷新该流的缓冲
  • newLine()——写入一个行分隔符
    说明:使用BufferedWriter类的write()方法时,数据 并没有立刻被写入至输出流,而是首先进入缓冲区,如果想要立刻将缓冲区的数据写入输出流,一定要调用flush()方法。

示例:首先用BufferedWriter类将数组中的字符串分行写入指定文件中,然后通过BufferReader类将文件中的信息分行显示

public class BufferedWriterAndBufferedRead {

	public static void main(String[] args) {
		String content[]= {"听说程序员都秃顶!","我是程序员,","所以我也秃顶?"};
		File file=new File("word.txt");
		try {
			FileWriter fw=new FileWriter(file);
			BufferedWriter bufw=new BufferedWriter(fw);
			for(int k=0;k<content.length;k++) {
				bufw.write(content[k]);//将字符串数组中的元素写入磁盘文件中
				bufw.newLine();//将数组中的单个元素以单行的形式写入文件中
			}
			bufw.close();
			fw.close();
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		try {
			FileReader fr=new FileReader(file);
			BufferedReader bufr=new BufferedReader(fr);
			String s=null;
			int i=0;
			while((s=bufr.readLine())!=null) {
				i++;
				System.out.println("第"+i+"行:"+s);
			}
			bufr.close();
			fr.close();
		} catch (FileNotFoundException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
	}

}

五、数据输入/输出流

数据输入/输出流(DataInputStream类和DataOutputStream类)允许应用程序从输入流读取java基本数据类型的数据,也就是说,当读取一个数据时,不再关心这个数值是哪种类型。
DataInputStream类和DataOutputStream类构造方法如下:

  • DataInputStream(InputStream in):使用指定基础InputStream创建一个DataInputStream
  • DataOutputStream(OutputStream out):创建一个新的数据输出流,将数据写入指定基础输出流

示例:通过DataOutputStream类的写入方法向指定的磁盘文件中写入不同类型的数据,然后通过DataOutputStream类的相应读取方法将写入的不同类型的数据输出到控制台

public class DataTest {
	public static void main(String[] agrs) {
		try {
			FileOutputStream fos=new FileOutputStream("word.txt");
			DataOutputStream dos=new DataOutputStream(fos);
			dos.writeUTF("使用writerUTF()方法写入数据");
			dos.writeDouble(19.8);
			dos.writeInt(198);
			dos.writeBoolean(true);
			dos.close();
			FileInputStream fis=new FileInputStream("word.txt");
			DataInputStream dis=new DataInputStream(fis);
			System.out.println("readUTF方法读取数据:"+dis.readUTF());
			System.out.println("readDouble方法读取数据:"+dis.readDouble());
			System.out.println("readInt方法读取数据:"+dis.readInt());
			System.out.println("readBoolean方法读取数据:"+dis.readBoolean());
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值