java基础:关于java流与文件操作

1、描述:流是字节数据或字符数据序列。Java采用输入流对象和输出流对象来支持程序对数据的输入和输出。输入流对象提供了数据从源点流向程序的管道,程序可以从输入流对象读取数据;输出流对象提供了数据从程序流向终点的管道,程序通过该管道把数据写到终点。所有的关于输入/输出的类都包含在java.io的包中。
2、File类:它主要关心的是文件的具体属性,而非内容,定义了许多方法,实现对文件的创建、删除等操作。
code:
import java.io.*;
public class Test
{
 public static void main(String args[])throws Exception
 {
  File file1=new File("w1.txt");//在当前目录下
  file1.createNewFile();//得到文件w1.txt
  file1.mkdir();//得到目录w1.txt
  File file2=new File("D:\\javaprogram\\text\\w2.txt");//指定目录
  file2.createNewFile();//得到文件w2.txt
  //用静态字段separator获得系统分隔符,保证程序通用性
  File fDir=new File(File.separator);//作为字符是‘\‘,作为File对象为当前根目录
  String fStr="javaprogram"+File.separator+"text"+File.separator+"w3.txt";
  File file3=new File(fDir,fStr);
  file3.createNewFile();//得到文件w3.txt
  file1.delete();
  file2.delete();
  file3.delete();
  //delete()方法删除文件,调用即删除,而deleteOnExit()是在JVM终止时才删除
  //这样就得以建立临时文件以存储临时数据,临时文件保存在临时文件夹
  //要找临时文件夹,请查看环境变量temp的设置
  for(int i=0;i<5;i++)
  {
   File file=File.createTempFile("wang",".temp");
   file.deleteOnExit();
  }
  Thread.sleep(3000);
  //下面的一段程序将实现,打印指定目录下的.java文件的信息
  File f=new File("d:\\javaprogram");
  if(f.exists())//判断文件是否存在
  {
   if(f.isDirectory())//判断文件是目录还是标准文件
   {
    //调用带参数的listFiles()方法返回满足特定过虑器的
    //此抽象路径名所表示目录中的文件和目录的抽象路径名数组
    File[] fname=f.listFiles(new FilenameFilter()
    {
     //匿名类实现接口FilenameFileter的唯一方法
     public boolean accept(File dir, String name) 
     {
      return name.indexOf(".java")!=-1;
     }
    });
    for(int i=0;i<fname.length;i++)
    {
     System.out.println(fname[i]);
    }
   }
  }
  else
  {
   System.out.println("文件夹不存在.");
  }
 }
}

3、字节流:
程序运行中常的I/O操作包括向标准设备输入输出数据和文件输入输出。对于前者,java定义了三个直接使用的流对象:System.err(标准错误输出)、System.out(标准输出)和System.in(标准输入);对于后者,可以使用FileOutputStream和FileInputStream。
code:
import java.io.*;
public class Test
{
 static final String file1="D:\\javaprogram\\w1.txt";
 static final String file2="E:\\database\\w2.txt";
 static final String file3="E:\\wmpub\\w3.txt";
 public static void main(String args[])throws IOException
 {
  /*//关于System.in
  int data;
  while ((data=System.in.read())!=-1)//Ctrl+c结束输入
  {
   System.out.write(data);
  }*/
  //下面的程序段用以向file1文件写入,把其内容的一部分复制到file2
  //再把file2文件完整地复制到file3,并打印出来
  FileOutputStream fos1=new FileOutputStream(file1);
  FileOutputStream fos2=new FileOutputStream(file2);
  FileOutputStream fos3=new FileOutputStream(file3);
  fos1.write("今天是2008年8月3号,离北京奥运会还有5天,心里非常激动啊.".getBytes());
  fos1.close();
  FileInputStream fis1=new FileInputStream(file1);
  fis1.skip(19);//跳过19个字节
  byte[] buf=new byte[fis1.available()];
  fis1.read(buf);
  fis1.close();
  System.out.println(new String(buf));
  fos2.write(buf);
  fos2.close();
  FileInputStream fis2=new FileInputStream(file2);
  while(fis2.available()>0)
  {
   byte[] b=new byte[fis2.available()];
   int let=fis2.read(b);
   if(let==-1)break;
   fos3.write(b,0,let);
  }
  System.out.println("复制成功!");
  fis2.close();
  fos3.close();
  //以下程序段实现了一个图像文件的复制
  FileInputStream a=new FileInputStream("4.jpg");
  FileOutputStream b=new FileOutputStream("3.jpg");
  byte c[]=new byte[a.available()];
  a.read(c);
  b.write(c);
  a.close();
  b.close();
 }
}

