IO流用来处理设备之间的数据传输;Java对数据的操作是通过流的方式; Java用于操作流的对象都在IO包中;
示例:
FileWriter fw = new FileWriter(“java.text”); //创建一个FileWriter对象,该对象一初始化就必须要明确被操作的文件,该文件会被创建到指定目录下;如果该目录中已有同名文件将会被覆盖,该步就是在明确数据要存放的目的地; fw.write(“Hello World!!!”); //调用write方法,将字符串写入到流中; fw.flush(); //刷新流对象中的缓冲数据;将数据刷到目的地中; fw.close(); //关闭资源,但是在关闭之前会刷新一次内部中的缓冲数据;将数据刷到目的地。 //close和flush的区别:flush刷新后流可以继续使用;close刷新后流将会关闭;
|
- imp
ort java.io.*; - class IOExceptionDemo
- {
- public static void main(String[] args)
- {
- FileWriter fw = null;//首先将fw赋值为空,是因为创建FileWriter文件时
- //会抛出异常,需要捕捉;如果放在try中,finally中将访问不到fw;
- try
- {
- fw = new FileWriter("java.text");
- fw.write("Hello World!!!");
- }
- catch (IOException e )
- {
- System.out.println(e.toString());
- }
- finally
- {
- try
- {
- if(fw!=null)//如果上面的新创建对象抛出异常,fw将为空,执行到close时将会抛出空指针异常;所以确保不会抛出空指针异常需要做一个判断;
- fw.close();
- }
- catch (IOException e )
- {
- System.out.println(e.toString());
- }
- }
- }
- }
- imp
ort java.io.*; - class FileReaderDemo
- {
- public static void main(String[] args) throws IOException
- {
- FileReader fr = new FileReader("FileReaderDemo.java");
- char[] ch = new char[1024];//一般将该处的数组大小定义为1024的整数倍;
- int num = 0;
- while((num=fr.read(ch)) != -1)//当read返回的num等于-1时,表示已经读到文件末尾了;
- {
- System.out.print(new String(ch,0,num));//此处表示读多少就打印多少;
- }
- fr.close();
- }
- }
- imp
ort java.io.*; - class CopyTest
- {
- public static void main(String[] args) throws IOException
- {
- copy_1();
- }
- public static void copy_2()throws IOException
- {
- //创建需要Copy的目的地;
- FileWriter fw = new FileWriter("D:\\CopyDemo.txt");
- //创建需要copy的文件;
- FileReader fr = new FileReader("CopyTest.java");
- //使用read方法,每次读一个字符写一个字符;
- int len = 0;
- while((len=fr.read()) !=-1)
- {
- fw.write(len);
- }
- fw.close();
- fr.close();
- }
- //使用数组存储字符,让后让字符一次性输出;
- public static void copy_1()
- {
- FileWriter fw = null;
- FileReader fr = null;
- try
- {
- fw = new FileWriter("D:\\CopyDemo.txt");
- fr = new FileReader("CopyTest.java");
- int len = 0;
- char[] ch = new char[1024];
- while((len=fr.read(ch)) != -1)
- {
- fw.write(ch,0,len);
- }
- }
- catch (IOException e)
- {
- throw new RuntimeException("Read and write failure");
- }
- finally
- {
- try
- {
- if(fw != null)
- fw.close();
- }
- catch (IOException e)
- {
- throw new RuntimeException("Write close failure");
- }
- try
- {
- if(fr != null)
- fr.close();
- }
- catch (IOException e)
- {
- throw new RuntimeException("Read close failure");
- }
- }
- }
- imp
ort java.io.*; - class BufferedWriterDemo
- {
- public static void main(String[] args) throws IOException
- {
- FileWriter fw = new FileWriter("java.txt");//创建一个写入流对象和文件相关联;
- BufferedWriter buf = new BufferedWriter(fw);//将流对象作为参数传递到缓冲区的构造函数;
- buf.write("Hello java");
- buf.flush(); //需要刷新,缓冲区中的文件才能进去流对象中;
- buf.close();
- //fw.close();此时的fw不需要关闭,因为关闭了缓冲区,
- //也就是关闭了缓冲区中的流对象;
- }
- }
演示示例:
- imp
ort java.io.*; - class BufferedReaderDemo
- {
- public static void main(String[] args)throws IOException
- {
- FileReader fr = new FileReader("CopyTest.java");
- //创建一个缓冲区,将流对象作为参数传递给缓冲对象的构造函数;
- BufferedReader buf = new BufferedReader(fr);
- String line = null;
- while((line=buf.readLine()) != null)//readLine每次读一行,
- { //当读到文件末尾时返回null;
- System.out.println(line);
- }
- buf.close();
- }
- }
- imp
ort java.io.*; - class BufferedCopyDemo
- {
- public static void main(String[] args) throws IOException
- {
- BufferedReader bufr = null;
- BufferedWriter bufw = null;
- try
- {
- bufr = new BufferedReader(new FileReader("CopyTest.java"));
- bufw = new BufferedWriter(new FileWriter("D:\\BufferedCopy.txt"));
- String line = null;
- while((line=bufr.readLine()) != null)
- {
- bufw.write(line);//由于readLine不读换行符;
- bufw.newLine();//所以每读一行就需要换行一次;
- }
- }
- catch (IOException e)
- {
- throw new RuntimeException("Read and write failure");
- }
- finally //关闭流资源;
- {
- try
- {
- if(bufr != null)
- bufr.close();
- }
- catch (IOException e)
- {
- throw new RuntimeException("Read close failure");
- }
- try
- {
- if(bufw != null)
- bufw.close();
- }
- catch (IOException e)
- {
- throw new RuntimeException("Write close failure");
- }
- }
- }
- }
- imp
ort java.io.*; - class MyBufferedReader
- {
- private FileReader r;
- MyBufferedReader(FileReader r)
- {
- this.r = r;
- }
- //自定义一个readLine方法myReadLine;
- public String myReadLine()throws IOException
- {
- StringBuilder sb = new StringBuilder();
- int ch = 0;
- while((ch=r.read()) != -1)
- {
- if(ch == '\r')//当读到'\r'时,重新回去循环;
- continue;
- if(ch == '\n')//当读到'\n'时,将读到的数据转换成字符串;
- return sb.toString();
- else
- sb.append((char)ch);//否则的话,就将数据存储到sb中;
- }
- if(sb.length() !=0)//当最后一行没有出现回车符时,也要将数据转换成字符串;
- return sb.toString();
- return null;
- }
- public void myClose()throws IOException //自定义myClose方法;
- {
- r.close();
- }
- }
- class MyBufferedReaderDemo
- {
- public static void main(String[] args) throws IOException
- {
- FileReader fr = new FileReader("CopyTest.java");
- MyBufferedReader mbuf = new MyBufferedReader(fr);
- String line = null;
- while((line=mbuf.myReadLine()) != null)//调用myReadLine方法;
- {
- System.out.println(line);
- }
- mbuf.myClose();
- }
- }
- imp
ort java.io.*; - class MyBufferedReader extends Reader //该类继承Reader
- {
- private Reader r;
- MyBufferedReader(Reader r)
- {
- this.r = r;
- }
- public String myReadLine()throws IOException
- {
- StringBuilder sb = new StringBuilder();
- int ch = 0;
- while((ch=r.read())!=-1)
- {
- if(ch == '\r') //当读到回车符的’\r’时重新循环;
- continue;
- if(ch == '\n') //当读到回车符的’\n’时直接打印当前行;
- return sb.toString();
- else
- sb.append((char)ch);//如果没有遇到回车符将一直添加字符到sb中;
- }
- return null;
- }
- /*覆盖父类中的抽象方法*/
- public void close()throws IOException
- {
- r.close();
- }
- public int read(char[] cbuf, int off, int len)throws IOException
- {
- return read(cbuf,off,len);
- }
- public void myClose()throws IOException
- {
- r.close();
- }
- }
- class MyBufferedReaderDemo
- {
- public static void main(String[] args) throws IOException
- {
- MyBufferedReader buf = new MyBufferedReader(new FileReader("java.txt"));
- String line = null;
- while((line=buf.myReadLine()) != null)
- {
- System.out.println(line);
- }
- }
- }
- imp
ort java.io.*; - class LineNumberReaderDemo
- {
- public static void main(String[] args) throws IOException
- {
- FileReader fr = new FileReader("BufferedWriterDemo.java");
- LineNumberReader lnr = new LineNumberReader(fr);
- lnr.setLineNumber(100);//此处设置文件的行号从100(不包含100)开始;
- String line = null;
- while((line=lnr.readLine())!=null)
- {
- System.out.println(lnr.getLineNumber()+":"+line);
- } //getLineNumber()可以获取文件的行号;
- lnr.close();
- }
- }
- imp
ort java.io.*; - class MyLineNumberReader
- {
- private Reader r;
- private int lineNumber;
- public void setLineNumber(int lineNumber)
- {
- this.lineNumber = lineNumber;
- }
- public int getLineNumber()
- {
- return lineNumber;
- }
- MyLineNumberReader(Reader r)
- {
- this.r = r;
- }
- public String myReadLine() throws IOException
- {
- lineNumber++; //当每次调用MyReadLine方法时lineNumber就加一次;
- StringBuilder sb = new StringBuilder();
- int ch = 0;
- while((ch = r.read()) != -1)
- {
- if(ch == '\r')
- continue;
- if(ch == '\n')
- return sb.toString();
- else
- sb.append((char)ch);
- }
- if(sb.length() != 0)
- return sb.toString();
- return null;
- }
- public void myClose()throws IOException
- {
- r.close();
- }
- }
- class MyLineNumberReaderDemo
- {
- public static void main(String[] args) throws IOException
- {
- FileReader fr = new FileReader("BufferedReaderDemo.java");
- MyLineNumberReader mlnr = new MyLineNumberReader(fr);
- mlnr.setLineNumber(100); //设置起始行号为100;
- String line = null;
- while((line = mlnr.myReadLine()) != null)
- {
- System.out.println(mlnr.getLineNumber()+":"+line);
- }
- mlnr.myClose();
- }
1)、每读一个字节就打印一个字节;
2)、定义一个固定长度的数组,将读到的字节先存入到数组中,读完之后再一次性打印出来。
3)、定义一个长度为刚好的数组,其可是使用available方法获取,将读到的字节存入到刚好大小的数组中,让后直接全部打印出来。
在实际使用时,建议使用第二种方法,因为第一种方法读取速度较慢,第三种方法在读取较大文件时,当内存不够用时,就会发生内存溢出。
- imp
ort java.io.*; - class FileStream
- {
- public static void main(String[] args) throws IOException
- {
- readFile_3();
- }
- public static void readFile_1()throws IOException
- {
- FileInputStream fis = new FileInputStream("D:\\java.txt");
- int ch = 0;
- while((ch = fis.read()) != -1)
- {
- System.out.print((char)ch);
- }
- fis.close();
- }
- public static void readFile_2()throws IOException
- {
- FileInputStream fis = new FileInputStream("D:\\java.txt");
- byte[] bt = new byte[1024];
- int len = 0;
- while((len = fis.read(bt)) != -1)
- {
- System.out.println(new String(bt,0,len));
- }
- fis.close();
- }
- public static void readFile_3()throws IOException
- {
- FileInputStream fis = new FileInputStream("D:\\java.txt");
- byte[] bt = new byte[fis.available()];//使用available方法可以获取fis的字节长度;
- fis.read(bt);
- System.out.println(new String(bt));
- }
- public static void writeFile()throws IOException
- {
- FileOutputStream fos = new FileOutputStream("D:\\java.txt");
- fos.write("Hellojava".getBytes());
- fos.close();
- }
- }
2)、用字节写入流对象创建一副图片文件,用于存储获取到的图片数据;
3)、通过循环读写完成数据的存储;
4)、关闭资源。
- imp
ort java.io.*; - class CopyPicDemo
- {
- public static void main(String[] args)
- {
- FileInputStream fis = null;
- FileOutputStream fos = null;
- try
- {
- fis = new FileInputStream("D:\\1.jpg");
- fos = new FileOutputStream("D:\\2.jpg");
- int len = 0;
- byte[] bt = new byte[1024];
- while((len = fis.read(bt)) != -1)
- {
- fos.write(bt,0,len);
- }
- }
- catch (IOException e)
- {
- throw new RuntimeException("read and write file failure");
- }
- finally
- {
- try
- {
- if(fis!=null)
- fis.close();
- }
- catch (IOException e)
- {
- throw new RuntimeException("read close failure");
- }
- try
- {
- if(fos!=null)
- fos.close();
- }
- catch (IOException e)
- {
- throw new RuntimeException("write close failure");
- }
- }
- }
- imp
ort java.io.*; - class CopyMp3Demo
- {
- public static void main(String[] args) throws IOException
- {
- long start = System.currentTimeMillis();//复制开始时间;
- copy();
- long end = System.currentTimeMillis();//复制结束后的时间;
- System.out.println((end-start)+"毫秒");//复制mp3总共用时;
- }
- public static void copy()throws IOException
- {
- //通过字节流的缓冲区完成复制;将流对象作为参数传递给缓冲对象的构造函数;
- BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\1.mp3"));
- BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\2.mp3"));
- //此方法是读一字节的数据就写一字节的数据;将数据写入到缓冲区中;
- int bt = 0;
- while((bt = bis.read()) != -1)
- {
- bos.write(bt);
- }
- bis.close();
- bos.close();
- }
- }
- imp
ort java.io.*; - class MyBufferedInputStream
- {
- private InputStream in;
- private byte[] buf = new byte[1024];
- 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;
- }
- else if(count > 0)
- {
- byte b = buf[pos];
- count--;
- pos++;
- return b;
- }
- return -1;
- }
- public void myClose()throws IOException
- {
- in.close();
- }
- }
- class MyBufferedInputStreamDemo
- {
- public static void main(String[] args) throws IOException
- {
- MyBufferedInputStream bis = new MyBufferedInputStream(new FileInputStream("D:\\1.mp3"));
- BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("D:\\2.mp3"));
- int by = 0;
- while((by = bis.myRead()) != -1)
- {
- bos.write(by);
- }
- bis.close();
- bos.close();
- }
- }
此代码在复制过程中,会出现目标文件中没有数据;这是问什么呢?
mp3文件的存储格式是二进制数据存放的,当取数据的时候碰到1111 1111 1111 1111 0000 0101 0100 1101… ,当连续读到8个二进制数据1111 1111返回时,将会被强转提升成int型,即变成-1,此时用4个八位存储该数据;所以当读到语句while((by = bis.myRead()) != -1)时,将跳出循环,不再写数据;就会出现以上情况。
那么这个问题该如何解决呢?
为了避免-1与判断标记-1相同,需要在保留原8个二进制数据1111 1111时,在转换成int类型时,在前24位补0,即00000000 00000000 00000000 11111111,这样既可以避免 原数据不变化,也可以避免出现于标记-1相同的情况出现。此时只需要将返回的b&255。其修改情况如下:
- 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;
- }
- imp
ort java.io.*; - 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))//遇到over时退出循环;
- break;
- System.out.println(s.toUpperCase());//打印出输入字符的大写;
- sb.delete(0,s.length());//每次输完一行后就清空一次容器;
- }
- else
- sb.append((char)ch);//否则就将数据存储在容器中;
- }
- }
- }
- imp
ort java.io.*; - class InputStreamReaderDemo
- {
- public static void main(String[] args) throws IOException
- {
- //获取键盘录入;
- InputStream in = System.in;
- //将字节流转换成字符流,使用转换流;
- InputStreamReader isr = new InputStreamReader(in); //读取转换流;
- //为了提高效率使用缓冲流技术;
- BufferedReader bufr = new BufferedReader(isr);
- OutputStream out = System.out;
- OutputStreamWriter osw = new OutputStreamWriter(out); //写入转换流;
- BufferedWriter bufw = new BufferedWriter(osw);
- String line = null;
- while((line = bufr.readLine()) != null)
- {
- if(line.equals("over"))
- break;
- bufw.write(line.toUpperCase());
- bufw.newLine(); //由于readLine不读取回车符,所以没读一行就需要重新换行;
- bufw.flush();
- }
- bufr.close();
- bufw.close();
- }
- }
2)操作的数据是否是纯文本文件
是: 字符流 不是:字节流
3)当体系明确后,再明确使用哪个具体的对象,通过设备来进行区分:
源设备:内存、硬盘、键盘;
目的设备:内存、硬盘、控制台。
InputStreamReader isr = new InputStreamReader(System.in);
需要提高效率吗?需要,则需要使用BufferedReader
BufferedReader bufr = new BufferedReader(isr);
目的:OutputStream Writer;
设备:硬盘,文件,使用FileWriter;
是否是纯文本?是,使用Writer
FileWriter fr = new FileWriter(“A.txt”);
需要提高效率吗?需要,使用BufferedWriter
BufferedWriter new = BufferedWriter(fr);
扩展:需要把录入的数据按照指定的编码表UTF-8存入到文件中
目的:OutputStream Writer;
是否是纯文本?是,使用Writer
设备:硬盘,文件,使用FileWriter;FileWriter使用的是默认编码表:GBK.
但是存储时要使用指定的编码表UTF-8,而指定的编码表只有转换流可以指定,所以要使用的对象时 OutputStreamWriter,而该转换流对象要接受一个字节输出流,而且还可以操作文件的字节输出流FileOutputStream
OutputStreamWriter osw
= new OutputStreamWriter(new FileOutputStream(“B.txt”),”UTF-8”);
什么时候使用转换流?转换流为字符和字节之间的桥梁。通常涉及到字符编码转换时,需要用到转换流。- imp
ort java.io.*; - class InputStreamTest
- {
- public static void main(String[] args) throws IOException
- {
- BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
- BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("D:\\3.txt"),"UTF-8"));
- //这里需要将指定的编码表作为参数传递到OutputStreamWriter;
- String line = null;
- while((line = bufr.readLine()) != null)
- {
- if(line.equals("over"))
- break;
- bufw.write(line);
- bufw.flush();
- bufw.newLine();
- }
- bufr.close();
- bufw.close();
- }
- }
- import java.io.*;
- import java.util.*;
- import java.text.*;
- class ExceptionInfo
- {
- public static void main(String[] args) throws IOException
- {
- try
- {
- int[] arr = new int[2];
- System.out.println(arr[2]);//角标越界异常发生;
- }
- 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("D:\\ExceptionLog.txt");//指定异常信息存放目的地;
- ps.println(s);
- System.setOut(ps);
- }
- catch (IOException ex)
- {
- throw new RuntimeException("日志创建失败");
- }
- e.printStackTrace(System.out);
- }
- }
- }
- import java.util.*;
- import java.io.*;
- class SystemInfo
- {
- public static void main(String[] args) throws IOException
- {
- Properties prop = System.getProperties();
- //System.out.println(prop);
- System.setOut(new PrintStream("D:\\1.txt"));
- prop.list(System.out);
- }
- }