I/O流和文件

一、深入讲解

        流是在java中处理I/O的方式。

        流由字节或者字符组成,你可以从流中读取字节或者字符,或者将其写到流中,还可以将它们连接到各种数据源或数据存储器,甚至是字节和字符数组。

1、流、读取器和写入器

        引入流的概念使得处理不同的数据或者数据存储时的编程更统一。即无论你使用的是磁盘文件、内存缓冲区,还是网络,都可以用同样的方式处理输入和输出。

          在java中,流I/O基于InputStream、OutputStream、Reader和Writer类。InputStream和OutputStream用于面向字节的流(比如在处理二进制文件时),Reader和Write类用于面向字符的流(比如在处理文本文件时)。

注意:不要直接使用这些类,而是应该从它们派生出新类。实际上java已经为你做了很多事,因此你可以使用十几类。

        通常使用流类的构造器创建流,流通常分为输入流和输出流;在创建流对象后,可以使用它的方法(通常是read和write)传输数据。在使用过流对象后,通常使用close方法关闭并停止使用数据或者数据存储。

        File类并不是流类,这个类并不处理文件的内容,而是提供关于文件的许多信息,比如文件的大小、许可权、日期等等。

2、file类

2.1   抽象路径名      

        用户界面和操作系统使用与系统相关的路径名字符串来命名文件和目录。

        抽象路径名 有两个组件:

        1、一个可选的与系统有关的前缀 字符串,比如盘符

        2、零个或更多字符串名称 的序列

        抽象路径名中的第一个名称是目录名,对于 Microsoft Windows UNC路径名则是主机名。抽象路径名中第一个名称之后的每个名称表示一个目录;最后一个名称既可以表示目录,也可以表示文件。抽象路径名没有前缀和名称序列。

        路径名字符串与抽象路径名之间的转换与系统有关将抽象路径名转换为路径名字符串时,每个名称与下一个名称之间用一个默认分隔符隔开。

        默认名称分隔符由系统属性 file.separator定义,可通过此类的公共静态字段separatorseparatorChar使其可用。将路径名字符串转换为抽象路径名时,可以使用默认名称分隔符或者底层系统支持的任何其他名称分隔符来分隔其中的名称。

字段作用
static String scparator与系统相关的默认的名称分隔字符,为了方便表示成字符串
static char scparatorChar与系统相关的默认的名称分隔字符
        

        无论是抽象路径名还是路径名字符串,都可以是绝对路径名或相对 路径名。

        绝对路径名是完整的路径名,不需要任何其他信息就可以定位它所表示的文件。相反,相对路径名必须使用取自其他路径名的信息进行解释。

        默认情况下,java.io包中的类总是根据当前用户目录来解析相对路径名。

        调用此类的getParent()方法可以获取抽象路径名的 路径名,它由路径名前缀以及路径名名称序列中的每个名称(最后一个除外)组成。

String getParent()得到这个抽象路径名的父目录的抽象路径名;如果这个路径名没有命名父目录,那么返回null

 

        在处理 UNIX平台的根目录,以及 Microsoft Windows 平台的盘符、根目录和 UNC路径名时,将用到前缀这一概念。如下所示:

        1、对于 UNIX平台,绝对路径名的前缀始终是 "/"。相对路径名没有前缀。表示根目录的绝对路径名的前缀为 "/"且名称序列为空。

        2、对于 Microsoft Windows平台,包含盘符的路径名前缀由驱动器号和一个 ":"组成。如果路径名是绝对路径名,还可能后跟 "\\"UNC路径名的前缀是 "\\\\";主机名和共享名是名称序列中的前两个名称。没有指定驱动器的相对路径名没有前缀。

        文件系统可以实现对实际文件系统对象上的某些操作(比如,读、写、执行)进行限制。这些限制统称为访问权限

       File类的实例是不可变的;也就是说,一旦创建,File对象表示的抽象路径名将永不改变。


2.2  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实例


2.3  File类的方法

       暂时省略。。。


3、InputStream和OutputStream

      InputStream和OutputStream类是java中面向字节的I/O的基类。

3.1 InputStream

      InputStream类用于建立输入流

        构造器:

       InputStream():创建一个InputStreaam


      方法:

int   available()得到可以从这个输入流读取的字节数
void  close()关闭这个输入流
void  mark(int    readlimit) 在这个输入流的当前位置做标记
boolean   markSupported()如果这个输入流支持mark和reset方法,则返回True
abstract  int  read()从这个输入流读取数据的下一个字节
int   read(byte[]b)从这个输入流读取一些字节并将其存储在缓冲区数组b中
int   read(byte[]b,int  offset,int  len)从这个输入流读取最多len个字节的数据并将其存储在一个字节数组中
void   reset()j将这个输入流重新定位到上次调用mark方法的位置
long  skip(void)跳过这个输入流中n个字节的数据

3.2   OutputStream

         OutputStream用于建立输出流。

InputStream类用于建立输入流

        构造器:

       OutputStream():创建一个OutputStream


      方法:

void  close()关闭这个输出流
void  flush(int    readlimit) 刷新这个输出流并将任何等待的缓冲输出字节写出
void   write(byte[] b)将来自给定的字节数组的b.length个字节写到这个输出流
void   write(byte[] b,int offset,int len)将给定的字节数组中的从偏移量offset开始的len个字节写到这个输出流
abstract  void  write(int  b)将给定的字节写到这个输出流

        现在我们已经了解了OutputStream和InputStream类,那么从下一个主题开始使用它们。

4、FileInputStream和FileOutputStream

4.1   FileInputStream

        我需要打开一个图像文件并操作其中的个别字节,我应该怎么做?  你可以使用FileInputStream类处理文件中的字节。

        FileInputStream类的构造器如下表所示:


FileInputStream(File  file)通过打开一个实际文件的连接构造一个FileInputStream
FileInputStream(FileDescriptor fdObj)通过使用文件描述符fdObj构造一个FileInputStream
FileInputStream(String name)通过打开一个实际文件的连接构造一个FileInputStream。name指定了文件名

       FileInputStream类的方法如下表所示:

int   available()得到可以从这个输入流读取的字节数
void  close()关闭这个文件输入流
protected  void  finalize()当没有引用指向这个文件输入流时,确保调用它的close方法
FileDescriptor  getFD()得到FileDescriptor对象
int   read()从这个输入流读取一个字节的数据并返回它
int   read(byte[] b)从这个输入流读取最多b.length个字节的数据到一个字节数组中,并且返回读取的字节数
int   read(byte[] b,int offset,int len)从这个输入流读取最多len个字节的数据到一个字节数组中,并返回读取的字节数
long  skip(long   n)跳过并丢弃n个字节的数据


       使用FileInputStream类的构造器创建一个文件输入流。这个类的读取方法如下:

  • int   read():从这个输入流读取一个字节的数据并返回它
  • int   read(byte[] b):从这个输入流读取最多b.length个字节的数据到一个字节数组中,并且返回读取的字节数
  • int   read(byte[] b,int offset,int len):从这个输入流读取最多len个字节的数据到一个字节数组中,并返回读取的字节数

        让我们看一个例子,在这个例子中,我们打开这个应用程序自己的源代码文件,并读取并显示50个字节的代码,用skip()方法跳过50个字节,然后读取并显示50个字节。

