JAVA学习第19天,
/*
IO流用来处理设备(数据)之间的数据传输。
java对数据的操作是通过流的方式
java用于操作流的对象在IO包中
流按操作数据分为两种:字节流和字符流
流按流向分为:输入流,输出流
以前只有字节流,字符流是怎么产生的呢?
可以自己指定查找那个字节表
字节流的抽象基类:
InputStream , OutputStream
字符流的抽象基类
Reader , Writer
字符流特点:
既然IO流是用于操作数据的,那么数据最常见体现形式是:文件
那么先以操作文件为主来演示。
需求:在硬盘上,创建一个文件并写入一些文字数据。
思路:找到一个专门用于操作文件的Writer子类对象, FileWriter,后缀名是父类名,前缀名是该流对象的功能
*/
import java.io.*;
class IODemo
{
public static void main(String[] args) throws IOException
{
//创建一个FileWriter对象,该对象一被初始化就必须要明确被操作的文件。
//而且该文件会被创建到指定目录下。如果该目录下已有同名文件,将被覆盖
//其实该步就是在明确数据要存放的目的地
FileWriter fw = new FileWriter("demo.txt");
//调用weitr方法,将字符串写入到流中,临时数据,不会放到文件中
fw.write("abcdef");
//要将数据写入到demo.txt文件下,
//可以刷新流对象中的缓冲中的数据
//将数据刷到目的地中
//fw.flush();
//关闭流资源,但是关闭之前会刷新一次内部的缓冲中的数据
//将数据刷新到目的地中
//和flush区别:flush刷新后,流可以继续使用,close刷新后,会将流关闭
fw.close();
fw.write("hahah");
//fw.flush();
}
}
/*
IO异常的处理方式
*/
import java.io.*;
class FileWriterDemo
{
public static void main(String[] args)
{
FileWriter fw = null;
try
{
fw = new FileWriter("demo.txt");
fw.write("abcdefghjio");
}
catch (IOException e)
{
System.out.println(e.toString()+"...");
}
finally
{
try
{
if(fw!=null)
fw.close();
}
catch (IOException e)
{
System.out.println(e.toString()+"......");
}
}
}
}
/*
演示对已有文件的数据续写
*/
import java.io.*;
class FileWriterDemo2
{
public static void main(String[] args)
{
FileWriter fw = null;
try
{
//传递一个true参数,代表不覆盖已有的文件,并在已有文件的末尾处进行数据续写
fw = new FileWriter("demo.txt",true);
fw.write("hhahahha\r\nhello");
}
catch (IOException e)
{
System.out.println(e.toString()+"...");
}
finally
{
try
{
if(fw!=null)
fw.close();
}
catch (IOException e)
{
System.out.println(e.toString()+"......");
}
}
}
}
//第一种读取方式:读一个字符,就打印一次
import java.io.*;
class FileReaderDemo
{
public static void main(String[] args) throws IOException
{
//创建一个文件读取流对象,和指定名称的文件相关联
//要保证文件是已经存在的,如果不存在,会发生异常 FileNotFoundException
FileReader fr = new FileReader("demo.txt");
/*
while (true)
{
int ch = fr.read();
if(ch == -1)
break;
System.out.println("ch="+(char)(ch) );
}*/
//调用读取流对象的read方法
//raed() 一次读一个字符,而且会自动往下读
int ch1 = fr.read();
System.out.println("ch1="+(char)ch1);
int ch2 = fr.read();
System.out.println("ch2="+(char)ch2);
int ch3 = fr.read();
System.out.println("ch3="+ch3);
int ch4 = fr.read();
System.out.println("ch4="+ch4); //dome.txt文件只有三个字符,当读到第四个字符时,返回数组是-1;
int ch5 = fr.read();
System.out.println("ch5="+(char)ch5);
fr.close();
}
}
/*
第二种获取方法:通过字符数组获取,读一个存一个到字符数组中,当存满数组再打印出来
*/
import java.io.*;
class FileReaderDemo2
{
public static void main(String[] args) throws IOException
{
FileReader fr = new FileReader("demo.txt");
char[] buf = new char[1024];
int num = 0;
while ((num = fr.read(buf))!=-1)
{
System.out.println(new String(buf,0,num));
}
/*
//定义一个字符数组,用于存储读到的字符
//该read(char[])返回的是读到的字符个数
char[] buf = new char[3];
int num = fr.read(buf);
System.out.println("num="+num+"..."+new String(buf));
int num1 = fr.read(buf);
System.out.println("num1="+num1+"..."+new String(buf));
int num2 = fr.read(buf);
System.out.println("num2="+num2+"..."+new String(buf,0,num2));
int num3 = fr.read(buf);
System.out.println("num3="+num3+"..."+new String(buf));
*/
fr.close();
}
}
/*
读取一个java文件,并打印在控制台上
*/
import java.io.*;
class FileReaderTest
{
public static void main(String[] args) throws IOException
{
FileReader fr = new FileReader("IODemo.java");
char[] buf = new char[1024];
int num = 0;
while ((num = fr.read(buf)) != -1)
{
System.out.print(new String(buf,0,num));
}
fr.close();
}
}
/*
将C盘一个文本文件复制到D盘(必须掌握)
步骤:
1,在D盘创建一个文件,用于存储C盘文件中的数据。
2,定义读取流和C盘文件关联
3,通过不断的读写完成数据存储
4,关闭资源
*/
import java.io.*;
class CopyText
{
public static void main(String[] args)
{
copy_2();
}
//第二种方法
public static void copy_2()
{
FileWriter fw = null;
FileReader fr = null;
try
{
fw= new FileWriter("FileCopy_2.txt");
fr= new FileReader("IODemo.java");
char[] buf = new char[1024];
int len = 0;
while ((len=fr.read(buf))!=-1)
{
fw.write(buf,0,len);
}
}
catch (Exception e)
{
System.out.println("读写异常");
}
finally
{
if (fw!=null)
try
{
fw.close();
}
catch (Exception e)
{
}
if (fr!=null)
try
{
fr.close();
}
catch (Exception e)
{
}
}
}
//方法一:从C盘读一个字符,就往D盘写一个字符
public static void Copy_1() throws IOException
{
//创建目的地
FileWriter fw = new FileWriter("FileCopy_1.txt");
//创建读取流文件关联
FileReader fr = new FileReader("FileWriterDemo.java");
int ch = 0;
while ((ch = fr.read())!= -1) //???
{
fw.write(ch);
}
fw.close();
fr.close();
}
}
/*
字符流的缓冲区(相当于蓄水池),缓冲区在内存中,停电了就释放了
缓冲取得出现时为了提高流的操作效率而出现的
所以在创建缓冲区之前,必须要先有流对象
对应类
BufferedWriter
BufferedReader
该缓冲区中提供了一个跨平台的换行符
newLine();方法
*/
import java.io.*;
class BufferedWriterDemo
{
public static void main(String[] args) throws IOException
{
//创建一个字符写入流,指定文件,要是没有这个文件,会在本地创建一个新的文件
FileWriter fw = new FileWriter("buf.txt");
//为了提高字符写入流效率,创建一个缓冲区技术
//只要将需要被提高效率的流对象作为参数传递给缓冲区的构造函数即可
BufferedWriter bufw = new BufferedWriter(fw);
for (int x=0;x<5 ;x++ )
{
bufw.write("abcd"+x);
bufw.newLine();
bufw.flush();
}
//bufw.write("abcdefg");
// bufw.newLine(); // bufw.write("\r\n"); 自动换行功能
//记住,只要用到缓冲区,就要记得刷新
//bufw.flush();
//其实关闭缓冲区,就是在关闭缓冲区中的流对象,fw.close();
bufw.close();
}
}
/*
字符读取流缓冲区:
该缓冲区提供了一个一次读一行的方法,readLine();方便于对文本数据的获取
当返回null时,表示读到了文件末尾
readLine() 方法返回的时候只返回回车符之前的数据内容,并不返回回车符
理解原理: 相当于 read()\r\n
*/
import java.io.*;
class BufferedReaderDemo
{
public static void main(String[] args) throws IOException
{
//先创建一个读取流对象和文件相关联
FileReader fr = new FileReader("buf.txt");
//为了提高效率,加入缓冲区技术,将字符读取流对象作为参数传递给缓冲区对象的构造函数
BufferedReader bufr = new BufferedReader(fr);
String len = null;
while ((len=bufr.readLine()) != null)
{
System.out.println(len);
}
/*
String s1 = bufr.readLine();
System.out.println("s1="+s1);
String s2 = bufr.readLine();
System.out.println("s2="+s2);
String s3 = bufr.readLine();
System.out.println("s3="+s3);
*/
bufr.close();
}
}
/*
明白了BufferedReader 类中特有方法, readLine 的原理后,
可以自定义一个类中包含一个功能和readLine 一致的方法
来模拟一下 BufferedReader
BufferedReader 特殊方法有两个,一个是换行的读取,一个是关闭
*/
import java.io.*;
class MyBufferedReader
{
private FileReader r;
MyBufferedReader(FileReader r)
{
this.r = r;
}
public String myReadLine() throws IOException
{
StringBuilder sb = new StringBuilder(); //StringBuilder容器,用于临时存放 读取到的字符,最后可转换成字符串类型,用toString()方法
int ch = 0;
while ((ch=r.read()) != -1)
{
if(ch=='\r') //表示扫描到一行的倒数第二位,没必要返回,继续循环查找
continue;
if(ch=='\n') //表示扫描到一行的最后的回车符,需要返回了;
return sb.toString();
else
sb.append((char)ch); //表示没有扫描到最后几位,就把前面的字符全部存放到 StringBuilder 容器中
}
//还有一种情况是,文本输入文字,最后一个字符人们不会输入回车符,但前面还是有字符的,一样还是需要返回
if (sb.length()!=0)
{
return sb.toString();
}
return null; //到这里表示已经走到一行的最后一位了,把整个需要获取的文件都扫描一遍了
}
public void myColse()throws IOException
{
r.close();
}
}
class MyBufferedReaderDemo
{
public static void main(String[] args) throws IOException
{
FileReader fr = new FileReader("buf.txt");
MyBufferedReader myBufr = new MyBufferedReader(fr);
String line =null;
while ((line= myBufr.myReadLine()) != null)
{
System.out.println(line);
}
myBufr.myColse();
}
}
/*
通过缓冲区复制一个 .java文件
*/
import java.io.*;
class CopyTestByBuf
{
public static void main(String[] args)
{
BufferedReader bufr = null;
BufferedWriter bufw = null;
try
{
FileWriter fw = new FileWriter("BufferCopy_1.txt");
FileReader fr = new FileReader("BufferedWriterDemo.java");
//建立写入和读取的缓冲区
bufw = new BufferedWriter(fw);
bufr = new BufferedReader(fr);
String line = null;
while ((line = bufr.readLine()) != null)
{
bufw.write(line);
bufw.newLine(); //注意
bufw.flush();
}
}
catch (IOException e)
{
throw new RuntimeException("读写失败");
}
finally
{
try
{
if (bufw != null)
{
bufw.close();
}
}
catch (IOException e)
{
throw new RuntimeException("写入关闭失败");
}
try
{
if (bufr != null)
{
bufr.close();
}
}
catch (IOException e)
{
throw new RuntimeException("读取关闭失败");
}
}
}
}