1、File读写操作
- 1.1 FileInputStrean和FileOutputStream的基本使用
/***********************************************************************
需求:使用FileOutputStream进行写入数据"zi fu ce shi shu ju"。
使用FileInputStream进行读取数据打印到控制台。
************************************************************************/
import java.io.*;
class FileStreamDemo1
{
public static void main(String[] args)throws IOException
{
// OutputStreamDemo1();
InputStreamDemo2();
}
public static void OutputStreamDemo1()throws IOException
{
FileOutputStream fos=new FileOutputStream("demo.txt");
fos.write("zi fu ce shi shu ju".getBytes());
fos.close();
}
//读取方式一:
public static void InputStreamDemo1()throws IOException
{
FileInputStream fis=new FileInputStream("demo.txt");
int ch=0;
while ((ch=fis.read())!=-1)
{
System.out.println((char)ch);
}
fis.close();
}
//读取方式二:
public static void InputStreamDemo2() throws IOException
{
FileInputStream fis=new FileInputStream("demo.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();
}
}
注意:available()方法定义的是刚刚好的缓冲区,但是使用的时候要注意,如果数据过大,内存会被卡死。
- 1.2 事例:拷贝图片、MP3
(1)
/************************************************************************
需求:拷贝图片
思路:(1)使用字节流读取对象"1.bmp"并建立关联
(2)用字节写入流对象创建一个图片文件,用于存储获取到图片数据
(3)通过循环读写完成数据的存储
(4)关闭资源
************************************************************************/
import java.io.*;
class FileStreamDemo2
{
public static void main(String[] args)
{
FileOutputStream fos=null;
FileInputStream fis=null;
try
{
fis=new FileInputStream("1.bmp");
fos=new FileOutputStream("2.bmp");
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("读取关闭失败");
}
}
}
}
(2)
/******************************************************************
需求:使用FileInputStream FileOutputStream实现MP3的复制。并使用缓冲区提高效率。
思路:(1)使用字节流读取对象"1.MP3"并建立关联
(2)用字节写入流对象创建一个MP3文件,用于存储获取到MP3数据
(3)完成数据的存储
(4)关闭资源
*******************************************************************/
import java.io.*;
class BufferedStreamDemo3
{
public static void main(String[] args)throws IOException
{
long start=System.currentTimeMillis();
BufferedInputStream bufis=new BufferedInputStream(new FileInputStream("1.mp3"));
BufferedOutputStream bufos=new BufferedOutputStream(new FileOutputStream("2.mp3"));
int by=0;
while ((by=bufis.read())!=-1)
{
bufos.write(by);
}
bufis.close();
bufos.close();
long end=System.currentTimeMillis();
System.out.println(end-start+"毫秒");
}
}
- 1.3 自定义字节流缓冲区
/*******************************************************************
自定义一个读取缓冲区类,模拟一BufferedInputStream BufferedOutoutStream
分析:将MP3文件抓取到字符数组中,然后从字符数组中读取数据,所以需要定义指针POS来操作数组的角标。定义计数器来操作数组中取出的元素个数。
缓冲的原理:其实就是从源中获取一批数据到缓冲区中,再从缓冲区不断地取出一个
一个数据。在此次取完后,再从源中继续取一批数据进缓冲区,当源中的数据取完时,
用-1作为结束标记.
********************************************************************/
import java.io.*;
class MyBufferedStreamDemo4
{
public static void main(String[] args) throws IOException
{
long start=System.currentTimeMillis();
MyBufferedInputStream bufis=new MyBufferedInputStream(new FileInputStream("1.mp3"));
BufferedOutputStream bufos=new BufferedOutputStream(new FileOutputStream("2.mp3"));
int by=0;
while ((by=bufis.myRead())!=-1)
{
bufos.write(by);
}
bufis.myClose();
bufos.close();
long end=System.currentTimeMillis();
System.out.println(end-start+"毫秒");
}
}
class MyBufferedInputStream
{
private InputStream in;
MyBufferedInputStream(InputStream in)
{
this.in=in;
}
private byte[]buf=new byte[1024];
private int pos=0,count=0;
public int myRead() throws IOException
{
if (count==0)
{
count=in.read(buf);//通过in对象读取硬盘上的数据,并存储到buf中
if (count<0)
return -1;
pos=0;
byte b=buf[pos];
count--;
pos++;
return b;
}
else if(count>0)
{
byte b=buf[pos];
count--;
pos++;
return b;
}
return -1;
}
public void myClose()throws IOException
{
in.close();
}
}
2、键盘的读写
- 2.1 InputStream和PrintStream类
public static final InputStream in
“标准”输入流。此流已打开并准备提供输入数据。通常,此流对应于键盘输入或者由主机环境或用户指定的另一个输入源。
public static final PrintStream out
“标准”输出流。此流已打开并准备接受输出数据。通常,此流对应于显示器输出或者由主机环境或用户指定的另一个输出目标。
对于简单独立的 Java 应用程序,编写一行输出数据的典型方式是:System.out.println(data)
//方法一:阻塞式的读取字符的方法,读取两个字符。
import java.io.*;
class SystemDemo5
{
public static void main(String[] args)throws IOException
{
InputStream in=System.in;
int by=in.read();
int by1=in.read();
System.out.println(by);
System.out.println(by1);
}
}
//方法二:循环读取键盘录入的数据
import java.io.*;
class SystemDemo5
{
public static void main(String[] args)throws IOException
{
InputStream in=System.in;
int ch=0;
while ((ch=in.read())!=-1)
{
System.out.println((char)ch);
}
}
}
//方法三:StringBuffer存储
import java.io.*;
class SystemDemo5
{
public static void main(String[] args)throws IOException
{
InputStream in=System.in;
StringBuffer sb=new StringBuffer();
while(true)
{
int ch=in.read();
if (ch=='\r')
continue;
else 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);
}
}
}
- 2.2 InputStreamReader和BufferReader
BufferedReader类中的方法:
public String readLine() throws IOException
读取一个文本行。通过下列字符之一即可认为某行已终止:换行 (‘\n’)、回车 (‘\r’) 或回车后直接跟着换行。
返回:包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null
//方法四:通过BufferedReader中的readLine()方法完成键盘读写,
import java.io.*;
class SystemDemo5
{
public static void main(String[] args)throws IOException
{
InputStream in=System.in;
InputStreamReader isr=new InputStreamReader(in);
BufferedReader bufr=new BufferedReader(isr);
String line=null;
while ((line=bufr.readLine())!=null)
{
System.out.println(line.toUpperCase());
if ("over".equals(line))
break;
}
bufr.close();
}
}
使用字节流读取一个中文字符需要读取两次,因为一个中文字符由两个字节组成,而使用字符流只需要读取一次
System.out的类型是PrintStream,属于OutputStream类型
OutputStreamReader是字符流桐乡字节流的桥梁
- 2.3 BufferedWriter 和OutputStreamWriter
//方法五:Writer中有OutputStreamWriter字节流通向字符流的桥梁
import java.io.*;
class SystemDemo5
{
public static void main(String[] args)throws IOException
{
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out));
//System.out,这个也是输出,输出语句对象变成字符流对象
String line=null;
while ((line=bufr.readLine())!=null)
{
if ("over".equals(line))
break;
bufw.write(line.toUpperCase());
bufw.newLine();
bufw.flush();
}
bufr.close();
}
}
3 、System类中一些方法
- 3.1 setIn和setOut方法
System类中的:
public static void setIn(InputStream in)
重新分配“标准”输入流。
public static void setOut(PrintStream out)
重新分配“标准”输出流。
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out));
例如上市的前面加上:System.setOut(new PrintStrean(“1.txt”));
输入的字符就不会打印到控制台,而是到文本中去了
- 3.2 printStackTrace()方法
System类中:
public void printStackTrace(PrintStream s)
将此 throwable 及其追踪输出到指定的输出流。
(1)需求:将错误信息打印到文本文档中
import java.io.*;
class LogDemo6
{
public static void main(String[] args) throws IOException
{
try
{
int[]arr=new int[2];
System.out.println(arr[3]);//角标越界异常
}
catch (Exception e)
{
// e.printStackTrace();
// e.printStackTrace(System.out);
e.printStackTrace(new PrintStream("demo2.txt"));
}
}
(2)扩展:将时间加到错误信息上
import java.io.*;
import java.text.*;
class LogDemo6
{
public static void main(String[]args)
{
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("demo3.log");
ps.println(d.toString());
System.setOut(ps);
}
catch (IOException e1)
{
throw new RuntimeException("日志文件创建失败");
}
e.printStackTrace(System.out);
}
}
}
- 3.3 打印系统信息
Properties类中的方法:
public String getProperty(String key)
用指定的键在此属性列表中搜索属性。如果在此属性列表中未找到该键,则接着递归检查默认属性列表及其默认值。如果未找到属性,则此方法返回 null。
System类中方法:
public void list(PrintStream out)
将属性列表输出到指定的输出流。此方法对调试很有用。
import java.util.*;
import java.io.*;
class SystemDemo7
{
public static void main(String[] args) throws IOException
{
Properties prop=System.getProperties();
prop.list(new PrintStream("demo5.txt"));
}
}
4、总结
- 4.1 字符流和字节流的关系
- 4.2 流的操作规律
明确源和目的:
源:InputStreamReader
目的:OutputStreamWriter
明确数据是否为纯文本数据:
源:是纯文本:Reader
不是InputStream
目的:是纯文本:Writer
不是:OutputStream
明确具体的设备:
硬盘File
键盘:System.in
控制台:System.out
网络:Socket流
内存:数组
举例说明:
(1)复制一个文本文件
1、明确源和目的
源:InputSreamReader
目的:OutputStreamWriter
2、是否是纯文本
是
源:Reader
目的:Writer
3
明确具体设备
硬盘:File
FileReader fr=new FileReader(“a.txt”);
FileWriter fw=new FileWriter("b.txt");
(2)读取键盘录入信息,并写入到一个文件中
1、明确源和目的
源:InputStreamReader
目的:OutputStreamWriter
2、是否是纯文本?
是
源:Reader
目的:Writer
3、明确设备
源:键盘System.in
目的:File
FileReader fr=System.in;
FileWriter fw=new FileWriter(“a.txt”);
4、需要额外功能吗?
需要,转换,将字节流转换为字符流,因为明确的源是Reader,这样操作文本数据更快捷
InputStreamReader isr=new InputStreamReader(System.in);
FileWriter fw=new FileWriter(“a.txt”);
(3)将一个文本数据显示到控制台上
1、明确源和目的
源:InputStreamReader
目的:OutputStreamWriter
2、是否为纯文本?
是!
源:Reader
目的:Writer
3、明确具体设备
源:硬盘File
目的:键盘:System.out
FileReader fr=new FileReader(“a.txt”);
FileWriter fw=System.out;
4、需要额外功能吗?
需要,转换。
FileReader fr=new FileReader(“a.txt”);
OutputStreamWriter osw=new OutputStreamWriter(System.out);
提高效率:
BufferedReader bufr=new BufferedReader(new FileReader(“a.txt”));
BufferedWriter bufw=new BufferedWriter(new OutputStreamWriter(System.out));