import  java.io.*
class   fileInputStream{
         public  static void main(String args[ ]) throws Exception{
          int size;
          FileInputStream fileinputStream = new FileInputStream("fileInputStream.java");
          System.out.println("Available bytes:" + (size - fileinputstream.available()));
          System.out.println(Reading  50 bytes...");
          byte  bytearray[] = new byte[50];
          if(fileinputStream.read(bytearray) != 50){
                  System.out.println("Could  not  get  50 bytes!");
         }
         System.out.println(new String(bytearray,0,50));
         System.out.println("SKipping  50 bytes...");
         fileinputStream.skip(50);
         System.out.println(Reading  50 bytes...");
         if(fileinputStream.read(bytearray) != 50){
                  System.out.println("Could  not  get  50 bytes!");
         }
         System.out.println(new String(bytearray,0,50));
         fileinputStream.close();
       }
 }

4.2  FileOutputStream类

        OK,我们知道应该如何使用FileInPutStream类从文件读,但是用哪个类写文件呢? 我打赌你应该能够猜到。

        你可以使用FileOutputStream类逐字节地将数据写到文件中。这个类是从OutputStream类派生的。

        FileOutputStream的构造器如下表所示。

FileOutputStream(File file)构造一个写到给定的File对象的文件输出流
FileOutputStream(FileDescriptor fdbj)构造一个写到给定的文件描述符的文件输出流
FileOutputStream(String name)构造一个附加到具有给定名称/路径的文件输出流

FileOutputStream的方法如下表所示:

void  close()关闭这个文件输出流
protected  void  finalize()当没有引用指向这个文件输入流时,确保调用它的close方法
FileDescriptor  getFD()得到FileDescriptor对象
void   write(byte[] b)将来自给定的字节数组的b.length个字节写到这个文件输出流
void  write(byte[] b,int off,int len)将给定字节数组中从偏移量off开始的len个字节写到这个文件输出流给定
void  write(int  b)将给定的字节写到这个文件输出流









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 Java 中使用 I/O 复制文件可以使用如下的代码: ``` import java.io.*; public class CopyFile { public static void main(String[] args) { // 要复制的文件的路径 String srcFile = "/path/to/src/file.txt"; // 复制后的文件的路径 String destFile = "/path/to/dest/file.txt"; try (InputStream in = new FileInputStream(srcFile); OutputStream out = new FileOutputStream(destFile)) { // 缓冲区大小 byte[] buffer = new byte[1024]; int length; // 循环读取文件内容并写入到新文件中 while ((length = in.read(buffer)) > 0) { out.write(buffer, 0, length); } } catch (IOException e) { e.printStackTrace(); } } } ``` 上面的代码使用了 try-with-resources 语句,这样在结束后会自动关闭。如果不使用 try-with-resources 语句,需要在 finally 块中手动关闭。 需要注意的是,上面的代码只能复制纯文本文件。如果要复制二进制文件,需要使用字节(InputStream 和 OutputStream)而不是字符(Reader 和 Writer)。 ### 回答2: 文件复制通过使用Java中的I/O可以轻松地实现。下面是一个简单的示例,演示了如何使用I/O来实现文件复制。 ```java import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class FileCopy { public static void main(String[] args) { String sourceFilePath = "source.txt"; // 源文件路径 String targetFilePath = "target.txt"; // 目标文件路径 try { // 创建输入和输出 FileInputStream input = new FileInputStream(sourceFilePath); FileOutputStream output = new FileOutputStream(targetFilePath); // 创建一个缓冲区,用于存储读取/写入的数据 byte[] buffer = new byte[1024]; int bytesRead; // 读取源文件中的数据,并将其写入目标文件中 while ((bytesRead = input.read(buffer)) != -1) { output.write(buffer, 0, bytesRead); } // 关闭 input.close(); output.close(); System.out.println("文件复制完成!"); } catch (IOException e) { System.out.println("发生错误:" + e.getMessage()); } } } ``` 上述代码中,我们首先指定源文件和目标文件的路径。然后,我们使用`FileInputStream`和`FileOutputStream`类创建输入和输出。我们还创建了一个缓冲区,用于存储读取和写入的数据。 在`while`循环中,我们使用`read()`方法从输入读取数据,并使用`write()`方法将读取的数据写入输出。我们还使用`bytesRead`变量来记录实际读取的字节数,以便正确写入到输出中。 最后,我们在`IOException`中捕获任何可能发生的错误,并将错误消息输出到控制台。如果没有错误发生,则输出"文件复制完成!"的消息。 通过运行上述代码,我们可以将一个文件的内容复制到另一个文件中。请确保源文件存在,并且目标文件不存在,以避免发生意外的覆盖。 ### 回答3: Java使用I/O完成文件复制非常简单。我们可以使用字节或字符来实现文件复制。 使用字节实现文件复制时,首先需要创建一个文件输入和一个文件输出。然后,通过循环从文件输入中读取字节,并将其写入文件输出中,实现文件复制。最后记得关闭输入和输出。 代码示例: ```java import java.io.*; public class FileCopy { public static void main(String[] args) { // 设置输入文件和输出文件的路径 String inputFilePath = "input.txt"; String outputFilePath = "output.txt"; try { FileInputStream inputStream = new FileInputStream(inputFilePath); FileOutputStream outputStream = new FileOutputStream(outputFilePath); // 定义一个字节数组来存储读取的字节数据 byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } // 关闭输入和输出 inputStream.close(); outputStream.close(); System.out.println("文件复制成功!"); } catch (IOException e) { e.printStackTrace(); } } } ``` 使用字符实现文件复制时,操作步骤与字节类似。只是在创建时需要使用Reader和Writer类,同时要保证源文件和目标文件的编码类型一致。 代码示例: ```java import java.io.*; public class FileCopy { public static void main(String[] args) { // 设置输入文件和输出文件的路径 String inputFilePath = "input.txt"; String outputFilePath = "output.txt"; try { FileReader reader = new FileReader(inputFilePath); FileWriter writer = new FileWriter(outputFilePath); // 定义一个字符数组来存储读取的字符数据 char[] buffer = new char[1024]; int charsRead; while ((charsRead = reader.read(buffer)) != -1) { writer.write(buffer, 0, charsRead); } // 关闭输入和输出 reader.close(); writer.close(); System.out.println("文件复制成功!"); } catch (IOException e) { e.printStackTrace(); } } } ``` 无论使用字节还是字符,Java中的I/O都提供了方便的方法来实现文件复制。通过以上的代码示例,我们可以轻松地完成文件复制操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值