IO
2、OutputStream
Reader
BufferedWriter
BufferedReader
实例二:
目的:输出流。OutputStream Writer。
不是:字节流。
源设备:内存,硬盘。键盘
目的设备:内存,硬盘,控制台。
OutputStream
字节流缓冲区:
BufferedInputStream
BufferedOutputStream
目的:输出流。OutputStream Writer。
不是:字节流。
源设备:内存,硬盘。键盘
目的设备:内存,硬盘,控制台。
OutputStream
字节流缓冲区:
BufferedInputStream
BufferedOutputStream
boolean createNewFile()
创建新文件,如果已存在,则不创建,与输出流不同
输出流会覆盖,
创建文件夹
boolean mkdir()
创建此抽象路径名指定的目录。
boolean mkdirs()
创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。
2、删除
boolean delete()
删除此抽象路径名表示的文件或目录。
void deleteOnExit()
在虚拟机终止时,请求删除此抽象路径名表示的文件或目录。
3、判断
boolean canExecute()
该文件是否可执行
boolean exists()
测试此抽象路径名表示的文件或目录是否存在。
boolean isDirectory()
该文件对象是否是目录
boolean isFile();
该文件对象是否是文件
boolean isHidden()
该文件是否是隐藏对象
boolean isAbsolute()
测试此抽象路径名是否为绝对路径名。
4、获取
String getName()
返回由此抽象路径名表示的文件或目录的名称。
String getPath()
将此抽象路径名转换为一个路径名字符串。
String getParent()
返回此抽象路径名父目录的路径名字符串;如
果此路径名没有指定父目录,则返回 null。
String getAbsolutePath()
返回此抽象路径名的绝对路径名字符串。
long lastModified()
返回此抽象路径名表示的文件最后一次被修改的时间。
long length()
返回由此抽象路径名表示的文件的长度。
static File[] listRoots()
列出可用的盘符。
String[] list()
列出File对象目录和文件
5、更改
boolean renameTo(File dest)
重新命名此抽象路径名表示的文件
1、PrintStream 字节打印流
构造方法参数:
(1)、File
(2)、字符串路径
(3)、字节输出流 OutputStream
2、PrintWriter 字符打印流
构造方法参数:
(1)、File
(2)、字符串路径
(3)、字节输出流 OutputStream
(4)、字符输出流 Writer
实例:
一、字节流
1、InputStream2、OutputStream
二、字符流
WriterReader
BufferedWriter
BufferedReader
三、实例一:
import java.io.*;
/* 字符流
Writer
|-FileWriter
*/
class FileTest
{
public static void main(String[] args) throws IOException
{
//创建一个FileWriter对象,同时会在制定目录创建一个文件
FileWriter fw = new FileWriter("test.txt");
//将字符写到流中
fw.write("Test");
//刷新缓冲中的数据,存到目的地
//fw.flush();
/*
关闭流之前会刷新流
flush和close区别:
flush刷新后流还可以继续使用,close关闭流
后不能使用
*/
fw.close();
}
}
实例二:
import java.io.*;
/*
文件异常处理
*/
class IOExceptionTest
{
public static void main(String[] args)
{
FileWriter fw = null;
try
{
fw = new FileWriter("Test.txt");
fw.write("Test");
}
catch (IOException ie)
{
System.out.println(ie.toString());
}
finally {
try
{
if(fw != null)
fw.close();
}
catch (IOException ie)
{
System.out.println(ie.toString());
}
}
}
}
四、字符读取
实例一:import java.io.*;
/*
文件读取
*/
class FileReaderTest
{
public static void main(String[] args) throws IOException
{
read_2();
}
//读取一个字符
public static void read_1() throws IOException {
FileReader fr = new FileReader("FileReaderTest.java");
int ch = 0;
while((ch = fr.read()) != -1) {
System.out.print((char)ch);
}
fr.close();
}
//读取到字符数组
public static void read_2() throws IOException {
FileReader fr = new FileReader("FileReaderTest.java");
//定义一个字符数组
char[] chs = new char[1024];
int num = 0;
while((num = fr.read(chs)) != -1) {
System.out.print(new String(chs, 0 ,num));
}
fr.close();
}
}
实例二:
import java.io.*;
/*
文件拷贝实例
步骤:
1、创建一个字符数组
2、读取字符并写入
注意:通过缓冲区中的readLine方法读取,不包括换行符
*/
class FileCopyTest
{
public static void main(String[] args) throws IOException {
copy_3();
}
//通过缓冲区复制文件
public static void copy_3() {
BufferedReader bufr = null;
BufferedWriter bufw = null;
try
{
bufr = new BufferedReader(new FileReader("FileCopyTest.java"));
bufw = new BufferedWriter(new FileWriter("copy_test.txt"));
String str = null;
while((str = bufr.readLine()) != null) {
bufw.write(str);
bufw.newLine();
bufw.flush();
}
}
catch (IOException ie)
{
throw new RuntimeException("文件读取失败!");
// ie.printStackTrace();
}
finally
{
if (bufr != null)
{
try
{
bufr.close();
}
catch (IOException ie)
{
throw new RuntimeException("写文件关闭失败!");
}
}
if (bufw != null)
{
try
{
bufw.close();
}
catch (IOException ie)
{
throw new RuntimeException("读文件关闭失败!");
}
}
}
}
//读取一个字符数组
public static void copy_2() {
FileWriter fw = null;
FileReader fr = null;
try
{
fw = new FileWriter("Copy_2_test.txt");
fr = new FileReader("FileCopyTest.java");
char[] buf = new char[1024];
int len = 0 ;
while((len = fr.read(buf)) != -1) {
fw.write(buf, 0, len);
}
}
catch (IOException ie)
{
throw new RuntimeException("文件读取失败");
}
finally
{
if (fw != null)
{
try
{
fw.close();
}
catch (IOException ie)
{
}
}
if (fr != null)
{
try
{
fr.close();
}
catch (IOException ie)
{
}
}
}
}
//读取一个字符就写入
public static void copy_1() throws IOException {
FileWriter fw = new FileWriter("Copy_1_Test.txt");
FileReader fr = new FileReader("FileCopyTest.java");
int temp = 0;
while((temp = fr.read()) != -1) {
fw.write(temp);
}
fw.close();
fr.close();
}
}
五、自己实现readLine()
import java.io.*;
/*
实现readLine
原理:就是一个一个的读取字符,在判断改字符如果不是换行符,
就存入缓冲区,如果是则返回缓冲区中的字符
*/
//MyBufferedReader
class MyBufferedReader
{
private FileReader fr;
public MyBufferedReader(FileReader fr) {
this.fr = fr;
}
//读取一行方法
public String myReadLine() throws IOException {
//定义缓冲区
StringBuilder sb = new StringBuilder();
//读取字符
int ch = 0;
while ((ch = fr.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 myColse() throws IOException {
fr.close();
}
}
class MyReadLine
{
public static void main(String[] args) throws IOException
{
MyBufferedReader mybuf = new MyBufferedReader(new FileReader("test.txt"));
String str = null;
while((str = mybuf.myReadLine()) != null) {
System.out.println(str);
}
}
}
六、自定义实现getLineNumber()
import java.io.*;
/*
类 LineNumberReader
int getLineNumber()
获得当前行号。
void setLineNumber(int lineNumber)
设置当前行号。
1、测试这两个方法
2、自定义类实现上述方法
*/
class BufferedLineNumber
{
public static void main(String[] args) throws IOException
{
test_2();
}
//2
public static void test_2() throws IOException {
FileReader fr = new FileReader("BufferedLineNumber.java");
MyBufferedLineNumber mybufr = new MyBufferedLineNumber(fr);
String str = null;
mybufr.setLineNum(100);
while((str = mybufr.readLine()) != null) {
System.out.println(mybufr.getLineNum() + ":" + str);
}
}
//1
public static void test_1() throws IOException {
LineNumberReader lnbr = new LineNumberReader(new FileReader("BufferedLineNumber.java"));
lnbr.setLineNumber(100); //101开始
String str = null;
while((str = lnbr.readLine()) != null) {
System.out.println(lnbr.getLineNumber() + ":" + str);
}
}
}
//自定义类,用来增强BufferedReader类
class MyBufferedLineNumber
{
public MyBufferedLineNumber(Reader r) {
this.r = r;
}
public String readLine() throws IOException {
i++;
StringBuilder sb = new StringBuilder();
int str = 0;
while((str = r.read()) != -1) {
if(str == '\r')
continue;
if(str == '\n')
return sb.toString();
sb.append((char)str);
}
if(sb.length() != 0)
return sb.toString();
return null;
}
public void close() throws IOException {
r.close();
}
public int getLineNum() {
return i;
}
public void setLineNum(int i) {
this.i = i;
}
private Reader r;
private int i;
}
字符流常用对象:
FileReader
FileWriter
BufferedReader
BufferedWriter
Java流操作规律
1,明确源和目的。
源:输入流。InputStream Reader目的:输出流。OutputStream Writer。
2,操作的数据是否是纯文本。
是:字符流。不是:字节流。
3,当体系明确后,在明确要使用哪个具体的对象。
通过设备来进行区分:源设备:内存,硬盘。键盘
目的设备:内存,硬盘,控制台。
----------------------------------
字节流
一、字节流
InputStreamOutputStream
字节流缓冲区:
BufferedInputStream
BufferedOutputStream
实例一;
import java.io.*;
/*
字节流测试
InputStream
OutputStream
注意:字节流写时,不需要刷新
*/
class StreamTest
{
public static void main(String[] args) throws IOException
{
outputTest();
}
//一次性读取完
public static void test_3() throws IOException {
FileInputStream fis = new FileInputStream("Test.txt");
int len = fis.available();
byte[] temp = new byte[len];
fis.read(temp);
System.out.print(new String(temp));
fis.close();
}
//读取一个字节数组
public static void test_2() throws IOException {
FileInputStream fis = new FileInputStream("Test.txt");
byte[] temp = new byte[1024];
int len = 0;
while((len = fis.read(temp)) != -1) {
System.out.print(new String(temp));
}
fis.close();
}
//读取一个打印一个
public static void test_1() throws IOException {
FileInputStream fis = new FileInputStream("Test.txt");
int len = 0;
while((len = fis.read()) != -1) {
System.out.print((char)len + " ");
}
fis.close();
}
//输出
public static void outputTest() throws IOException {
FileOutputStream fos = new FileOutputStream("Test.txt");
fos.write("这是字符串".getBytes());
fos.close();
}
}
拷贝图片文件
1,明确源和目的。
源:输入流。InputStream Reader目的:输出流。OutputStream Writer。
2,操作的数据是否是纯文本。
是:字符流。不是:字节流。
3,当体系明确后,在明确要使用哪个具体的对象。
通过设备来进行区分:源设备:内存,硬盘。键盘
目的设备:内存,硬盘,控制台。
----------------------------------
字节流
一、字节流
InputStreamOutputStream
字节流缓冲区:
BufferedInputStream
BufferedOutputStream
实例一;
import java.io.*;
/*
字节流测试
InputStream
OutputStream
注意:字节流写时,不需要刷新
*/
class StreamTest
{
public static void main(String[] args) throws IOException
{
outputTest();
}
//一次性读取完
public static void test_3() throws IOException {
FileInputStream fis = new FileInputStream("Test.txt");
int len = fis.available();
byte[] temp = new byte[len];
fis.read(temp);
System.out.print(new String(temp));
fis.close();
}
//读取一个字节数组
public static void test_2() throws IOException {
FileInputStream fis = new FileInputStream("Test.txt");
byte[] temp = new byte[1024];
int len = 0;
while((len = fis.read(temp)) != -1) {
System.out.print(new String(temp));
}
fis.close();
}
//读取一个打印一个
public static void test_1() throws IOException {
FileInputStream fis = new FileInputStream("Test.txt");
int len = 0;
while((len = fis.read()) != -1) {
System.out.print((char)len + " ");
}
fis.close();
}
//输出
public static void outputTest() throws IOException {
FileOutputStream fos = new FileOutputStream("Test.txt");
fos.write("这是字符串".getBytes());
fos.close();
}
}
拷贝图片文件
import java.io.*;
/*
字节流拷贝文件
1、将源文件与字节输入流相关联
2、将目标文件与字节输出流相关联
3、拷贝
*/
class CopyPic
{
public static void main(String[] args)
{
FileInputStream fis = null;
FileOutputStream fos = null;
try
{
fis = new FileInputStream("c:\\1.bmp"); //源
fos = new FileOutputStream("c:\\2.bmp"); //目标
int len = 0;
byte[] sub = new byte[1024];
while((len = fis.read(sub)) != -1) {
fos.write(sub, 0, len);
}
}
catch (IOException ie)
{
throw new RuntimeException("文件拷贝失败!");
}
finally
{
if (fis != null)
{
try
{
fis.close();
}
catch (IOException ie)
{
throw new RuntimeException("源文件关闭失败!");
}
}
if (fos != null)
{
try
{
fos.close();
}
catch (IOException ie)
{
throw new RuntimeException("源文件关闭失败!");
}
}
}
}
}
拷贝MP3
import java.io.*;
/*
拷贝mp3
*/
class CopyMp3
{
public static void main(String[] args) throws IOException
{
long start = System.currentTimeMillis();
copyTest();
long end = System.currentTimeMillis();
System.out.println((end - start) + "毫秒");
}
public static void copyTest() throws IOException {
BufferedInputStream bufis = new BufferedInputStream(new FileInputStream("c:\\1.mp3")); //源文件
BufferedOutputStream bufos = new BufferedOutputStream(new FileOutputStream("c:\\2.mp3")); //目标文件
int len = 0;
while((len = bufis.read()) != -1) {
bufos.write(len);
}
bufis.close();
bufos.close();
}
}
四、自定义InputStream缓冲区
import java.io.*;
/*
实现BufferedInputStreame功能
步骤:
1、首先定义InputStremae变量用来接受传进来的对象
2、定义一字节数组和两个变量
*/
class MyBufferedInputStream
{
private InputStream r;
private int pos;
private int count;
private byte[] sub = new byte[1024];
MyBufferedInputStream(InputStream r) {
this.r = r;
}
public int read() throws IOException {
if (count == 0) //如果count等于0说明字节数组中的数据取完了
{
count = r.read(sub); //取数据到缓冲区
if (count < 0) //说明文件已经读取完了
return -1;
pos = 0;
byte b = sub[pos];
count--; //计数器减一
pos++; //位置自增
return b & 0xff;
} else if (count > 0)
{
byte b = sub[pos];
count--;
pos++;
return b & 0xff;
}
return -1;
}
//close
public void close() throws IOException {
r.close();
}
}
从键盘上读取数据
import java.io.*;
/*
从键盘读取数据
需求:
1、从键盘读取一串数据 敲回车后全部打印
2、如果输入over则停止输入
*/
class ReadIn
{
public static void main(String[] args) throws IOException
{
test_2();
}
//方式二 将InputStream流转成Reader流
public static void test_2() throws IOException{
// //获取键盘输入流
// InputStream in = System.in;
//
// //将字节流转换成字符流
// InputStreamReader is = new InputStreamReader(in);
//
// //为了提高读取效率使用缓冲技术
// BufferedReader bufi = new BufferedReader(is);
//1、键盘录入
// BufferedReader bufi = new BufferedReader(new InputStreamReader(System.in));
//2、读取文件
BufferedReader bufi = new BufferedReader(new InputStreamReader(new FileInputStream("ReadIn.java")));
// //将输出字节流转缓存字节流
// OutputStream out = System.out;
// OutputStreamWriter outw = new OutputStreamWriter(out);
// BufferedWriter bufw = new BufferedWriter(outw);
//1、输出到控制台
// BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(System.out));
//2、输出到文件
BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("test.txt")));
String line = null;
while((line = bufi.readLine()) != null) {
if("over".equals(line))
break;
bufw.write(line);
bufw.newLine();
bufw.flush();
// System.out.println(line);
}
}
//方式一
public static void test_1() throws IOException {
InputStream in = System.in;
StringBuilder sb = new StringBuilder();
int ch = 0;
while(true) {
ch = in.read();
if(ch == 13)
continue;
if(ch == 10) {
if("over".equals(sb.toString()))
break;
System.out.println(sb.toString());
sb.delete(0, sb.length());
} else {
sb.append((char)ch);
}
}
}
}
自定义InputStream缓冲区
import java.io.*;
/*
实现BufferedInputStreame功能
步骤:
1、首先定义InputStremae变量用来接受传进来的对象
2、定义一字节数组和两个变量
*/
class MyBufferedInputStream
{
private InputStream r;
private int pos;
private int count;
private byte[] sub = new byte[1024];
MyBufferedInputStream(InputStream r) {
this.r = r;
}
public int read() throws IOException {
if (count == 0) //如果count等于0说明字节数组中的数据取完了
{
count = r.read(sub); //取数据到缓冲区
if (count < 0) //说明文件已经读取完了
return -1;
pos = 0;
byte b = sub[pos];
count--; //计数器减一
pos++; //位置自增
return b & 0xff;
} else if (count > 0)
{
byte b = sub[pos];
count--;
pos++;
return b & 0xff;
}
return -1;
}
//close
public void close() throws IOException {
r.close();
}
}
File类常用方法及实例
一、File类常见方法:
1、创建boolean createNewFile()
创建新文件,如果已存在,则不创建,与输出流不同
输出流会覆盖,
创建文件夹
boolean mkdir()
创建此抽象路径名指定的目录。
boolean mkdirs()
创建此抽象路径名指定的目录,包括所有必需但不存在的父目录。
2、删除
boolean delete()
删除此抽象路径名表示的文件或目录。
void deleteOnExit()
在虚拟机终止时,请求删除此抽象路径名表示的文件或目录。
3、判断
boolean canExecute()
该文件是否可执行
boolean exists()
测试此抽象路径名表示的文件或目录是否存在。
boolean isDirectory()
该文件对象是否是目录
boolean isFile();
该文件对象是否是文件
boolean isHidden()
该文件是否是隐藏对象
boolean isAbsolute()
测试此抽象路径名是否为绝对路径名。
4、获取
String getName()
返回由此抽象路径名表示的文件或目录的名称。
String getPath()
将此抽象路径名转换为一个路径名字符串。
String getParent()
返回此抽象路径名父目录的路径名字符串;如
果此路径名没有指定父目录,则返回 null。
String getAbsolutePath()
返回此抽象路径名的绝对路径名字符串。
long lastModified()
返回此抽象路径名表示的文件最后一次被修改的时间。
long length()
返回由此抽象路径名表示的文件的长度。
static File[] listRoots()
列出可用的盘符。
String[] list()
列出File对象目录和文件
5、更改
boolean renameTo(File dest)
重新命名此抽象路径名表示的文件
二、目录列表
import java.io.*;
/*
File类
列出目录中的目录
*/
class FileTest
{
public static void main(String[] args)
{
File f = new File("c:/testdir");
removeDir(f);
}
//输出目录前面的空格
public static String getLevel(int n) {
StringBuilder sb = new StringBuilder();
sb.append("|--");
for(int i=0;i<n;i++) {
sb.insert(0, " ");
}
return sb.toString();
}
//递归删除一个目录
public static void removeDir(File dir) {
File[] files = dir.listFiles();
for(File f : files) {
if(f.isDirectory()) {
removeDir(f);
} else {
out(f + "--file--" + f.delete());
}
}
out(dir + "--dir--" + dir.delete());
}
//列出目录和文件1
public static void showDir(File dir, int level) {
// out(getLevel(level) + dir.getPath());
level++;
File[] files = dir.listFiles();
for(File f : files) {
if(f.isDirectory()) {
showDir(f, level);
} else {
out(getLevel(level) + f.getName());
}
}
}
//输出
public static void out(Object obj) {
System.out.println(obj);
}
}
三、打印流
该流可以打印各种类型的数据1、PrintStream 字节打印流
构造方法参数:
(1)、File
(2)、字符串路径
(3)、字节输出流 OutputStream
2、PrintWriter 字符打印流
构造方法参数:
(1)、File
(2)、字符串路径
(3)、字节输出流 OutputStream
(4)、字符输出流 Writer
实例:
import java.io.*;
class PrintStreamDemo
{
public static void main(String[] args) throws IOException
{
BufferedReader bufr =
new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(new FileWriter("a.txt"),true);
String line = null;
while((line=bufr.readLine())!=null)
{
if("over".equals(line))
break;
out.println(line.toUpperCase());
//out.flush();
}
out.close();
bufr.close();
}
}
分割图片
import java.io.*;
import java.util.*;
class SplitFile
{
public static void main(String[] args) throws IOException
{
//splitFile();
merge();
}
public static void merge()throws IOException
{
ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
for(int x=1; x<=3; x++)
{
al.add(new FileInputStream("c:\\splitfiles\\"+x+".part"));
}
final Iterator<FileInputStream> it = al.iterator();
Enumeration<FileInputStream> en = new Enumeration<FileInputStream>()
{
public boolean hasMoreElements()
{
return it.hasNext();
}
public FileInputStream nextElement()
{
return it.next();
}
};
SequenceInputStream sis = new SequenceInputStream(en);
FileOutputStream fos = new FileOutputStream("c:\\splitfiles\\0.bmp");
byte[] buf = new byte[1024];
int len = 0;
while((len=sis.read(buf))!=-1)
{
fos.write(buf,0,len);
}
fos.close();
sis.close();
}
public static void splitFile()throws IOException
{
FileInputStream fis = new FileInputStream("c:\\1.bmp");
FileOutputStream fos = null;
byte[] buf = new byte[1024*1024];
int len = 0;
int count = 1;
while((len=fis.read(buf))!=-1)
{
fos = new FileOutputStream("c:\\splitfiles\\"+(count++)+".part");
fos.write(buf,0,len);
fos.close();
}
fis.close();
}
}
SequenceInputStream合并文件
import java.io.*;
import java.util.*;
class SequenceDemo
{
public static void main(String[] args) throws IOException
{
Vector<FileInputStream> v = new Vector<FileInputStream>();
v.add(new FileInputStream("c:\\1.txt"));
v.add(new FileInputStream("c:\\2.txt"));
v.add(new FileInputStream("c:\\3.txt"));
Enumeration<FileInputStream> en = v.elements();
SequenceInputStream sis = new SequenceInputStream(en);
FileOutputStream fos = new FileOutputStream("c:\\4.txt");
byte[] buf = new byte[1024];
int len =0;
while((len=sis.read(buf))!=-1)
{
fos.write(buf,0,len);
}
fos.close();
sis.close();
}
}
IO包中其他流
一、对象持久化
1、将Person对象写到文件
Person:
import java.io.*;
class Person implements Serializable
{
public static final long serialVersionUID = 42L;
private String name;
transient int age;
static String country = "cn";
Person(String name,int age,String country)
{
this.name = name;
this.age = age;
this.country = country;
}
public String toString()
{
return name+":"+age+":"+country;
}
}
ObjectStreamDemo:
import java.io.*;
class ObjectStreamDemo
{
public static void main(String[] args) throws Exception
{
//writeObj();
readObj();
}
public static void readObj()throws Exception
{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt"));
Person p = (Person)ois.readObject();
System.out.println(p);
ois.close();
}
public static void writeObj()throws IOException
{
ObjectOutputStream oos =
new ObjectOutputStream(new FileOutputStream("obj.txt"));
oos.writeObject(new Person("lisi0",399,"kr"));
oos.close();
}
}
二、管道流
import java.io.*;
class Read implements Runnable
{
private PipedInputStream in;
Read(PipedInputStream in)
{
this.in = in;
}
public void run()
{
try
{
byte[] buf = new byte[1024];
System.out.println("读取前。。没有数据阻塞");
int len = in.read(buf);
System.out.println("读到数据。。阻塞结束");
String s= new String(buf,0,len);
System.out.println(s);
in.close();
}
catch (IOException e)
{
throw new RuntimeException("管道读取流失败");
}
}
}
class Write implements Runnable
{
private PipedOutputStream out;
Write(PipedOutputStream out)
{
this.out = out;
}
public void run()
{
try
{
System.out.println("开始写入数据,等待6秒后。");
Thread.sleep(6000);
out.write("piped lai la".getBytes());
out.close();
}
catch (Exception e)
{
throw new RuntimeException("管道输出流失败");
}
}
}
class PipedStreamDemo
{
public static void main(String[] args) throws IOException
{
PipedInputStream in = new PipedInputStream();
PipedOutputStream out = new PipedOutputStream();
in.connect(out);
Read r = new Read(in);
Write w = new Write(out);
new Thread(r).start();
new Thread(w).start();
}
}
三、RandomAccessFile对数据的随机访问
import java.io.*;
/*
RandomAccessFile
该类不是算是IO体系中子类。
而是直接继承自Object。
但是它是IO包中成员。因为它具备读和写功能。
内部封装了一个数组,而且通过指针对数组的元素进行操作。
可以通过getFilePointer获取指针位置,
同时可以通过seek改变指针的位置。
其实完成读写的原理就是内部封装了字节输入流和输出流。
通过构造函数可以看出,该类只能操作文件。
而且操作文件还有模式:只读r,,读写rw等。
如果模式为只读 r。不会创建文件。会去读取一个已存在文件,如果该文件不存在,则会出现异常。
如果模式rw。操作的文件不存在,会自动创建。如果存则不会覆盖。
*/
class RandomAccessFileDemo
{
public static void main(String[] args) throws IOException
{
//writeFile_2();
//readFile();
//System.out.println(Integer.toBinaryString(258));
}
public static void readFile()throws IOException
{
RandomAccessFile raf = new RandomAccessFile("ran.txt","r");
//调整对象中指针。
//raf.seek(8*1);
//跳过指定的字节数
raf.skipBytes(8);
byte[] buf = new byte[4];
raf.read(buf);
String name = new String(buf);
int age = raf.readInt();
System.out.println("name="+name);
System.out.println("age="+age);
raf.close();
}
public static void writeFile_2()throws IOException
{
RandomAccessFile raf = new RandomAccessFile("ran.txt","rw");
raf.seek(8*0);
raf.write("周期".getBytes());
raf.writeInt(103);
raf.close();
}
public static void writeFile()throws IOException
{
RandomAccessFile raf = new RandomAccessFile("ran.txt","rw");
raf.write("李四".getBytes());
raf.writeInt(97);
raf.write("王五".getBytes());
raf.writeInt(99);
raf.close();
}
}
四、操作基本数据类型流
DataInputStream和DataOutputStream
/*
DataInputStream与DataOutputStream
可以用于操作基本数据类型的数据的流对象。
*/
import java.io.*;
class DataStreamDemo
{
public static void main(String[] args) throws IOException
{
//writeData();
//readData();
//writeUTFDemo();
// OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("gbk.txt"),"gbk");
//
// osw.write("你好");
// osw.close();
// readUTFDemo();
}
public static void readUTFDemo()throws IOException
{
DataInputStream dis = new DataInputStream(new FileInputStream("utf.txt"));
String s = dis.readUTF();
System.out.println(s);
dis.close();
}
public static void writeUTFDemo()throws IOException
{
DataOutputStream dos = new DataOutputStream(new FileOutputStream("utfdate.txt"));
dos.writeUTF("你好");
dos.close();
}
public static void readData()throws IOException
{
DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
int num = dis.readInt();
boolean b = dis.readBoolean();
double d = dis.readDouble();
System.out.println("num="+num);
System.out.println("b="+b);
System.out.println("d="+d);
dis.close();
}
public static void writeData()throws IOException
{
DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));
dos.writeInt(234);
dos.writeBoolean(true);
dos.writeDouble(9887.543);
dos.close();
ObjectOutputStream oos = null;
oos.writeObject(new O());
}
}
五、操作数组流
ByteArrayInputStream和ByteArrayOutputStream
/*
用于操作字节数组的流对象。
ByteArrayInputStream :在构造的时候,需要接收数据源,。而且数据源是一个字节数组。
ByteArrayOutputStream: 在构造的时候,不用定义数据目的,因为该对象中已经内部封装了可变长度的字节数组。
这就是数据目的地。
因为这两个流对象都操作的数组,并没有使用系统资源。
所以,不用进行close关闭。
在流操作规律讲解时:
源设备,
键盘 System.in,硬盘 FileStream,内存 ArrayStream。
目的设备:
控制台 System.out,硬盘FileStream,内存 ArrayStream。
用流的读写思想来操作数据。
*/
import java.io.*;
class ByteArrayStream
{
public static void main(String[] args)
{
//数据源。
ByteArrayInputStream bis = new ByteArrayInputStream("ABCDEFD".getBytes());
//数据目的
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int by = 0;
while((by=bis.read())!=-1)
{
bos.write(by);
}
System.out.println(bos.size());
System.out.println(bos.toString());
// bos.writeTo(new FileOutputStream("a.txt"));
}
}
六、字符转换流
InputStreamReader和OutputStreamWriter
注意:中文GBK两个八位,最高位为1,也就是两个负数
编码实例1:
/*
编码:字符串变成字节数组。
解码:字节数组变成字符串。
String-->byte[]; str.getBytes(charsetName);
byte[] -->String: new String(byte[],charsetName);
*/
import java.util.*;
class EncodeDemo
{
public static void main(String[] args)throws Exception
{
String s = "哈哈";
byte[] b1 = s.getBytes("GBK");
System.out.println(Arrays.toString(b1));
String s1 = new String(b1,"utf-8");
System.out.println("s1="+s1);
//对s1进行iso8859-1编码。
byte[] b2 = s1.getBytes("utf-8");
System.out.println(Arrays.toString(b2));
String s2 = new String(b2,"gbk");
System.out.println("s2="+s2);
}
}
编码实例2:记事本里面直接输入联通,打开乱码
这是因为将联通两个字编码后正好符合UTF-8读取规则,所以记事本将该文件识别成UTF-8格式,但是其实这个文件是GBK的,所以最后导致乱码
补充:UTF-8读取规则(在API,DataInputStream接口中,readUTF方法中)
开头为0,一个八位
开头为110,两个八位
开头为1110,三个八位
class EncodeDemo2
{
public static void main(String[] args) throws Exception
{
String s = "联通ͨ";
byte[] by = s.getBytes("gbk");
for(byte b : by)
{
System.out.println(Integer.toBinaryString(b&255));
}
System.out.println("Hello World!");
}
}
字符编码3:编码转换
import java.io.*;
class EncodeStream
{
public static void main(String[] args) throws IOException
{
//writeText();
readText();
}
public static void readText()throws IOException
{
InputStreamReader isr = new InputStreamReader(new FileInputStream("utf.txt"),"gbk");
char[] buf = new char[10];
int len = isr.read(buf);
String str = new String(buf,0,len);
System.out.println(str);
isr.close();
}
public static void writeText()throws IOException
{
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("utf.txt"),"UTF-8");
osw.write("你好");
osw.close();
}
}