Java的I/O操作

一、概述

  Java的IO支持通过java.io包下的类和接口来完成,在java.io包下主要有包括输入、输出两种IO流,每种输入输出流又可分为字节流和字符流两大类。从JDK1.4以后,Java在java.nio包下提供了系列的全新API,通过java.nio,程序可以更高效的进行输入、输出操作。

二、Java I/O类和接口 

1、File类

  File类直接处理文件和文件系统,它没有指定如何获取信息或将信息保存到文件中,只描述了文件本身的属性。File对象用于获得或者操作与磁盘文件相关联的信息,如存取权限、时间、日期和目录路径等,并且还可以浏览子目录的层次结构。

下面的构造函数可用来创建File对象:

构造方法摘要
File(File parent, String child)
          根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例。
File(String pathname)
          通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。
File(String parent, String child)
          根据 parent 路径名字符串和 child 路径名字符串创建一个新 File 实例。
File(URI uri)
          通过将给定的 file: URI 转换为一个抽象路径名来创建一个新的 File 实例。

File类定义了许多可以得到File对象标准属性的方法

public class Demo
{
    public static void main(String[] args)
    {
        File f=new File("D://hello.java");
        System.out.println(f.getParent());//返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回 null
        System.out.println(f.getName());//返回由此抽象路径名表示的文件或目录的名称
        System.out.println(f.exists());//测试此抽象路径名表示的文件或目录是否存在
        System.out.println(f.getAbsoluteFile());// 返回此抽象路径名的绝对路径名形式
        System.out.println(f.getAbsolutePath());//返回此抽象路径名的规范路径名字符串
        System.out.println(f.getPath());//将此抽象路径名转换为一个路径名字符串
        System.out.println(f.hashCode());//计算此抽象路径名的哈希码
        System.out.println(f.length());//返回由此抽象路径名表示的文件的长度
        System.out.println(f.list());// 返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录
        System.out.println(f.mkdir());//创建此抽象路径名指定的目录
    }
}

  2. 流类

  Java中把不同的输入输出源抽象画为“流”,通过流的方式允许?Java程序使用相同的方式来访问不同的输入输出源。

  字节流类:提供了处理针对字节的IO的丰富环境,顶部类是InputStream和OutputStream,它们均是抽象类。

  字符流类:字节流类不能处理Unicode字符,字符流类操作的数据单元为字符,,顶部类是Reader和Writer。

  字节流类和字符流类的功能基本一样,只是操作的数据单元不同,其中InputStream和Reader都是将数据抽象为一根水管,程序可以通过read()方法每次抽取一个“水滴”,也可以通过read(char[]cbuf)方法来读取多个“水滴”,程序通过read()方法返回-1来判断是否到了输入流的结束点。

  eg.读取文件,统计文件字符数:

