IO总结

15 篇文章 0 订阅

一、IO概述
    1.字节流(常用来copy文件)
        InputStream
                |--FileInputStream(只能读字节)
                     创建对象,关联文件,调用read()的方法可以读取一个字节,读到末尾则返回-1
                |--FilterInputStream
                                |--BufferedInputStream
                                    自带缓冲功能,一批一批的读到自己的缓冲区内,而不是一个字节一个字节的读,减少操作文件的次数.
      OutputStream
                |--FileOutputStream (可追加)
                    创建对象,关联文件,文件若不存在则创建,存在则清空,如果要追加,则传true.
                |--FilterOutputStream
                               |--BufferedOutputStream
                                   写出,先写到自己的缓冲区,写满或刷新或关闭流时,才会写到文件中.
   2.字符流
        Reader
                 |--BufferedReader
                    包装一个Reader,提供缓冲功能,而且有readLine()方法
                              |--LineNumberReader
                                  带缓冲,可以读取一行,还能统计行号.
                 |--InputStreamReader(转换流,可指定编码)
                        包装一个InputStream,可以直接读取字符,可以在构造函数中指定编码
                              |--FileReader
                                  只能读取平台默认码表的文件.
      Writer
                |--BufferedWriter
                   包装一个writer,提供缓冲功能,提供newLine()方法.
                |--OutputStreamWriter(转换流,可指定编码)
                   包装一个OutputStream,直接写出字符.
                             |--FileWriter
                                 只能写出平台默认码表的文件.
    3.字符流能不能copy文件?什么时候用字符流
         如果是纯文本文件,可以用字符流拷贝,但不推荐,因为效率不高
              在拷贝的时候会将数据读取出来解码为字符,然后再将字符编码回字节写入文件.
              而字节流直接读取字节,写出字节就可以.
        如果不是文本文件,例如视频,图片等,是不能使用字符流拷贝的.
    4.File类
      (1)什么是File类
               File类代表一个文件或文件夹的路径.
      (2)构造函数
               File(String pathname)    
               File(String parent, String child)
               File(File parent, String child)
     (3)常用方法
              String getName()
              String getParent()
              long length()
              long lastModified()
              boolean exists()
              boolean isFile()
              boolean isDirectory()
              boolean renameTo(File dest) //改名,可用来剪切
              boolean createNewFile()
              boolean mkdir()    //创建文件夹(不包含父级)
              boolean mkdirs()   //创建文件夹(包含父级)
              boolean delete()
              String[] list()    //获取文件夹下的所有子文件名(String)
              File[] listFiles() //获取文件夹下的所有子文件(File对象)

