概念:
IO流来处理设备之间的数据传输
Java对数据的操作是通过流的方式
Java用于操作流的对象都在IO包中
流按操作数据分为两种:字节流(图片,纯文本数据)与字符流(文字)
流按流向分为:输入流,输出流。
一、字符流:
写:
读:
复制文件:
Windows换行:\r\n
Linux换行:\n
IO异常处理方式:
import java.io.FileWriter;
import java.io.IOException;
public class FileWriteDemo {
public static void main(String[] args) {
FileWriter fw = null;
try {
fw = new FileWriter("demo.txt");
fw.write("Hello Java");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if( fw != null)
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
import java.io.FileReader;
import java.io.IOException;
public class MyBuffereReader {
private FileReader r;
MyBuffereReader(FileReader r){
this.r = r;
}
//定义一个可以一次读一行数据的方法
public String myReadLine() throws IOException {
//定义一个临时容器。原BuffereReader封装的是字符数组。
//定义一个StringBuilder容器。因为最终还是要将数组编程字符串
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 ReaderDemo{
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("a.txt");
MyBuffereReader myfr = new MyBuffereReader(fr);
String line;
while((line =myfr.myReadLine()) != null){
System.out.println(line);
}
myfr.myClose();
}
}
源码:
String readLine(boolean ignoreLF) throws IOException {
StringBuffer s = null;
int startChar;
synchronized (lock) {
ensureOpen();
boolean omitLF = ignoreLF || skipLF;
bufferLoop:
for (;;) {
if (nextChar >= nChars)
fill();
if (nextChar >= nChars) { /* EOF */
if (s != null && s.length() > 0)
return s.toString();
else
return null;
}
boolean eol = false;
char c = 0;
int i;
/* Skip a leftover '\n', if necessary */
if (omitLF && (cb[nextChar] == '\n'))
nextChar++;
skipLF = false;
omitLF = false;
charLoop:
for (i = nextChar; i < nChars; i++) {
c = cb[i];
if ((c == '\n') || (c == '\r')) {
eol = true;
break charLoop;
}
}
startChar = nextChar;
nextChar = i;
if (eol) {
String str;
if (s == null) {
str = new String(cb, startChar, i - startChar);
} else {
s.append(cb, startChar, i - startChar);
str = s.toString();
}
nextChar++;
if (c == '\r') {
skipLF = true;
}
return str;
}
if (s == null)
s = new StringBuffer(defaultExpectedLineLength);
s.append(cb, startChar, i - startChar);
}
}
}
BufferedReader和BufferedWriter都是Reader和Writer的装饰类
最终版本:装饰设计方式,继承体系超类。
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
public class MyBuffereReader extends Reader {
private Reader r;
MyBuffereReader(Reader r){
this.r = r;
}
//定义一个可以一次读一行数据的方法
public String myReadLine() throws IOException {
//定义一个临时容器。原BuffereReader封装的是字符数组。
//定义一个StringBuilder容器。因为最终还是要将数组编程字符串
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;
}
@Override
public int read(char[] cbuf, int off, int len) throws IOException {
return r.read(cbuf,off,len);
}
@Override
public void close() throws IOException {
r.close();
}
public void myClose() throws IOException {
r.close();
}
}
class ReaderDemo{
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("a.txt");
MyBuffereReader myfr = new MyBuffereReader(fr);
String line;
while((line =myfr.myReadLine()) != null){
System.out.println(line);
}
myfr.myClose();
}
}
自己写LineNumberReader:
class MyLineNumberReader{
private Reader r;
private int lineNumber;
MyLineNumberReader(Reader r){
this.r = r;
}
public int getLineNumber() {
return lineNumber;
}
public void setLineNumber(int lineNumber) {
this.lineNumber = lineNumber;
}
public String myReaderLine() throws IOException{
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 ReaderDemo{
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("a.txt");
MyLineNumberReader myfr = new MyLineNumberReader(fr);
String line;
while((line =myfr.myReaderLine()) != null){
System.out.println(myfr.getLineNumber() + "::" + line);
}
myfr.myClose();
}
}
继承BufferedReader:提高代码复用性
class MyLineNumberReader extends MyBuffereReader{
private Reader r;
private int lineNumber;
MyLineNumberReader(Reader r){
super(r);
}
public int getLineNumber() {
return lineNumber;
}
public void setLineNumber(int lineNumber) {
this.lineNumber = lineNumber;
}
public String myReaderLine() throws IOException{
lineNumber++;
return super.myReadLine();
}
}
- 输入流
- 输出流
注意:上面少了一个释放资源, f r . c l o s e ( ) fr.close() fr.close().
练习:
练习:文件复制
- 缓冲流的基本使用:
缓冲流复制文件:
缓冲区的特殊功能:
复制文件:
总结:5种方式复制文本:
import java.io.*;
public class CopyTest {
public static void main(String[] args) throws IOException{
String srcFileName = "FileWrite.java";
String destFileName = "Copy.java";
method1(srcFileName,destFileName);
method2(srcFileName,destFileName);
method3(srcFileName,destFileName);
method4(srcFileName,destFileName);
// method5(srcFileName,destFileName);
}
//基本流一次读写一个字符
public static void method1(String srcFileName, String destFileName) throws IOException{
//创建输入流对象
FileReader fr = new FileReader(srcFileName);
//创建输出流对象
FileWriter fw = new FileWriter(destFileName);
//一次读写一个字符
int ch;
while((ch = fr.read()) != -1)
{
fw.write(ch);
}
//释放资源
fw.close();
fr.close();
}
//基本流一次读写一个字符
public static void method2(String srcFileName, String destFileName) throws IOException{
//创建输入流对象
FileReader fr = new FileReader(srcFileName);
//创建输出流对象
FileWriter fw = new FileWriter(destFileName,true);
//一次读写一个字符
char[] chs = new char[1024];
int len;
while((len = fr.read(chs)) != -1) //函数原型 public int read(char cbuf[]) throws IOException
{
fw.write(chs,0,len); //public void write(char cbuf[], int off, int len) throws IOException
}
//释放资源
fw.close();
fr.close();
}
//缓冲流一次读写一个字符
public static void method3(String srcFileName, String destFileName) throws IOException
{
//创建输入缓冲对象
BufferedReader br = new BufferedReader(new FileReader(srcFileName));
//创建输出缓冲对象
BufferedWriter bw = new BufferedWriter(new FileWriter(destFileName,true));
//一次读写一个字符
int ch;
while((ch = br.read()) != -1){
bw.write(ch);
}
//释放资源
bw.close();
br.close();
}
//缓冲流一次读写一个字符数组
public static void method4(String srcFileName, String destFileName) throws IOException
{
//创建输入缓冲对象
BufferedReader br = new BufferedReader(new FileReader(srcFileName));
//创建输出缓冲对象
BufferedWriter bw = new BufferedWriter(new FileWriter(destFileName,true));
//一次读写一个字符数组
char[] chs = new char[1024];
int len;
while((len = br.read(chs)) != -1){
bw.write(chs,0,len);
}
//释放资源
bw.close();
br.close();
}
//缓冲流一次读写一个字符串
public static void method5(String srcFileName, String destFileName) throws IOException
{
//创建输入缓冲对象
BufferedReader br = new BufferedReader(new FileReader(srcFileName));
//创建输出缓冲对象
BufferedWriter bw = new BufferedWriter(new FileWriter(destFileName,true));
//一次读写一个字符串
String line;
while((line = br.readLine()) != null){
bw.write(line);
bw.newLine();
bw.flush();
}
//释放资源
bw.close();
br.close();
}
}
练习:把集合元素写到文本文件中
练习:把文本文件中的数据读取到集合中:
二、字节流
不涉及刷新,不涉及到任何转换
总结: