黑马程序员---IO流

        ------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------


一,A.字节流:
  1.输出流:OutputStream(抽象类)
  |--FileOutputStream(类)
  2.输入流:InputStream(抽象类)
  B.字符流:
  1.输出流:Writer(抽象的)
  2.输入流:Reader(抽象的)
二,FileOutputStream的构造方法:
  构造方法;
  FileOutputStream(String name):使用一个文件名构造一个输出流
  FileOutputStream(File file):使用一个File构造一个输出流:
三,使用FileOutputStream向文件写入数据: 
  成员方法:
  public void write(int b):写入一个int
  public void write(byte[] b):写入一个byte数组(重点掌握)(使用String类的getBytes()获取byte[]数组)
  public void write(byte[] b,int off,int len):写入一个byte数组中从off开始,len个长度(重点掌握) 
  public void close():关闭流:
四, 换行符和追加写入: 
  1.换行符:Windows:\r\n
   Linux : \r
   Mac : \n
  
  2.追加写入:使用FileOutputStream的其它构造方法:
  public FileOutputStream(String name, boolean append):append如果为true,则追加写入
  public FileOutputStream(File file, boolean append):
五,输入流:InputStream(抽象类):
  子类:
  FileInputStream(类):
  构造方法:文件必须存在,如果不存在,则抛出异常:java.io.FileNotFoundException
  FileInputStream(File file)
  FileInputStream(String name) 
  读取方法:
  public int read():一次读取一个字节
  public int read(byte[] b):一次读取一个字节数组填充到参数数组b中(例子放在后面:见标题)
  复制文本代码:
  将项目目录下的output2.txt复制到项目目录的output2_copy.txt 
  步骤:
  1.从output2.txt中读取数据:FileInputStream
  2.一次读取一个字节
  3.向output2_copy.txt中写入数据:FileOutputStream

   一次输出一个字节;

public class Demo {
	public static void main(String[] args) {
		//1.实例化输入输出流
		try{
			FileInputStream in = new FileInputStream("output2.txt");
			FileOutputStream out = new FileOutputStream("outptu2_copy.txt");
			//一次读取一个字节:
			int n = 0;
			while((n = in.read()) != -1){
				out.write(n);
			}
			//释放资源
			in.close();
			out.close();
			System.out.println("复制完毕!");
		}catch(Exception e){
			
		}
		
	}
}
六,FileInputStream读取数据一次一个字节数组:
  int read():返回值就是读取的字节
  int read(byte[] byteArray):一次读取一个字节数组
七,带缓冲的字节流:
  1.之前我们看到,使用byte[]数组,可以大大的提高"复制文件的速度",就是由于数组作为一个"缓冲区"使用,一次读取的数据
    可以一次填充到一个byte[]数组中,然后一次写入,这样可以大大提高效率;
  2.Java中给我另外提供了两个"带缓冲的输入流/输出流",它们可以利用内部的"缓冲区",大大的提高读写效率:
  
  3.带缓冲区的输出流:BufferedOutputStream:该类实现缓冲的输出流。
    带缓冲区的输入流:BufferedInputStream:该类实现缓冲的输入流:
    
  4.输出流的构造方法:
  BufferedOutputStream:都是带一个字节输出流:只要是OutputStream的子类都可以,我们学过:FileOutputStream;
                         BufferedOutputStream只提供了"缓冲区",内部写入,仍然使用参数传递的FileOutputStream对象实现:
  |--BufferedOutputStream(OutputStream out) :创建一个新的缓冲输出流,以将数据写入指定的底层输出流。 
  |--BufferedOutputStream(OutputStream out, int size) 创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输出流。 
    --输出流的写入的方法:它没有特有的写入方法,使用父类的即可
八,带缓冲的输入流:BufferedInputStream: 
  构造方法:参数使用:FileInputStream
  BufferedInputStream(InputStream in) : 创建一个 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。 
  BufferedInputStream(InputStream in, int size) : 创建具有指定缓冲区大小的 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。 
  
  没有特有的"读取"的方法,使用父类的:
  int read():读取一个字节
  int read(byte[] byteArray):读取一个字节数组
九,转换流:
输出流:OutputStreamWriter:
    转换流-->输出流:OutputStreamWriter:
  
  构造方法:
  public OutputStreamWriter(OutputStream out):使用一个字节输出流构造一个转换流
  public OutputStreamWriter(OutputStream out,String charsetName):使用一个字节输出流,和编码方式,构造一个转换流: 
  写入的方法:
  public void write(int c):写入一个字节;(不常用)
  public void write(char[] cbuf):写入一个字符数组
  public void write(char[] cbuf,int off,int len):写入一个字符数组的一部分
  public void write(String str):直接写入一个字符串(最常用,也最方便)
  public void write(String str,int off,int len):写入字符串的一部分:
输入流:InputStreamReader:
  构造方法:
  public InputStreamReader(InputStream in):使用一个字节输入流构造
  public InputStreamReader(InputStream in,String charsetName):使用一个字节输入流,和一个编码方式构造; 
  成员方法:
  public int read():读取单个字符
  public int read(char[] cbuf):读取到一个字符数组cbuf,返回读取的字符的数量;
  复制单级文件夹代码
  需求:将D:\\aaa目录,复制到E:\\ 
  思路:
  1.封装源目录的File对象;
  2.封装目标目录的File对象;
  3.判断目标目录是否存在这个要复制的目录,如果没有,则创建;
  4.将源目录中的所有文件获取出来:File[] listFile();
  5.遍历文件数组:针对每一个文件,定义"输入流"和"输出流":统一使用带缓冲的字节流;

public class Demo {
	public static void main(String[] args) throws IOException{
		//1.封装源目录
		File srcFile = new File("D:\\aaa");
		//2.封装目标目录:
		File destFile = new File("E:\\");
		
		//调用方法:
		copyFile(srcFile,destFile);
		
		System.out.println("复制完毕!");
	}

	private static void copyFile(File srcFile, File destFile) throws IOException{
		File newFile = new File(destFile,srcFile.getName());//E:\\aaa(new File("E:\\","aaa"))
		//判断目录是否存在
		if(!newFile.exists()){
			newFile.mkdir();//创建目录
		}
		//获取源目录下的所有文件
		File[] fileArray = srcFile.listFiles();
		for(File f : fileArray){
			//针对每个文件定义输入流和输出流
			BufferedInputStream in = new BufferedInputStream(new FileInputStream(f));
			BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(new File(newFile,f.getName())));
			//一次读写一个字节数组
			byte[] byteArray = new byte[1024];
			int n = 0;
			while((n = in.read(byteArray)) != -1){
				out.write(byteArray,0,n);
			}
			//释放资源
			in.close();
			out.close();
			
			System.out.println("文件:" + f.getAbsolutePath() + " 复制完毕!");
		}
		
	}
}
十,数据输入流和数据输出流
    操作基本数据类型
  DataInputStream
  构造方法:
  DataInputStream(InputStream in) 使用指定的底层 InputStream 创建一个 DataInputStream
  DataOutputStream
  构造方法:
  DataOutputStream(OutputStream out)  创建一个新的数据输出流,将数据写入指定基础输出流
十一,打印流: 
  1.字节打印流:PrintStream:
  2.字符打印流:PrintWriter: 
  打印流的特点:
  1.只能操作目的地,不能操作数据(只能写入,没有读取);
  2.可以操作任何类型的数据:基本数据类型,引用类型;
  3.如果启动了自动刷新,内部的部分方法会带自动刷新;
  4.它可以对文件进行操作:
  Writer:
  |--PrintWriter: 
  构造方法:
  PrintWriter(OutputStream out) :根据现有的 OutputStream 创建不带自动行刷新的新 PrintWriter。 
  PrintWriter(OutputStream out, boolean autoFlush) 通过现有的 OutputStream 创建新的 PrintWriter。 
  参数:autoFlush:true:自动刷新;
  PrintWriter(Writer out) 创建不带自动行刷新的新 PrintWriter。 
  PrintWriter(Writer out, boolean autoFlush) 创建新 PrintWriter。 
  
  注意:如果启用了自动刷新,则只有在调用 println、printf 或 format 的其中一个方法时才可能完成此操作
  标准的输入输出流:
  1.System.in:输入流:返回:InputStream类型:InputStream的子类对象的引用
  2.System.out:输出流:返回:PrintStream类型(类):是OutputStream的子类
  从控制台接收数据的三种方式:
  1.Scanner类;
  2.main()方法的形参;
  3.System.in:
  1).返回的InputStream(抽象类)类型;
  2).返回的具体类型:BufferedInputStream:
十二,随机访问流 RandomAccessFile类:
  1.它是在io包,但不属于"流",它直接继承自Object;
  2.它内部包含了InputStream和OutputStream两种流,
    也就意味着,此类可以对文件进行"读取"和"写入";
  3.构造方法:
  RandomAccessFile(File file, String mode)  创建从中读取和向其中写入(可选)的随机访问文件流,该文件由 File 参数指定。 
  RandomAccessFile(String name, String mode):创建从中读取和向其中写入(可选)的随机访问文件流,该文件具有指定名称。 
  参数mode:
  含意
"r" 以只读方式打开。调用结果对象的任何 write 方法都将导致抛出 IOException。  
"rw" 打开以便读取和写入。如果该文件尚不存在,则尝试创建该文件。
十三,序列化流概述:
  1.序列化:之前我们可以向文件中写入一些数据,可以指定编码;序列化:是可以将一个内存中的"对象"写入到一个文件中,包括这个对象中的所有属性的值。
         也可以将一个对象,通过网络传输到另一台机器上。这个过程就叫:序列化;
    反序列化:当将一个对象"序列化"后,我们可以将其"反序列化",将对象的信息读入到程序;例如:从一个文件中读取一个"对象的信息";从网络接收到一个
         对象的信息。
  2.序列化和反序列化使用的类:
  1.输出流:ObjectOutputStream:序列化;
  构造方法:
  public ObjectOutputStream(OutputStream out):
  成员方法:
  public final void writeObject(Object obj):
                                 注意:需要被序列化的类,必须实现Serializable接口。这个接口是一个"标识性"的接口,没有抽象方法。
                                            实现此接口的类,表示可以被序列化。
  2.输入流:ObjectInputStream:反序列化;
  构造方法:
  ObjectInputStream(InputStream in) 创建从指定 InputStream 读取的 ObjectInputStream。
  成员方法:
  public final Object readObject():
  
  3.注意:每个被序列化的类,都隐式的有一个属性:serialVersionUID,而且有一个默认值。
       如果我们不显示定义这个属性,java会自动添加一个这个属性:
       这时,如果我们将此类的对象序列化后,如果更改了类结构,这个属性的值也会随之改变,那么就与已经序列化的对象
       的这个属性值不匹配了。当我们反序列化时,Java会验证这个属性值,如果不匹配,则抛出:InvalidClassException异常;
    建议:在需要序列化的类中显示的定义serialVersionUID属性,并赋予一个值。如果这个值不发生变化,反序列化就不会有问题。
    使用transient关键字声明不需要序列化的成员变量
十四,Properties类:
  1.它不是IO流类;
  2.它是Map的子类,直接继承自Hashtable;
  3.它内部结合输入、输出流,可以对"配置文件"进行读写;
  
  什么是配置文件:
  1.一般软件运行时都会记录一些用户的"设置信息"、"操作信息"等一些信息,记录的目的是为了下次再启动软件时,
    可以根据用户上次的设置或使用情况,来显示软件;
  2.例如:QQ的登录窗体:会记录我们以往登录的所有QQ号,可以通过下拉列表快速选择;
        暴风影音:播放列表:
        上述的一些内容都可以记录到"配置文件"中;
  3.配置文件就是一个"文本文件";
  4.它内部一般以"键值对"的形式存储。
  例如:游戏账户:
  疲劳值=1200
  金币=500
  经验=5000
  敏捷=20
  5.上面这种键值对形式的配置文件内容,就可以使用Properties类进行方便的读写;
  Properties类的使用:
  Map的方法:
  put(Object key ,Object value):存储元素
  keySet():获取键的集合
  get(Object key):通过键获取值
  特有方法:
  public Object setProperty(String key,String value):存储元素:相当于put()方法
  public String getProperty(String key):获取元素。相当于get()方法
  public Set<String> stringPropertyNames():获取所有键名。相当于keySet()方法
 Properties和IO流的结合使用
 public void load(Reader reader):从配置文件中读取;
 public void store(Writer writer,String comments):向配置文件中写入


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值