public class FileDemo
{
    public static void main(String[] args)
    {
        int b=0;
        try
        {
            FileInputStream in=null;
            in =new FileInputStream("D:\\a.txt");
            long num=0;
            while((b=in.read())!=-1)
            {
                System.out.print((char)b);
                num++;
            }
            in.close();
            System.out.println(num);
        }
        catch (FileNotFoundException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}

  FileInputStream类创建一个InputStream,可以用来从文件中读取文件。

  eg.将一个文件内容拷贝至另一个文件:

public class FileOutStream
{
    public static void main(String[] args)
    {
        int b=0;
        try
        {
            FileInputStream in =new FileInputStream("D:\\Eclipse\\workSpace\\day_041602\\src\\day_041602\\TestMain.java");
            FileOutputStream out=new FileOutputStream("D:\\hello.java");
            while((b=in.read())!=-1)
            {
                out.write(b);
            }
            in.close();
            out.close();
            System.out.println("执行完成");
        }
        catch (FileNotFoundException e)
        {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        } catch (IOException e)
        {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }
    }
}

  BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter称为缓冲流,它们通过缓冲输入输出来提高性能。

  eg.在hello.java文本中输入100个随机数,并在屏幕上显示:

public class BufferWriterDemo
{
    public static void main(String[] args)
    {
        try
        {
            String s;
            BufferedWriter bw=new BufferedWriter(new FileWriter("D:\\hello.java"));
            BufferedReader br=new BufferedReader(new FileReader("D:\\hello.java"));
            for(int i=0;i<100;i++)
            {
                s=String.valueOf(Math.random());  //产生随机数
                bw.write(s);//写入hello.java文件中
                bw.newLine();//写入一个换行符
            }
            bw.flush();//刷新缓冲
            while((s=br.readLine()) != null)//读取一个文本行
                {
                        System.out.println(s);
                }
            bw.close();
            br.close();
        }
        catch (IOException e)
        {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }
    }
}

三、NIO

  1.概述

  NIO使用内存映射的方式处理输入输出,将文件或文件的一段区域映射到内存中,这样就可以像访问内存一样来访问文件了。

  相关的包有:java.nio.channels包:主要包含Channel和Selector相关的类,java.nio.charset包:主要包含和字符集相关的类

  NIO系基于两个基本的元素:缓冲和通道。缓冲区容纳数据,通道代表队I/O设备的开放式连接。一般而言使用NIO系统,需要获得到I?O设备的一个通道和容纳数据的一个缓冲区,然后可以对缓冲区进行操作,随意输入和输出数据。除此之外,NIO还提供了用于将Unicode字符串映射成字节序列以及逆映射操作的Charset类,还有支持非阻塞式输入输出的Selector类。

  2.缓冲区

   缓冲(buffer)可以理解成一个容器,它的本质是一个数组,发送到Channel中的所有对象都必须首先放到buffer中,从channel中读取的数据也必须先读到buffer中。

   Buffer中有三个重要的参数

  • capacity:表示该Buffer的最大存储容量
  • limit:第一个不应该被读出或写入的缓冲区位置索引
  • position:用于指明下一个可以被读出或写入的缓冲区位置索引

      

    除此之外还有一个可选的mark标记,该mark允许程序直接将position定位到mark处。位置如下所示:

   每放入一个数据,position向后移动一位,当Buffer装入数据结束后,调用flip方法,将limit设置为position所在的位置,将position设置为0,这样使得从Buffer中读数据总是从0开始。当Buffer输出数据结束后,Buffer调用 clear方法,它将position置为0,,置limit为capacity,这样为再次向Buffer中装入数据做好准备。Buffer还提供了put和get方法,用于向Buffer中放入数据和读取数据,既支持对单个数据的访问也支持对批量数据的访问。

  eg.

public class Test
{
    public static void main(String[] args)
    {
        CharBuffer m=CharBuffer.allocate(8);
        m.put(‘a‘);
        m.put(‘b‘);
        m.put(‘c‘);
        System.out.println("position:"+m.position());
        System.out.println("limit:"+m.limit());
        m.flip();
        System.out.println("第一个元素"+m.get());
        System.out.println("第二个元素"+m.get());
        System.out.println("position:"+m.position());
    }
}

   执行结果:

  

 3.通道

   Channel与传统的InputStream、OutputStream最大的区别在于它提供了一个map方法,通过该map方法可以直接将一块数据映射到内存中。

   Channel是一个接口,系统为该接口提供了FileChannel等实现类,所有的Channel都是通过传统节点InputStream、OutputSteam的getChannel方法来返回对应的Channel。

   Channel中最常见的三个方法是:map、read和write。其中map将Channel对应的部分或全部数据映射的ByteBuffer,read或write方法有一系列重载的形式用于读取数据。

  eg.将WelcomeServlet.java的内容复制到a.txt中去,并在控制台打印处内容。

public class FileChannelTest
{
    public static void main(String[] args)
    {
        FileChannel inChannel=null;
        FileChannel outChannel=null;
        FileChannel randomChannel=null;
        File f=new File("D://WelcomeServlet.java");
        try
        {
            FileInputStream fs=new FileInputStream(f);
            inChannel=fs.getChannel();

            MappedByteBuffer buffer=inChannel.map(FileChannel.MapMode.READ_ONLY,0, f.length());//将inChannel里的全部数据映射成ByteBuffer
            Charset charset=Charset.forName("GBK");
            outChannel=new FileOutputStream("D://a.txt").getChannel();

            outChannel.write(buffer);
            buffer.clear();

            CharsetDecoder decoder=charset.newDecoder();//创建解码器对象
            CharBuffer charBuffer=decoder.decode(buffer);//使用解码器将ByteBuffer转换为charBuffer
            System.out.println(charBuffer);     //获取对应字符串
        }
        catch (FileNotFoundException e)
        {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }
        catch (IOException e)
        {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }
    }
}
时间: 2024-08-05 06:02:02

Java的I/O操作的相关文章

java 对mongodb的操作

java 对mongodb的操作 1.1连单台mongodb Mongo mg = newMongo();//默认连本机127.0.0.1  端口为27017 Mongo mg = newMongo(ip);//可以指定ip 端口默认为27017 Mongo mg = newMongo(ip,port);//也可以指定ip及端口号 1.2连双台mongodb //ip为主机ip地址,port为端口号,dataBaseName相当于数据库名 DBAddress left = new DBAddre

Java I/O流操作(二)---缓冲流[转]

转自:http://blog.csdn.net/johnny901114/article/details/8710403 一.BufferWriter类 IO的缓冲区的存在就是为了提高效率,把要操作的数据放进缓冲区,然后一次性把缓冲区的内容写到目的地,而不是写一次就往目的地写一次. 在这里要注意的是当我们关闭了缓冲区对象实际也关闭了与缓冲区关联的流对象. BufferWriter类 try { FileWriter fw =new FileWriter("test.txt"); //使

java大文件读写操作,java nio 之MappedByteBuffer,高效文件/内存映射

java处理大文件,一般用BufferedReader,BufferedInputStream这类带缓冲的Io类,不过如果文件超大的话,更快的方式是采用MappedByteBuffer. MappedByteBuffer是java nio引入的文件内存映射方案,读写性能极高.NIO最主要的就是实现了对异步操作的支持.其中一种通过把一个套接字通道(SocketChannel)注册到一个选择器(Selector)中,不时调用后者的选择(select)方法就能返回满足的选择键(SelectionKey

java中的集合操作类(未完待续)

申明: 实习生的肤浅理解,如发现有错误之处,还望大牛们多多指点 废话 其实我写java的后台操作,我每次都会遇到一条语句:List<XXXXX> list = new ArrayList<XXXXX>(); 但是我仅仅只是了解,list这个类是一个可变长用来存储的对象实例的类,我甚至觉得这个List对象可以理解成数组,但是却又与java中咱们正常理解的数组很多的不同,比如说,他的长度可以随着需要自动增长,比如说,实例化一个List类就和咱们声明数组的时候是不一样的! 今天的实习生活

java生成Excel及操作Excel

JAVA EXCEL API:是一开放源码项目,通过它Java开发人员可以读取Excel文件的内容.创建新的Excel文件.更新已经存在的Excel文件.使用该API非Windows操作系统也可以通过纯Java应用来处理Excel数据表.因为它是使用Java编写的,所以我们在Web应用中可以通过JSP.Servlet来调用API实现对Excel数据表的访问. 下载: 官方网站 http://www.andykhan.com/jexcelapi/ 下载最新版本(本人下的是jexcelapi_2_6

java file文件类操作使用方法大全

1.构造函数 [java] view plaincopy public class FileDemo { public static void main(String[] args){ //构造函数File(String pathname) File f1 =new File("c:\\zuidaima\\1.txt"); //File(String parent,String child) File f2 =new File("c:\\zuidaima",&quo

java FileStream文件流操作

直接上代码,函数使用说明详见Java API文档 import java.io.*; public class StreamDemo { public static void main(String[] args) { File f=new File("F:\\workspace\\JavaPrj\\test.txt"); FileOutputStream out=null; try { out=new FileOutputStream(f); byte[] b=new String(

Java链表的删除操作

刚开始接触java时很长一段时间, 总觉得java链表的删除操作自己写的有bug. 第一个bug版本: 仅接removeByForlist.remove(j)之后应该显示调用i-- public static void testRemoveByFor() { List<Integer> removeByForlist = Lists.newArrayList(1, 1, 1, 1, 1, 1, 1, 1, 1, 1); System.out.println(ToStringBuilder.re

Java并发学习之四——操作线程的中断机制

本文是学习网络上的文章时的总结,感谢大家无私的分享. 1.如果线程实现的是由复杂算法分成的一些方法,或者他的方法有递归调用,那么我们可以用更好的机制来控制线程中断.为了这个Java提供了InterruptedException异常.当你检测到程序的中断并在run()方法内捕获,你可以抛这个异常. 2.InterruptedException异常是由一些与并发API相关的Java方法,如sleep()抛出的. 下面以程序解释 package chapter; import java.io.File

java对cookie的操作

java对cookie的操作比较简单,主要介绍下建立cookie和读取cookie,以及如何设定cookie的生命周期和cookie的路径问题. 建立一个无生命周期的cookie,即随着浏览器的关闭即消失的cookie,代码如下 1 2 3 4 HttpServletRequest request  HttpServletResponse response Cookie cookie = new Cookie("cookiename","cookievalue");