IO_03_字节流

原创 2016年08月21日 09:52:35
字符流底层也是用的字节流的缓冲区


两者的区别就是:字节流可以既可以操作文本文件,也可以操作非文本文件,如一些二进制数据(图片,视频,对象),
而字符流只能操作文本。这也是两者的适用情况,如何决定该使用哪种数据流读写取决于要读写的数据类型,若是文本本件,
当然选择字符流,因为我们都知道字符流每次处理的单元为2个字节的Unicode字符,而字节流每次处理的是一个,若是非文本文件,
那么就只能用字节流了,这个时候就不能单纯的看谁的效率高了


对于我们常用的GBK中,英文是占用1个字节,中文是2个 
对于UTF-8,英文是1个,中文是3个 

对于Unicode,英文中文都是2个

字节流读取文件和写入文件

class  FileStream
{
	public static void main(String[] args) throws IOException
	{
		readFile_3();
		readFile_2();
		readFile_1();
		readFile_1();
	}
	/**
	 * 定义刚刚好的缓冲区,不用再循环(用于知道文件的大小,慎用,只是用于文件小的)
	 * @throws IOException
	 */
	public static void readFile_3()throws IOException
	{
		FileInputStream fis = new FileInputStream("src\\com\\fileStream\\ref\\fos.txt");
		
//		int num = fis.available();
		byte[] buf = new byte[fis.available()];//定义一个刚刚好的缓冲区。不用在循环了。

		fis.read(buf);

		System.out.println(new String(buf));

		fis.close();
	}

	/**
	 * 定义一个1024的字节数据读取
	 * @throws IOException
	 */
	public static void readFile_2()throws IOException
	{
		FileInputStream fis = new FileInputStream("src\\com\\fileStream\\ref\\fos.txt");

		byte[] buf = new byte[1024];
		int len = 0;
		while((len=fis.read(buf))!=-1)
		{
			System.out.println(new String(buf,0,len));
		}

		fis.close();
		
	}


	/**
	 * 字节流读文件,一个一个读
	 * @throws IOException
	 */
	public static void readFile_1()throws IOException
	{
		FileInputStream fis = new FileInputStream("src\\com\\fileStream\\ref\\fos.txt");

		int ch = 0;

		while((ch=fis.read())!=-1)
		{
			System.out.println((char)ch);
		}

		fis.close();
	}
	/**
	 * 字节流写文件
	 * @throws IOException
	 */
	public static void writeFile()throws IOException
	{
		FileOutputStream fos = new FileOutputStream("src\\com\\fileStream\\ref\\fos.txt");
		

		fos.write("abcde".getBytes());

		fos.close();
		
	}
}
复制一个图片

思路:
1,用字节读取流对象和图片关联。
2,用字节写入流对象创建一个图片文件。用于存储获取到的图片数据。
3,通过循环读写,完成数据的存储。
4,关闭资源。

class  CopyPic
{
	public static void main(String[] args) 
	{
		FileOutputStream fos = null;
		FileInputStream fis = null;
		try
		{
			fos = new FileOutputStream("src\\com\\fileStream\\ref\\copy\\devOps.png");
			fis = new FileInputStream("src\\com\\fileStream\\ref\\devOps.png");
			/**定义一个1024的字节数据来缓冲*/
			byte[] buf = new byte[1024];

			int len = 0;

			while((len=fis.read(buf))!=-1)
			{
				fos.write(buf,0,len);
			}
		}
		catch (IOException e)
		{
			throw new RuntimeException("复制文件失败");
		}
		finally
		{
			try
			{
				if(fis!=null)
					fis.close();
			}
			catch (IOException e)
			{
				throw new RuntimeException("读取关闭失败");
			}
			try
			{
				if(fos!=null)
					fos.close();
			}
			catch (IOException e)
			{
				throw new RuntimeException("写入关闭失败");
			}
		}
	}
}

自定义缓冲区

class MyBufferedInputStream
{
	private InputStream in;

	private byte[] buf = new byte[1024*4];
		
	private int pos = 0,count = 0;
	
	MyBufferedInputStream(InputStream in)
	{
		this.in = in;
	}

	//一次读一个字节,从缓冲区(字节数组)获取。
	public int myRead()throws IOException
	{
		//通过in对象读取硬盘上数据,并存储buf中。
		if(count==0)
		{
			count = in.read(buf);
			if(count<0)
				return -1;
			pos = 0;
			byte b = buf[pos];

			count--;
			pos++;
			return b&255;
		}
		else if(count>0)
		{
			byte b = buf[pos];

			count--;
			pos++;
			return b&0xff;
		}
		return -1;

	}
	public void myClose()throws IOException
	{
		in.close();
	}
}


/*
11111111-111111110000000000101001001010100101010010101001010


byte: -1  --->  int : -1;
00000000 00000000 00000000 11111111  255

11111111 11111111 11111111 11111111


11111111  -->提升了一个int类型 那不还是-1吗?是-1的原因是因为在8个1前面补的是1导致的。
那么我只要在前面补0,即可以保留原字节数据不变,又可以避免-1的出现。
怎么补0呢?

 11111111 11111111 11111111 11111111                        
&00000000 00000000 00000000 11111111 
------------------------------------
 00000000 00000000 00000000 11111111 

0000-0001
1111-1110
000000001
1111-1111  -1


结论:
字节流的读一个字节的read方法为什么返回值类型不是byte,而是int。
因为有可能会读到连续8个二进制1的情况,8个二进制1对应的十进制是-1.
那么就会数据还没有读完,就结束的情况。因为我们判断读取结束是通过结尾标记-1来确定的。
所以,为了避免这种情况将读到的字节进行int类型的提升。
并在保留原字节数据的情况前面了补了24个0,变成了int类型的数值。


而在写入数据时,只写该int类型数据的最低8位。


*/
复制Mp3

