java学习之IO流1

IO流用来处理设备之间的数据传输
           流按操作数据分为两种:字节流与字符流
           流按流向分为:输入流和输出流
           
输入流和输出流相对于内存设备而言:
            将外设中的数据读取到内存中:输入
            将内存的数据写入到外设中:输出

字符流的由来:
其实就是字节流读取文字字节数据后,不直接操作而是先查指定的编码表,获取对应的文字,
再对这个文字进行操作。简单说:字节流+编码表

字符流的两个顶层父类:
             1.InputStream    2.OutputStream
字符流的两个顶层父类:
             1.Reader    2.Writer

这些体系的子类都以父类名作为后缀,而且子类名的前缀就是该对象的功能

如果要操作文字数据,优先考虑字符流,而且要将数据从内存写到硬盘上,要使用字符流中的输出流。(Writer)


字符流:

FileWriter:

示例1:

下图中第3行创建一个可以往文件中写入字符数据的字符输出流对象,既然是往一个文件中写入文件数据,那么再创建对象时,就必须明确该文件(用于存储数据的目的地),所以构造函数中指定的形参为写入的文件地址和文件名。没有指定地址则默认为当前目录。如果指定的文件不存在,则会自动创建,如果文件存在,则会被覆盖(覆盖的意思是原文件中的数据会被清空,被一个新建立的文件替换)。第4行用write方法把字符串"abc"写入文件当中,此时查看文件,会发现文件中并没有写入的字符串"abc",是因为此时的字符串是先存储在临时缓冲区中,所以必须调用flush方法刷新缓冲区,把数据立即写入预期目标。如果调用close方法,则会先刷新缓冲区,即调用flush()方法,然后再关闭流,在关闭该流之后,再调用 write() 或 flush() 将导致抛出 IOException

        public static void demo1() throws IOException 
	{
		FileWriter fw = new FileWriter("demo.txt");
		fw.write("abc");
//		fw.flush();
		fw.close();
	}

示例2:

如果在写入数据的时候需要换行,在windows系统下的换行符号是“\r\t”。也可以如下图第1行,声明一个常量,用System类中的getProperty("line.separator")方法获取当前系统的换行符,这样就不需要在意当前的操作系统了。如果要在一个已有数据的文件中追加数据,需要在构造函数中加入true表示对文件进行续写,如第7行,否则新写入的数据会覆盖原数据。

	private static final String LINE_SEPARATOR = System.getProperty("line.separator");
	public static void demo2() throws IOException
	{
		FileWriter fw = new FileWriter("demo2.txt");
		fw.write("abc" + LINE_SEPARATOR + "def");
		fw.close();
		FileWriter fw1 = new FileWriter("demo2.txt", true);
		fw1.write("haha");
		fw1.close();
	}

FileWriter IO异常处理

实例3:

下图中第6、7、18行都可能出现异常,所以用try-catch处理异常。无论有没有出现异常,都要执行第18行,所以把它放在了finally语句块中,为了能在finally中使用fw对象引用,就把fw定义在try语句块之外,如第3行。如果第6行建立对象时出现了异常,那么fw就不能参考至对象,就会出现空指针异常java.lang.NullPointerException,所以必须加入判断fw是否为空,如第15行所示。

	public static void demo3() 
	{
		FileWriter fw = null;
		try 
		{
			fw = new FileWriter("k:\\demo2.txt");
			fw.write("abcdef");
		} 
		catch (IOException e) 
		{
			System.out.println(e.toString());
		}
		finally
		{
			if(fw != null)
				try
				{
					fw.close();
				}
				catch(IOException e)
				{
					throw new RuntimeException("关闭失败");
				}
		}
	}

FileReader:

示例1:

下图中第3行创建读取字符数据的流对象,在构造函数中明确了要读取的文件,即用一个读取流关联一个已存在的文件。第4行用read()方法读取一个字符,返回的是一个整数。第5行中打印出来的值为97,字符a对应的ASCII码,第6行把97转换成char类型的,打印出来为a。如果读取已经达到流的末尾,就返回-1。

	public static void demo1() throws IOException 
	{
		FileReader fr = new FileReader("demo.txt");
		int ch = fr.read();
		System.out.println(ch);//97
		System.out.println((char)ch);//a
		fr.close();
	}

示例2:

下图中使用的是read()方法读取多个字符,存储在一个字符数组中。第5行返回的是实际读取到的个数,并把读到的字符存储在buf数组中。如果文件中字符的长度大于数组长度时,那么一次最多只能读到的个数等于数组的长度。如果读到流的末尾没有数据了,会返回-1。所以可以用循环的方式来读取,如第9-11行。第11行是把char类型的数组buf转换成String类型,从0号下标开始,转换的个数为len。

	public static void demo2() throws IOException
	{
		FileReader fr = new FileReader("demo.txt");
		char[] buf = new char[5];
//		int num = fr.read(buf);
//		System.out.println("读到的个数 = " + num);//读到的个数 = 5
//		System.out.println(new String(buf));//abcde
		int len = 0;
		while((len = fr.read(buf)) != -1)
		{
			System.out.println(new String(buf, 0, len));
			/*输出 abcde
			     f*/
		}
	}

