|
(1)FileInputStream/FileOutputStream
1.FileInputStream(文件输入流(由文件输入到计算机))
2.FileOutputStream(文件输出流(由计算机输出到文件))
FileInputStream/FileOutputStream分别扩展于InputStream/OutputStream,并将read和write方法重写了。
package unite_9;
import java.io.*;
public class TestFileIOStream {
public static void main(String[] args)
{
File f = new File("test.txt");
try
{
FileOutputStream fos = new FileOutputStream(f);
String info = "java 笔记";//不是说Java里面char 代表两个字节么为什么返回长度是8,info.length获得的不是存储空间的大小,而是字符个数,此外存储的大小是和字符 集有关的,选择的字符集不用来存储每个符号的空间大小不同,字符集可以自己选择,一般使用默认值,在没有自我选择的情况下。
fos.write(info.getBytes());//这里是将info以byte的形式输入到文件中去
fos.close();
System.out.println(info.length());
FileInputStream fis = new FileInputStream(f);
byte[] binfo = new byte[8];
String single;
int len;
while((len = fis.read(binfo))>0)//这里read(binfo)指的是将文件里面的内容读到binfo这个数组里面来,如果文件里面的内容小于数组binfo的内容则会在后面输出的info中出现乱码,返回的长度为什么可以不断变化
{
single = new String(binfo,0,len);//我不理解这里是怎么赋值的
info = info + single;
System.out.println(len);
System.out.println(info.length());
}
System.out.println(len);
fis.close();
System.out.println(info);
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
(2)BufferedInputStream/BufferedOutputStream
package unite_9;
import java.io.*;
public class TestBufferIOStream {
public static void main(String[] args)
{
File f = new File("test.txt");
try{
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(f));
String info="现在是测试缓冲区";
bos.write(info.getBytes(),0,info.length()*2);//info.length获得的不是存储空间的大小,而是字符个数,而Java是每个字符存储两个字节的。
bos.flush();//这里是将缓冲区的所有数据发送到目的地,并且清空缓冲区
bos.close();
info="";
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f));
String single;
byte[] binfo = new byte[1024];
int len;
while((len = bis.read(binfo))>0)//这里是从缓冲区读取数据,放入到binfo中,我很好奇是在哪一步将文件中的内容放到了缓冲区
{
//System.out.println(info);
single = new String(binfo,0,len);
info = info + single;
}
bis.close();
System.out.println(info);
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
(3)DateInputStream/DateOutputStream、
采用普通流对数据进行读写需要先对数据进行转换,这两个流是为了简化数据的读取操作
1.DateInputStream主要方法
int read(byte[] b) | //从输入流中读入一定数量的字节,并且将它们存储到缓冲区数组b中 |
int read(byte[] b,int off,int len) | 读最多len个字节
|
boolean readBoolean() | //其他的形式都和这个类似 |
数据类型 read数据类型() | //功能读取该数据类型大小的字节,并且返回该数据类型的值 |
void readFully(byte[] b) | //从输入流中读入一定数量的字节,并且将它们存储到缓冲区数组b中 |
void readFully(byte[] b,int off,int len) | 读len个字节
|
String readUTF() | //如果读到的数据类型不匹配会抛出UTFDateFormatException
|
2.DateOutputStream主要方法
void write(int b) |
|
void write(byte[] b,int off,int len) |
|
void writeBoolean(Boolean v ) |
|
数据类型 write数据类型(数据类型) | //将一个该类型的值以该类型的大小写入基础输出流
|
Void writeDouble(double v) | //用Double类中的doubleToLongBits方法将double参数转换为一个long值,然后将该long值以8-bit值的形式写入基础输出流中,先写入高字节。 |
void writeUTF(String str)
|
|
import java.io.*;
public class TestDataIOStream {
public static void main(String[] args)
{
try{
DataOutputStream dos = new DataOutputStream(new FileOutputStream(new File("test.txt")));//基于FileOutputStream流的DataOutputStream对象,为什么要基于文件流,不能直接打开文件?
dos.writeInt(123);
dos.writeFloat(397.9f);
dos.writeUTF("测试数据输入输出流");
dos.close();
DataInputStream dis = new DataInputStream(new FileInputStream(new File("test.txt")));
System.out.println("读出的整数: "+dis.readInt());//要按照输入的顺序读出
System.out.println("读出的小数: "+dis.readFloat());
System.out.println("读出的字符串: "+dis.readUTF());
dis.close();
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
(4)ObjectInputStream/ObjectOutputStream
对于可序列化的对象进行输入输出
import java.io.*;
class Point1 implements Serializable
{
private int x;
private int y;
public Point1()
{
x=3;
y=4;
}
public void set(int x,int y)
{
this.x=x;
this.y=y;
}
public String toString()
{
String str="x="+x+",y="+y;
return str;
}
}
public class TestObjectIOStream {
public static void main(String[] args)
{
try{
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("test.txt")));//注意这里也是三个new
Point1 p= new Point1();
oos.writeObject(p);
oos.close();
p = null;
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("test.txt")));
System.out.println(ois.readObject());
ois.close();
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
(5)ByteArrayInputStream/ByteArrayOutputStream
通常在需要先对数据进行处理后再执行其他操作时,可以通过这个输入输入流来实现
坦白说看完这个的代码后我觉得将这里接受输入输出的流的对象改为 字符串也是没有问题的,这个东西的独特和方便之处在哪里!!!
可能主要是和写入文件的流相比这个不用写入文件就可以把字节给处理了,那什么加密解密的代码我自己就没有手打了。而且加密解密代码还有点问题,我晕。
import java.io.*;
class ByteArrayStream
{
// 加密
public void encrypt(InputStream in, OutputStream out)
{
try
{
int c = 0;
int ec = 0;
while((c = in.read()) != -1)
{
if(c >= 'A' && c <= 'Z')
{
ec = (c - 'A' + 4) % 26 + 'A';
}
else if(c >= 'a' && c <= 'z')
{
ec = (c - 'a' + 4) % 26 + 'a';
}
else if(c >= '0' && c <= '9')
{
ec = (c - '0' + 4) % 10 + '0';
}
else
{
ec = c;
}
out.write(ec);//读完一个字节就输出一个字节
}
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
}
// 解密
public void decrypt(InputStream in, OutputStream out)
{
try
{
int c = 0;
int ec = 0;
while((c = in.read()) != -1)
{
if(c >= 'A' && c <= 'Z')
{
ec = (c - 4 - 'A') % 26 + 'A';
}
else if(c >= 'a' && c <= 'z')
{
ec = (c - 4 - 'a') % 26 + 'a';
}
else if(c >= '0' && c <= '9')
{
ec = (c - 4 - '0') % 10 + '0';
}
else
{
ec = c;
}
out.write(ec);
}
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
public class TestByteArrayIOStream {
public static void main(String[] args)
{
try
{
String str = "test the ByteArrayIOStream!";
System.out.println("the origin string:"+str);
ByteArrayInputStream bais = new ByteArrayInputStream(str.getBytes());
ByteArrayOutputStream bao = new ByteArrayOutputStream();
ByteArrayStream bas = new ByteArrayStream();
bas.encrypt(bais, bao);
String str2 = bao.toString();
System.out.println("the String which has been encrypted:"+bao);
bais.close();
bao.close();
bais = new ByteArrayInputStream(str2.getBytes());
bao = new ByteArrayOutputStream();
bas.decrypt(bais, bao);
System.out.println("the String which has been decrypted:"+bao);
bais.close();
bao.close();
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
(6)PushbackInputStream
我很想知道这个所谓的流是放在哪里了
功能是将已经从流中读取的字符节“回退”到流中,退回的字节可以再次被读取。实际上是回退到该流的缓冲区中,该流的读取和回退数据均是基于缓冲区完成的
其他有用特性:
可以先预览流中的数据,根据预览结果进行后续操作
在需要分隔数据的时候,先依次读入流中的字节,当发现的读入的字节属于下一单元时可以将读入的字节退回到流中,以免读取下一个数据单元不全。
有三个重载方法
void unread(byte[] b) | 将数组b中的所有字节回退到PushbackInputStream对象的缓冲区前部 |
void unread(byte[] b,int off,int len) | 将该数组指定偏移量处开始的若干个字节回退到PushbackInputStream对象的缓冲区前部 |
void unread(int b) | 将一个字节、字符推回到缓冲区? |
import java.io.*;
public class TestPushBackStream {
public static void main(String[] args)//主方法里面不能有方法
{
try
{
TestPushBackStream pist = new TestPushBackStream();
PushbackInputStream pis = new PushbackInputStream(new FileInputStream(new File("work.txt")));
String info;
do
{
info = pist.readWord(pis);
System.out.println(info);
}while(info.length()>0);
pis.close();
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public String readWord(PushbackInputStream pis)
{
// skipSpace(pis); //感觉这个功能有点费,于是把它注释了,输出结果一样,因为如果一旦读过但是却不输出的话指针也是会往后面走的,所以就没有必要专门写一个函数来跳过空格了。
try{
int ch = -1;
StringBuffer sb = new StringBuffer();
while((ch = pis.read()) >= 0)//如果这个字符不是空白字符就赋值到sb直到空白字符出现,而且我无语的发现这个声称是处理字节的函数,分明可以处理字符,按照输出结果像是以字符为输出单位
{
// System.out.println((char)ch);
if(Character.isWhitespace(ch))
{
break;
}
else
{
sb.append((char)ch);
}
}
return sb.toString();
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
return "";
}
public void skipSpace(PushbackInputStream pis) {
try
{
int ch = -1;
while((ch = pis.read())>=0)//如果这个不是空白字符就将字符退回并退出,这里主要是为了告诉我们虽然是读了,但是仍然是可以退回去的,因为输出很明显是读过的数据打头。
{
if(!Character.isWhitespace(ch))
{
pis.unread(ch);
break;
}
}
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
一、字符流
如果以一个字符的长度(两个字节)为单位来处理流中的数据,则可以将流称为“字符流”。
使用字符流的方式来处理可以对流中的字符进行适当的字符编码转换处理,以便让字符能够以正确的形式进行显示或者存储。
(1)Reader/Writer
这两个类是抽象类也是其他字符流处理类的父类,他们的主要方法挺多的,主要的是
Reader: read(char[],int,int)
close();
Writer: write(char[],int,int)
flush();
close();
(2)InputStreamReader/OutputStreamWriter
1,InputStreamReader(字节流向字符的桥梁)
使用指定的字符集并将其解码为字符,它使用的字符集可以在构造器中通过字符型的名称指定或显示的给定字符集,或者它也可以接受平台默认字符集,默认为G2312
2,OutputStreamWriter(字符流向字节的桥梁)
它可以使用指定的字符集将要写入流的字符编码成字节。字符集可默认或指定(指定方式和inputstreamreader一样)。默认为G2312
import java.io.*;
public class TestIOStreamRW {
public static void main(String[] args)
{
try
{
int ch;
InputStreamReader isr = new InputStreamReader(System.in);//scanner那里也用过
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(new File("test.txt")));
while((ch = isr.read())>0)
{
osw.write(ch);
}
isr.close();
osw.close();
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
(3)FileReader/FileWriter
以上两个类分别继承了InputStreamReader/OutputStreamWriter。然后提供了数个重载的构造器,没有重写或者添加其他方法。
本人暂时不会使用
(4)BufferedReader/BufferedWriter
下面的代码建立了test2并将test中的内容复制到了test2中
import java.io.*;
public class TestBufferedReaderWriter {
public static void main(String[] args)
{
int ch;
try{
BufferedReader br = new BufferedReader(new FileReader(new File("test.txt")));
BufferedWriter bw = new BufferedWriter(new FileWriter(new File("test2.txt")));
while((ch=br.read())!=-1)
{
bw.write(ch);
}
br.close();//没有close text的内容就没有复制过去
bw.close();//没有close text的内容就没有复制过去
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
(5)PrintWriter
很方便。
import java.io.*;
public class TestPrintWriter {
public static void main(String[] args)
{
try
{
PrintWriter pw = new PrintWriter(new File("test.txt"));
pw.print(true);
pw.print("i am coming to test the PrintWriter.");
pw.write("me either");
pw.close();
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
习题:
1.编程实现文件的复制功能,要求源文件名及目标文件名在程序运行后根据提示输入
2.编制程序,当程序运行时,首先询问输入数据的个数,然后依次输入指定个数的整数,输入完毕后,输出所有的输入整数和平均值
3.加密,解密
小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)
GMT+8, 2024-5-17 13:24
Powered by Discuz! X3.4
© 2001-2023 Discuz! Team.