class  CopyMp3
{
	public static void main(String[] args) throws IOException
	{
		long start = System.currentTimeMillis();
		copy_2();
		long end = System.currentTimeMillis();

		System.out.println((end-start)+"毫秒");
		
		
		start = System.currentTimeMillis();
		copy_1();
		end = System.currentTimeMillis();

		System.out.println((end-start)+"毫秒");
	}

	public static void copy_2()throws IOException
	{
		/**
		 * 自定义缓冲
		 */
		MyBufferedInputStream bufis = new MyBufferedInputStream(new FileInputStream("src\\com\\fileStream\\ref\\cengjideni.mp3"));
		BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("src\\com\\fileStream\\ref\\copy\\cengjideni.mp3"));
		
		int by = 0;

		//System.out.println("第一个字节:"+bufis.myRead());

		while((by=bufis.myRead())!=-1)
		{
			bufos.write(by);
		}

		bufos.close();
		bufis.myClose();
	}

	//通过字节流的缓冲区完成复制。
	public static void copy_1()throws IOException
	{
		BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("src\\com\\fileStream\\ref\\cengjideni.mp3"));
		BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("src\\com\\fileStream\\ref\\copy\\cengjideni.mp3"));
		
		int by = 0;

		while((by=bufis.read())!=-1)
		{
			bufos.write(by);
		}

		bufos.close();
		bufis.close();

		
	}
}


读取键盘录入。
System.out:对应的是标准输出设备,控制台。
System.in:对应的标准输入设备:键盘。




需求:
通过键盘录入数据。
当录入一行数据后,就将该行数据进行打印。
如果录入的数据是over,那么停止录入。


class  ReadIn
{
	public static void main(String[] args) throws IOException
	{
		InputStream in = System.in;
		StringBuilder sb = new StringBuilder();

		while(true)
		{
			int ch = in.read();
			if(ch=='\r')
				continue;
			if(ch=='\n')
			{
				String s = sb.toString();
				if("over".equals(s))
					break;
				System.out.println(s.toUpperCase());
				sb.delete(0,sb.length());
			}
			else
				sb.append((char)ch);

		}
	}
}


将系统信息保存到文件

class  SystemInfo
{
	public static void main(String[] args) throws IOException
	{
		Properties prop = System.getProperties();

		//System.out.println(prop);
		prop.list(new PrintStream("src\\com\\fileStream\\ref\\sysinfo.txt"));
	}
}

将异常信息保存到文件

class  ExceptionInfo
{
	public static void main(String[] args)throws IOException 
	{
		try
		{
			int[] arr = new int[2];
			System.out.println(arr[3]);
		}
		catch (Exception e)
		{
			
			try
			{
				Date d = new Date();
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				String s = sdf.format(d);

				PrintStream ps = new PrintStream("src\\com\\fileStream\\ref\\exeception.log");
				ps.println(s);
				System.setOut(ps);

				
			}
			catch (IOException ex)
			{
				throw new RuntimeException("日志文件创建失败");
			}
			e.printStackTrace(System.out);
		}
	}
}



版权声明:本文为博主原创文章,未经博主允许不得转载。

IO-03字节流字符流

JAVA iO

io流详解,字符流和字节流代码

  • 2014年05月17日 19:38
  • 90KB
  • 下载

学习笔记之java.io包中的字节流(上)—— 基本的InputStream和OutputStream

先看下类的声明: 1 2 public abstract class InputStream implements Close...
  • hjding
  • hjding
  • 2017年02月11日 19:18
  • 447

Java IO _字节流与字符流

1.掌握流的概念 2.掌握字节流与字符流的作用 3.掌握文件的标准操作步骤 4.掌握字节与字符操作的区别 1、流的概念 程序中的输入输出都是以流的形式保存的,流中保存的实际上全都...

输入输出流(IO)—文件字节流(FileInputStream & FileOutputStream)的基本操作及运用

FileInputStream类是InputStream类的子类,称为文件字节输入流。按字节读取文件中的数据。 构造方法:FileInputStream(String name)           ...

IO_字节流_节点流_文件夹拷贝_工具制作_文件后缀与软件的关系JAVA149、163

一、S02E149_01IO_字节流、节点流、文件夹拷贝、工具制作、文件后缀与软件的关系 1.文件夹拷贝 a.递归查找子孙级文件或文件夹 b.文件则直接复制(IO流复制);文件夹则创建 c.举...

JAVA IO使用高速缓冲区的字节流复制文件

好记性不如赖笔头……带有高速缓冲区的字符流示例package com.Ckinghan.outputStream;import java.io.BufferedInputStream; import ...

Java基础---IO流三(字节流& 字符流)

2015-04-23 一、转换流(IO流续) 1、编码表概述      由字符及其对应的数值组成的一张表 编码 把看得懂的变成看不懂的 解码 把看不懂的变成看得懂的 常见的编码表      ASCII...

2017 - 10 -26 IO流 斐波那契数列 字节流 缓冲字节

1 递归求阶乘   public static int jieCheng(int n){        if(n == 1){              return 1;       }else{ ...
  • ouqia
  • ouqia
  • 2017年10月27日 20:57
  • 47
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:IO_03_字节流
举报原因:
原因补充:

(最多只允许输入30个字)