二、练习
    1.copy一个文件或音乐或视频,要求用三种方式.      
    2.写一个方法copyDir(File src, File dest),把src拷贝到dest中, 并且.java文件和.txt文件前面加上行号和冒号 

	//练习一
	import java.io.BufferedInputStream;
	import java.io.BufferedOutputStream;
	import java.io.FileInputStream;
	import java.io.FileOutputStream;
	import java.io.IOException;
	
	public class Demo1 {
		// 假设g盘下有test.mp3这个音乐文件
		public static void main(String[] args) throws IOException {
			copy1("g:/test.mp3", "e:/");
			copy2("g:/test.mp3", "e:/");
			copy3("g:/test.mp3", "e:/");
		}
	
		// 第一种方式,效率最低的一种,一个一个字节的读出与写出
		public static void copy1(String src, String dest) throws IOException {
			FileInputStream fis = null;
			FileOutputStream fos = null;
			try {
				fis = new FileInputStream(src);
				fos = new FileOutputStream(dest);
				int b;
				while ((b = fis.read()) != -1)
					fos.write(b);
			} finally {
				try {// 流最后必须关掉,所以要写进finally里边确保最后关闭流
					if (fis != null)
						fis.close();
				} finally {
					if (fos != null)
						fos.close();
				}
			}
		}
	
		// 第二种方式,效率最快,
		public static void copy2(String src, String dest) throws IOException {
			FileInputStream fis = null;
			FileOutputStream fos = null;
			try {
				fis = new FileInputStream(src);
				fos = new FileOutputStream(dest);
				byte[] buffer = new byte[1024];
				int len;
				while ((len = fis.read(buffer)) != -1)
					fos.write(buffer, 0, len);
			} finally {
				try {// 流最后必须关掉,所以要写进finally里边确保最后关闭流
					if (fis != null)
						fis.close();
				} finally {
					if (fos != null)
						fos.close();
				}
			}
		}
	
		// 第三种方式,效率比第二种方式略微低一点.
		public static void copy3(String src, String dest) throws IOException {
			BufferedInputStream bis = null;
			BufferedOutputStream bos = null;
			try {
				bis = new BufferedInputStream(new FileInputStream(src));
				bos = new BufferedOutputStream(new FileOutputStream(dest));
				int b;
				while ((b = bis.read()) != -1)
					bos.write(b);
			} finally {
				try {
					if (bis != null)
						bis.close();
				} finally {
					if (bos != null)
						bos.close();
				}
			}
		}
	}
	//练习二
	import java.io.BufferedWriter;
	import java.io.File;
	import java.io.FileInputStream;
	import java.io.FileOutputStream;
	import java.io.FileReader;
	import java.io.FileWriter;
	import java.io.IOException;
	import java.io.LineNumberReader;
	
	public class IOReview {
		//假设g:/java/day20这个文件夹存在.
		public static void main(String[] args) throws IOException {
			File src = new File("g:/java/day20");
			File dest = new File("g:/");
			copyDir(src, dest);
		}
	
		// 把src拷贝到dest中, .java文件和.txt文件前面加上行号和冒号
		private static void copyDir(File src, File dest) throws IOException {
			File newDir = new File(dest, src.getName());
			newDir.mkdir();
	
			File[] fileArr = src.listFiles();
			for (File file : fileArr)
				if (file.isFile())
					copyFile(file, new File(newDir, file.getName()));
				else
					copyDir(file, newDir);
		}
	
		private static void copyFile(File src, File dest) throws IOException {
			if (src.getName().endsWith(".java") || src.getName().endsWith(".txt")) {
				LineNumberReader lnr = new LineNumberReader(new FileReader(src));
				BufferedWriter bw = new BufferedWriter(new FileWriter(dest));
				String line;
				while ((line = lnr.readLine()) != null) {
					bw.write(lnr.getLineNumber() + ": " + line);
					bw.newLine();
				}
				lnr.close();
				bw.close();
			} else {
				FileInputStream fis = new FileInputStream(src);
				FileOutputStream fos = new FileOutputStream(dest);
				byte[] buffer = new byte[1024];
				int len;
				while ((len = fis.read(buffer)) != -1)
					fos.write(buffer, 0, len);
				fis.close();
				fos.close();
			}
		}
	}


三、IO包中的其他类介绍
    1.打印流(PrintStream)
         PrintStream是一个打印流,他是FilterOutputStream的子类
         可以当作普通的字节输出流使用.还可以输出字符,其print和println方法写出对象时,会将对象的toString()返回值写出.
    2.标准输入输出流
         System.in是一个InputStream,他是标准输入流,默认从键盘读取字节.
         System.out是一个PrintStream,他是标准输出流,默认可以向屏幕输出数据.
         System.setIn(InputStream)可以将标准输入流指向其他数据源.
         System.setOut(OutputStream)可以将标准输出流指向其他数据目的地.
    3.字节数组输出流(ByteArrayOutputStream)
         可以向内存中写出字节的一个输出流,通常可以作为一个缓冲区来使用
    4.数据输入输出流(DataInputStream, DataOutputStream)
         它们可以按照基本数据类型大小读写数据.
         使用DataOutputStream按照基本数据类型大小写出,例如:writeInt()方法可以写出一个int值,占四个字节
         同理,readInt()可以读取4个字节,readLong()可以读取8个字节.
         而普通字节流在读数据只能读一个字节,假如设计一个计算程序运行次数的程序,即向程序运行一次,就读一次然后加一操作再写回文件,
         假如用普通字节流,只能读到0-255,一旦程序运行次数超过255,就又回归到0了,计算不准确了.
    5.对象输入输出流(ObjectInputStream, ObjectOutputStream)
        使用ObjectOutputStream.writeObject()方法可以写出一个实现了Serializable接口的对象
        使用ObjectInputStream.readObject()方法可以读取ObjectOutputStream写出的对象
        如果需要写出多个对象,通常会将多个对象存入集合,然后将集合写出
    6.序列流(SequenceInputStream)      
        可以用来把多个输入流合并成一个
        使用构造函数可以接收2个InputStream, 或者一个包含多个InputStream的Enumeration 

	//代码示例
	import java.io.ByteArrayOutputStream;
	import java.io.FileInputStream;
	import java.io.FileNotFoundException;
	import java.io.FileOutputStream;
	import java.io.IOException;
	import java.io.InputStream;
	import java.io.PrintStream;
	import java.io.SequenceInputStream;
	import java.util.ArrayList;
	import java.util.Collections;
	import java.util.Enumeration;
	
	public class Demo2 {
	
		public static void main(String[] args) throws Exception {
			demo1();
			demo2();
			demo3();
			demo4();
		}
		//PrintStream
		//假设有Person这个类,构造函数的参数有名字和年龄
		public static void demo1() throws Exception {
			Person p1 = new Person("zhangsan", 19);
			Person p2 = new Person("lisi", 20);
			//可以写出对象,会自动将对象的toString()方法写出,还可以指定码表.
			PrintStream ps = new PrintStream("file.txt", "UTF-8");
			ps.println(p1);
			ps.println(p2);
			ps.close();
		}
		//ByteArrayOutputStream
		public static void demo2() throws Exception {
			FileInputStream fis = new FileInputStream("test.txt");
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			byte[] buffer = new byte[1024];
			int len;
			while ((len = fis.read(buffer)) != -1)		
				baos.write(buffer, 0, len);			// 将文件中所有数据写入到内存中
			fis.close();
			baos.close();
			
			byte[] data = baos.toByteArray();		// 获取内存中的数据
			
			FileOutputStream fos = new FileOutputStream("file.txt");
			fos.write(data);						// 一次性写出到文件
			fos.close();
		}
		//ByteArrayOutputStream
		private static void demo3() throws FileNotFoundException, IOException {
			FileInputStream fis = new FileInputStream("day22-笔记.txt");
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			byte[] buffer = new byte[1024];
			int len;
			while ((len = fis.read(buffer)) != -1)
				baos.write(buffer, 0, len);	// 将文件中所有数据写入到内存中
			fis.close();
			baos.close();
			// 把内存中的数据取出, 一次性转为字符
			String content = new String(baos.toByteArray());	
			System.out.println(content);
		}
		//SequenceInputStream
		private static void demo4() throws FileNotFoundException, IOException {
			FileInputStream fis1 = new FileInputStream("a.txt");
			FileInputStream fis2 = new FileInputStream("b.txt");
			FileInputStream fis3 = new FileInputStream("c.txt");
			
			ArrayList<InputStream> al = new ArrayList<InputStream>();// 为了得到Enumeration创建ArrayList
			Collections.addAll(al, fis1, fis2, fis3);				// 装入输入流
			Enumeration<InputStream> e = Collections.enumeration(al);// 获取Enumeration
			
			SequenceInputStream sis = new SequenceInputStream(e);// 合并
			FileOutputStream fos = new FileOutputStream("file.txt");
			int i;
			while ((i = sis.read()) != -1)	// 使用SequenceInputStream读取时,
				fos.write(i);	//先从第一个流开始读, 读完读第二个, 直到所有的都读完返回-1
			sis.close();
			fos.close();
		}
	}	


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
java中的IO操作总结(四) 前面已经把java io的主要操作讲了 这一节我们来说说关于java io的其他内容 Serializable序列化 实例1:对象的序列化 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.Serializable; @SuppressWarnings("serial") //一个类要想实现序列化则必须实现Serializable接口 class Person implements Serializable { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String toString() { return "Name:" + this.name + ", Age:" + this.age; } } public class Demo { public static void main(String[] args) { String path = File.separator + "home" + File.separator + "siu" + File.separator + "work" + File.separator + "demo.txt"; Person p1 = new Person("zhangsan",12); Person p2 = new Person("lisi",14); //此处创建文件写入流的引用是要给ObjectOutputStream的构造函数玩儿 FileOutputStream fos = null; ObjectOutputStream oos = null; try { fos = new FileOutputStream(path); oos = new ObjectOutputStream(fos); //这里可以写入对象,也可以写入其他类型数据 oos.writeObject(p1); oos.writeObject(p2); } catch (IOException e) { e.printStackTrace(); } finally { try { oos.close(); } catch (IOException e) { e.printStackTrace(); } } } } 解压密码 www.jiangyea.com
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值