4、字符流(FileWriter and FileReader)

import java.io.*;
public class Test
{
 public static void main(String args[])
 {
  //本程序完成从控制台读入文件名,并实现复制
  int length;
  char buf[]=new char[100];
  try
  {
   FileReader in=new FileReader(args[0]);
   FileWriter out=new FileWriter(args[1]);
   length=in.read(buf);
   while(length!=-1)
   {
    out.write(buf,0,length);
    //字符流读取通过read()的返回值判断是否读到文件末尾
    //我刚才忘记加这条语句,文件被一直写,都死机了,重启后一看,写了2.6G
    length=in.read(buf);
   }
   in.close();
   out.close();
  }
  catch (IOException e)
  {
   e.printStackTrace();
  }
 }

5、过滤流之一
    Java利用过滤流可以在读写数据的同时对数据进行处理,以达到性能的改善,提高程序执行效率。将过滤流和某个输入流或输出流(节点流)连接。连接是通过在过滤流的构造方法中指定入口参数——节点流来实现的。
  §BufferedInputStream:
                        FileInputStream fis=new FileInputStream("w1.txt");
                        BufferedInputStream bis=new BufferedInputStream(fis);
                        byte[] buf=new byte[100];
                        int len=bis.read(buf,0,len);
                        System.out.println(new String(buf,0,len));
                        bis.close();
        §BufferedOutputStream:
                        FileOutStream fos=new FileOutputStream("w2.txt");
                        BufferedOutputStream bos=new BufferedOutputStream(bos);
                        bos.write("好好学习,天天向上".getBytes());
                        bos.flush();
                        bos.close();
    也可以是匿名创建:如:BufferedOutputStream bos=new BufferedOutputStream(new FileInputStream("w2.txt")); 
     BufferedReader和BufferedWirter与此类似,不过是分别指定Writer和Reader类型的参数罢了。
一个实例程序:
import java.io.*;
public class Test
{
 public static void main(String[] args)
 {
  try
  {
   FileInputStream in=new FileInputStream(args[0]);
   BufferedInputStream bufIn=new BufferedInputStream(in);
   int limit;
   bufIn.mark(limit=bufIn.available());//在当前位置打上标记
   for(int i=0;i<limit;i++)
    System.out.print((char)(bufIn.read()));
   System.out.println();
   bufIn.reset();//reset缓冲区标志
   int c;
   while((c=bufIn.read())>=0)System.out.print((char)c);
   bufIn.close();
  }
  catch (IOException e)
  {
   e.printStackTrace();
  }
 }
}

5、过滤流之二基本类型数据传输:DataInputStream和DataOutputStream
import java.io.*;
public class Test
{
 public static void main(String args[])
 {
  try
  {
   DataOutputStream dos=new DataOutputStream(
    new BufferedOutputStream(new FileOutputStream(
     "d://javaprogram//w.txt")));
   dos.writeInt(5);
   dos.writeUTF("你好");
   dos.writeBoolean(true);
   dos.writeDouble(3.1415926);
   dos.writeBytes("ok!");
   dos.writeChars("bye bye");
   dos.close();
   DataInputStream dis=new DataInputStream(
    new BufferedInputStream(new FileInputStream(
        "d://javaprogram//w.txt")));
   //读出的顺序应与写入的顺序一致
   System.out.println(dis.readInt());
   System.out.println(dis.readUTF());
   System.out.println(dis.readBoolean());
   System.out.println(dis.readDouble());
   byte b[]=new byte[3];
   dis.readFully(b);
   for(int j=0;j<3;j++)System.out.print((char)b[j]);
   System.out.println();
   StringBuffer st3=new StringBuffer();
   for(int j=0;j<7;j++)st3.append(dis.readChar());
   System.out.println(st3.toString());
   dis.close();
  }
  catch (IOException e)
  {
   System.err.println(e.toString());
  }
 }
}
6、过滤流之三:I/O流的链接图:
  
7、字节和Unicode字符的桥梁:InputStreamReader、OutputStreamWriter
code:
import java.io.*;
public class Test
{
 public static void main(String[] args)throws IOException
 {
  //文件读写
  FileOutputStream fos=new FileOutputStream("w.txt");
  OutputStreamWriter osw=new OutputStreamWriter(fos);
  BufferedWriter bw=new BufferedWriter(osw);
  bw.write("今天是2008年8月3日,离北京奥运还有5天!");
  bw.close();
  FileInputStream fis=new FileInputStream("w.txt");
  InputStreamReader isr=new InputStreamReader(fis);
  BufferedReader br=new BufferedReader(isr);
  System.out.println(br.readLine());
  br.close();
  //控制台读写
  BufferedReader br1=new BufferedReader(new InputStreamReader(System.in));
  BufferedWriter bw1=new BufferedWriter(new OutputStreamWriter(System.out));
  String strLine,str="";
  while((strLine=br1.readLine())!=null)//Ctrl+c结束输入
  {
   str+=strLine;
   System.out.println(strLine);
  }
  br1.close();
  bw1.write(str,0,str.length());
  bw1.write((int)(‘\n‘)); //将回车符输入bw1
  bw1.flush();
  bw1.close();
 }
}
8、管道流:PipedInputStream、PipedOutputStream
      作用:用于线程间的通信,一个线程的pipedInputStream对象从另一个线程的PipedOutputStream对象读取输入,要使管道流有用,必须同时构造管道输入流和管道输出流。
例子(孙鑫老师的例子):
import java.io.*;
class Producer extends Thread
{
 private PipedOutputStream pos;
 public Producer(PipedOutputStream pos)
 {
  this.pos=pos;
 }
 public void run()
 {
  try
  {
   pos.write("Hello,welcome you!".getBytes());
  }
  catch (Exception e)
  {
   e.printStackTrace();
  }
 }
}
class Consumer extends Thread
{
 private PipedInputStream pis;
 public Consumer(PipedInputStream pis)
 {
  this.pis=pis;
 }
 public void run()
 {
  try
  {
   byte[] buf=new byte[100];
   int len=pis.read(buf);
   System.out.println(new String(buf,0,len));
   pis.close();
  }
  catch (Exception e)
  {
   e.printStackTrace();
  }
 }
}
public class Test
{
 public static void main(String args[])
 {
  PipedOutputStream pos=new PipedOutputStream();
  PipedInputStream pis=new PipedInputStream();
  try
  {
   pos.connect(pis);
   new Producer(pos).start();
   new Consumer(pis).start();
  }
  catch (Exception e)
  {
   e.printStackTrace();
  }
 }
}
9、PrintWriter类:创建的输出流可以使用print和println方法,按Unicode字符形式输出,输出的数据可读性较好。
        §打印流建立文本文件:
                                PrintWriter out=new PrintWriter(new FileWriter(1.dat));
                                String str="天呢,我告诉你吧:";
                                char[] z={‘北‘,‘京‘,‘奥‘,‘运‘,‘会‘,‘在‘};double g=2008;
                                out.println(st);out.print(z);out.print(g);out.println("年08月08日08时08分08秒");
                                out.close();
        §打印流在屏幕上显示文本
                                PrintWriter out=new PrintWriter(System.out);
                                其余同上,此处略
10、文件的随机读写:RandomAccessFile
import java.io.*;
public class Test
{
 public static void main(String args[])throws Exception
 {
  int lineNo;//读到的行号
  long fp;//文件指针
  BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
  RandomAccessFile raf=new RandomAccessFile("w.txt","rw");
  System.out.println("请输入6个字符串");
  int[] len=new int[12];
  String[] str=new String[12];
  for(int i=0;i<6;i++)
  {
   System.out.println("行号"+(i+1)+":");
   str[i]=br.readLine();
   len[i]=str[i].length();
   raf.write((str[i]+"\n").getBytes());
  }
  while(true)
  {
   fp=0;
   raf.seek(0);
   System.out.println("你要显示第几行?"+"(1--6)");
   lineNo=Integer.parseInt(br.readLine());
   for(int i=1;i<lineNo;i++)
    fp=fp+(long)len[i-1]+1;
   raf.seek(fp);
   System.out.println("第"+lineNo+"行"+":"+raf.readLine());
   System.out.println("继续吗?"+"(y/n)");
   if((br.readLine().equals("n")))break;
  }
  raf.seek(raf.length());
  System.out.println("继续写入6行数据:");
  for(int i=6;i<12;i++)
  {
   System.out.println("行号"+(i+1)+":");
   str[i]=br.readLine();
   len[i]=str[i].length();
   raf.write((str[i]+"\n").getBytes());
  }
  System.out.println("打印12行数据:");
  raf.seek(0);
  for(long i=0;i<raf.length();i=raf.getFilePointer())
  {
   System.out.println(raf.readLine());
  }
  raf.close();
 }
}
11、文件的压缩处理
 实例:
import java.io.*;
import java.util.*;
//ZipInputStream和ZipOutputStream在包java.util.zip中
import java.util.zip.*;
public class Test
{
 public static void main(String args[])throws Exception
 {
  //输入若干文件名,将所有文件压缩为w.zip
  ZipOutputStream zos=new ZipOutputStream(
   new BufferedOutputStream(new FileOutputStream("w.zip")));
  for(int i=0;i<args.length;i++)
  {
   BufferedInputStream bis=new BufferedInputStream(
    new FileInputStream(args[i]));
   //将每个要压缩的文件称为一个压缩入口,使用ZipEntry生成压缩入口对象
   //使用putNextEntry(ZipEntry entry)将压缩入口加入到压缩文件
   zos.putNextEntry(new ZipEntry(args[i]));
   int b;
   while((b=bis.read())!=-1)
    zos.write(b);
   bis.close();
  }
  zos.close();
  //解压缩文件并显示
  ZipInputStream zis=new ZipInputStream(
   new BufferedInputStream(new FileInputStream("w.zip")));
  ZipEntry z;
  while((z=zis.getNextEntry())!=null)//获得入口
  {
   System.out.println(z.getName());//显示文件初始名
   int x;
   while((x=zis.read())!=-1)
    System.out.write(x);
   System.out.println();
  }
  zis.close();
 }
}
12、编码与解码
 import java.util.*;
import java.nio.charset.*;
public class Test
{
 public static void main(String args[])throws Exception
 {
  //以下程序段打印当前计算机所能处理的标准 charset
  //Charset类位于java.nio.charset包中,此类定义了用于创建解码器和编码器
  //以及检索与 charset 关联的各种名称的方法。此类的实例是不可变的。
  //Charset.availableCharsets()返回一个映射
  //Map是java.util包中的一个接口
  Map m=Charset.availableCharsets();
  //keySet()方法返回此映射中包含的键的 set 视图
  Set names=m.keySet();
  //构造迭代器访问诸元素
  Iterator it=names.iterator();
  while(it.hasNext())
  {
   System.out.println(it.next());
  }
  //Properties 类位于java.util包中,表示了一个持久的属性集
  //System.getProperties()确定当前的系统属性。
  Properties pps=System.getProperties();
  pps.list(System.out);//打印属性
  //将系统文件的标准字符集改为:ISO-8859-1
  //设置的字符集,只是当前JVM上的字符集
  pps.put("file.encoding","ISO-8859-1");
  int data;
  byte[] buf=new byte[100];
  int i=0;
  while((data=System.in.read())!=‘q‘)
  {
   buf[i]=(byte)data;
   i++;
  }
  String str=new String(buf,0,1);
  System.out.println(str);
  //ISO-8859-1字符解码为Unicode字符(java使用)
  //Unicode字符编码为GBK字符
  //但并不是所有字符都能反编码回来,比如汉字将丢失高字节
  String strGBK=new String(str.getBytes("ISO-8859-1"),"GBK");
  System.out.println(strGBK);
 }

13、对象序列化
               对象的寿命常随着对象的程序的终止而终止,倘若需要对对象的状态进行保存,需要时再恢复。我们把对象的这种能够记录自己状态以便将来再生的能力,叫做对象的持续性(persistence)。对象通过写出描述自己状态的值——对象转化为字节流,来记录自己的这个过程叫对象的序列化(serialization)。  一个对象要能够实现序列化,必须实现Serializable接口,或者Externalizable接口。 
               一个对象被序列化时,只保存对象的非静态成员变量,如果一个对象的成员变量是一个对象,那么这个对象的数据成员也会被保存。如果一个可序列化的对象包含对某个不可序列化的对象的引用,那么整个序列化操作将会失败,并且会抛出一个NotSerializableException。但如果把这个引用标记为transient,那么对象仍然可以序列化。
                另外,对象序列化建立了一张对象网,将当前要序列化的对象中所持有的引用指向的对象都包含起来一起写入到文件,如果一次序列化几个对象,它们中的相同内容会被共享。
code:

import java.io.*;

public class Test
{
 public static void main(String[] args) throws Exception
 {
  Employee e1=new Employee("zhangsan",25,3000.50);
  Employee e2=new Employee("lisi",24,3200.40);
  Employee e3=new Employee("wangwu",27,3800.55);
  ObjectOutputStream oos=new ObjectOutputStream(
   new FileOutputStream("w.dat"));
  oos.writeObject(e1);
  oos.writeObject(e2);
  oos.writeObject(e3);
  oos.close();

ObjectInputStream ois=new ObjectInputStream(
   new FileInputStream("w.dat"));
  Employee e;
  String strSal;
  for(int i=0;i<3;i++)
  {
   e=(Employee)ois.readObject();
   //设置自已需要的输出方式
   //strSal=(e.salary==0)?"不告诉你":String.valueOf(e.salary);
   //System.out.println(e.name+":"+e.age+":"+strSal);
   System.out.println(e.name+":"+e.age+":"+e.salary);
  }
  ois.close();
 }
}
class Employee implements Serializable
{
 String name;
 int age;
 transient double salary;
 transient Thread t=new Thread();
 public Employee(String name,int age, double salary)
 {
  this.name=name;
  this.age=age;
  this.salary=salary;
 }
 //重写方法,完成需要的操作,如果不重写,要想不写入某些数据可以标记为transient
 //本程序的数据salary就被标记为transient,打印时输出为0.0,如果是String将为null
 /*private void writeObject(java.io.ObjectOutputStream oos)throws IOException
 {
  oos.writeUTF(name);
  oos.writeInt(age);
  //System.out.println("Write Object");
 }
 private void readObject(java.io.ObjectInputStream ois)throws IOException
 {
  name=ois.readUTF();
  age=ois.readInt();
  //System.out.println("Read Object");
 }*/
}

时间: 2024-10-13 00:29:09

java基础:关于java流与文件操作的相关文章

java基础篇IO流的规律

前两篇降了IO流中的字节流和字符流复制的例子,今天来总结一下IO流的规律 掌握好IO流的规律,再开发中会很好用 下面来总结一下: 1,明确源和目的 源:输入流 InputStream 和Reader 目的:输出流 OutputStream 和Writer 2,操作的数据是否是纯文本. 是:使用字符流 不是:使用字节流 3,当体系明确后,在明确要使用哪个具体的对象,通过设备来进行区分 源设备: 内存,硬盘,键盘 目的设备: 内存,硬盘,控制台 这里的源就是你想进行的操作,比如说你想从c盘复制一个文

java基础学习总结——流

永不放弃,一切皆有可能!!! 只为成功找方法,不为失败找借口! java基础学习总结——流 一.JAVA流式输入/输出原理 流是用来读写数据的,java有一个类叫File,它封装的是文件的文件名,只是内存里面的一个对象,真正的文件是在硬盘上的一块空间,在这个文件里面存放着各种各样的数据,我们想读文件里面的数据怎么办呢?是通过一个流的方式来读,咱们要想从程序读数据,对于计算机来说,无论读什么类型的数据都是以010101101010这样的形式读取的.怎么把文件里面的数据读出来呢?你可以把文件想象成一

java基础之IO流(一)

java基础之IO流(一)之字节流 IO流体系太大,涉及到的各种流对象,我觉得很有必要总结一下. 那什么是IO流,IO代表Input.Output,而流就是原始数据源与目标媒介的数据传输的一种抽象.典型数据源与目标媒介包括磁盘.网络.内存等等. IO流的分类: 按流向分为:输入流和输出流(本地内存为参考) 按处理数据单位:字符流和字节流 按照是否与特定的地方相连(磁盘.网络.内存):节点流和处理流 节点流:可以从或向一个特定的地方(节点)读写数据. 处理流:是对一个已存在的流的连接和封装,通过所

java基础之概谈xml文件解析

XML已经成为一种很通用的数据交换格式,它的平台无关性,语言无关性,系统无关性,给数据集成与交互带来了极大的方便.诸多web应用框架,其可配置的编程方式,给我们的开发带来了很大程度的便捷,但细细想来,它们的应用无一不是java bean与xml之间的转换解析.本文将对xml的两种操作标准DOM和SAX,从它们各自的特点.适用范围等方面进行简单介绍. DOM (Document Object Model) :DOM标准中,采用W3C标准表示XML,有多重语言支持,因此其跨平台性很好.采用DOM规范

Java基础复习笔记系列 七 IO操作

Java基础复习笔记系列之 IO操作 1. 2.

【java基础】Java反射机制

一.预先需要掌握的知识(java虚拟机)  1)java虚拟机的方法区:  java虚拟机有一个运行时数据区,这个数据区又被分为方法区,堆区和栈区,我们这里需要了解的主要是方法区.方法区的主要作用是存储被装载的类 的类型信息,当java虚拟机装载某个类型的时候,需要类装载器定位相应的class文件,然后将其读入到java虚拟机中,紧接着虚拟机提取class 中的类型信息,将这些信息存储到方法区中.这些信息主要包括: 这个类型的全限定名 这个类型的直接超类的全限定名 这个类型是类类型还是接口类型

【Java基础】Java面试题目整理与解说(二)

1.Collection 和 Collections 的差别. Collection 是集合类的上级接口,继承于他的接口主要有 Set 和 List. Collections 是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索.排序.线程安全化等操作. 2.HashMap 和 Hashtable 的差别. HashMap 是 Hashtable 的轻量级实现(非线程安全的实现),他们都完毕了 Map 接口,HashMap是非线程安全,效率上可能高于 Hashtable.在多个线程

【Java基础】Java面试题目整理与讲解(二)

1.Collection 和 Collections 的区别. Collection 是集合类的上级接口,继承于他的接口主要有 Set 和 List. Collections 是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索.排序.线程安全化等操作. 2.HashMap 和 Hashtable 的区别. HashMap 是 Hashtable 的轻量级实现(非线程安全的实现),他们都完成了 Map 接口,HashMap是非线程安全,效率上可能高于 Hashtable.在多个线程

Java基础 之Java动态绑定详解

程序绑定的概念: 绑定指的是一个方法的调用与方法所在的类(方法主体)关联起来.对java来说,绑定分为静态绑定和动态绑定:或者叫做前期绑定和后期绑定 静态绑定(早绑定 编译器绑定): 在程序执行前方法已经被绑定,此时由编译器或其它连接程序实现.例如:C. 针对java简单的可以理解为程序编译期的绑定:这里特别说明一点,java当中的方法只有final,static,private和构造方法是前期绑定 动态绑定(迟绑定 运行期绑定): 后期绑定:在运行时根据具体对象的类型进行绑定. 若一种语言实现