为了提高写入的效率,可以使用字符流的缓冲区

如下图中,第4行创建一个字符流的缓冲区对象,并和指定要被缓冲的流对象相关联的。第5行使用缓冲区的写入方法将数据先写入到缓冲区中。第6行使用缓冲区的方法,写入一个换行分隔符。第8行使用缓冲区的刷新方法将数据刷到目的地中。第9行关闭缓冲区,其实就是关闭流,即调用fw.close();

	public static void demo1() throws IOException 
	{
		FileWriter fw = new FileWriter("demo.txt");
		BufferedWriter bufw = new BufferedWriter(fw);
		bufw.write("abcdefg");
		bufw.newLine();
		bufw.write("hijk");
		bufw.flush();
		bufw.close();
	}

如下图中,第4行创建了一个读字符流的缓冲区对象,并和指定要被缓冲的流对象关联。第5行使用缓冲区对象的readLine()方法每次读取一行(行是以回车换行符来区分的),并返回字符串。当数据都读完是,会返回null。

	public static void demo1() throws IOException 
	{
		FileReader fr = new FileReader("demo.txt");
		BufferedReader bufr = new BufferedReader(fr);
		String line1 = bufr.readLine();
		System.out.println(line1);//abcdefg
		String line2 = bufr.readLine();
		System.out.println(line2);//hijk
		String line3 = bufr.readLine();
		System.out.println(line3);//null
		fr.close();
	}


字符流:

FileOutputStream:

下图中第6行把字符串“abcdefg”转换成byte数组,因为字符流只能操作字节数组。使用write方法写数据后,不需要使用临时缓冲,会直接将数据写到目的地中,这是字节流的一个特点。

	public static void demo_write() throws IOException
	{
		//创建字节输出流对象,用于操作文件
		FileOutputStream fos = new FileOutputStream("bytedemo.txt");
		//写数据,直接写入到了目的地中
		fos.write("abcdefg".getBytes());
		fos.close();//关闭资源
		
	}

下图中第3行创建了字节输入流对象,构造函数中关联了要操作的文件。第四行创建了一个字节数组,长度为fis.available(),该方法是获得当前操作文件的大小,对于小文件可以这样使用,对于大文件不能这样使用,不然会导致内存空间不足。第7行把字节数组转换成为字符串输出。

	public static void demo_read() throws IOException 
	{
		FileInputStream fis = new FileInputStream("demo.txt");
		byte[] buf = new byte[fis.available()];
		System.out.println(fis.available());
		fis.read(buf);
		System.out.println(new String(buf));
		fis.close();
	}

字节流复制MP3文件的四种方法:

方法一:

使用字节输出流和字节输入流,建立一个长度为1024的字节数组来存放数据。使用while循环进行读写。

	public static void copy_1() throws IOException
	{
		FileInputStream fis = new FileInputStream("D:\\酷狗音乐\\KuGou\\在他乡.mp3");
		FileOutputStream fos = new FileOutputStream("D:\\1.mp3");
		byte[] buf = new byte[1024];
		int len = 0;
		while((len = fis.read(buf)) != -1)
		{
			fos.write(buf, 0, len);
		}
		fos.close();
		fis.close();
	}
方法二:

使用缓冲区来进行数据的读写,加快了速度。

	public static void copy_2() throws IOException
	{
		FileInputStream fis = new FileInputStream("D:\\酷狗音乐\\KuGou\\在他乡.mp3");
		BufferedInputStream bufis = new BufferedInputStream(fis);
		FileOutputStream fos = new FileOutputStream("D:\\2.mp3");
		BufferedOutputStream bufos = new BufferedOutputStream(fos);
		int ch = 0;
		while((ch = bufis.read()) != -1)
		{
			bufos.write(ch);
		}
		bufos.close();
		bufis.close();
	}
方法三:

直接使用available()方法获取文件的大小,建立一个长度刚刚好的字节数组,进行一次性读,一次性写。

	public static void copy_3() throws IOException 
	{
		FileInputStream fis = new FileInputStream("D:\\酷狗音乐\\KuGou\\在他乡.mp3");
		FileOutputStream fos = new FileOutputStream("D:\\3.mp3");
		byte[] buf = new byte[fis.available()];
		fis.read(buf);
		fos.write(buf);
		fos.close();
		fis.close();
	}
方法四:

使用字节输入流,字节输出流,读取一个字节,写入一个字节,这样的操作很慢,效率低。

	public static void copy_4() throws IOException
	{
		FileInputStream fis = new FileInputStream("D:\\酷狗音乐\\KuGou\\在他乡.mp3");
		FileOutputStream fos = new FileOutputStream("D:\\4.mp3");
		int ch = 0;
		while((ch = fis.read()) != -1)
		{
			fos.write(ch);
		}
		fos.close();
		fis.close();
	}












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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值