JavaRush /Java 博客 /Random-ZH /Java 中的 I/O。类 FileInputStream、FileOutputStream、BufferedIn...

Java 中的 I/O。类 FileInputStream、FileOutputStream、BufferedInputStream

已在 Random-ZH 群组中发布
你好!在今天的讲座中,我们将继续讨论 Java 中的输入和输出流,简称Java I/O(“输入输出”)。这不是关于这个主题的第一场讲座,也不会是最后一场:) 碰巧 Java 作为一种语言提供了许多处理输入/输出的机会。有相当多的类实现了这个功能,所以我们把它们分成几个讲座,这样你一开始就不会感到困惑:)Java 中的 I/O。 类 FileInputStream、FileOutputStream、BufferedInputStream - 1在之前的讲座中,我们接触过BufferedReader,以及抽象类InputStream 和 OutputStream以及几个后人。今天我们将看看 3 个新类:FileInputStreamFileOutputStreamBufferedInputStream

文件输出流类

FileOutputStream类的主要用途是将字节写入文件。 没什么复杂的:) FileOutputStream是抽象OutputStream类的实现之一。在构造函数中,此类的对象采用目标文件(需要写入字节)的路径或该类的对象File。让我们看一下这两个例子:
public class Main {

   public static void main(String[] args) throws IOException {


       File file = new File("C:\\Users\\Username\\Desktop\\test.txt");
       FileOutputStream fileOutputStream = new FileOutputStream(file);

       String greetings = "Hi! Welcome to JavaRush - the best site for those who want to become a programmer!";

       fileOutputStream.write(greetings.getBytes());

       fileOutputStream.close();
   }
}
创建对象时,File我们在构造函数中指定了该对象所在的路径。无需提前创建:如果不存在,程序将自行创建。您可以不创建额外的对象,而只需传递带有地址的字符串:
public class Main {

   public static void main(String[] args) throws IOException {


       FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\test.txt");

       String greetings = "Hi! Welcome to JavaRush - the best site for those who want to become a programmer!";

       fileOutputStream.write(greetings.getBytes());

       fileOutputStream.close();
   }
}
两种情况的结果是相同的。我们可以打开我们的文件并看到:

Hello! Добро пожаловать на JavaRush — лучший сайт для тех, кто хочет стать программистом!
然而,这里有一个警告。尝试连续运行上面示例中的代码几次,然后查看该文件并回答问题:您看到其中写了多少行?只有一个。但您多次运行该代码。然而,事实证明,数据每次都被覆盖,替换旧的。如果我们对此不满意并需要顺序记录怎么办?如果我们想连续三次将问候语写入文件怎么办?这里一切都很简单。由于语言本身无法知道我们在每种情况下需要什么样的行为,因此FileOutputStream您可以向构造函数传递一个附加参数 - boolean append。如果其值为true,数据将写入文件末尾。如果为false(默认值为false),旧数据将被删除并写入新数据。让我们测试并运行修改后的代码三次:
public class Main {

   public static void main(String[] args) throws IOException {


       FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\test.txt", true);

       String greetings = "Hi! Welcome to JavaRush - the best site for those who want to become a programmer!\r\n";

       fileOutputStream.write(greetings.getBytes());

       fileOutputStream.close();
   }
}
文件中的结果:

Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
另一件事!使用 I/O 类时请记住此功能。有一次,我不得不花几个小时处理任务,以了解我的旧数据从文件中去了哪里:) 当然,与其他 I/O 类的情况一样,不要忘记通过close().

文件输入流类

该类具有FileInputStream相反的目的 - 从文件中读取字节。就像FileOutputStream继承一样OutputStream,此类派生自抽象类InputStream。让我们在文本“ test.txt ”中写入几行文本 :

«So close no matter how far
Couldn't be much more from the heart
Forever trusting who we are
And nothing else matters»
Java 中的 I/O。 类 FileInputStream、FileOutputStream、BufferedInputStream - 2 这是使用以下方法从文件读取数据的实现FileInputStream
public class Main {

   public static void main(String[] args) throws IOException {

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\test.txt");

       int i;

       while((i=fileInputStream.read())!= -1){

           System.out.print((char)i);
       }
   }
}
我们从文件中读取一个字节,将读取的字节转换为字符并将其输出到控制台。这是控制台中的结果:

So close no matter how far
Couldn't be much more from the heart
Forever trusting who we are
And nothing else matters

BufferedInputStream 类

我认为,鉴于之前讲座中的知识,您可以轻松说出为什么需要该类BufferedInputStream以及它具有哪些优势FileInputStream:)我们已经遇到过缓冲流,因此在继续阅读之前尝试猜测(或记住):) 缓冲流主要需要优化 I/O。 访问数据源(例如从文件中读取)是一项性能密集型操作。并且每次访问文件读取一个字节是一种浪费。因此,BufferedInputStream它不是一次读取一个字节,而是分块读取数据,并将它们临时存储在特殊的缓冲区中。这使我们能够通过减少对文件的访问次数来优化程序的操作。让我们看看它是什么样子的:
public class Main {

   public static void main(String[] args) throws IOException {

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\test.txt");

       BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream, 200);

       int i;

       while((i = bufferedInputStream.read())!= -1){

           System.out.print((char)i);
       }
   }
}
这里我们创建了一个对象BufferedInputStream。它接受一个对象或其任何后继者作为输入InputStream,因此前一个FileInputStream就可以了。它将缓冲区大小(以字节为单位)作为附加参数。现在,多亏了这一点,数据将从文件中读取,而不是一次一个字节,而是一次 200 个!想象一下我们减少了多少文件访问次数。FileInputStream为了比较性能,您可以使用一些大小为几兆字节的大型文本文件,并使用和来比较读取它并将其输出到控制台所需的时间(以毫秒为单位)BufferedInputStream。以下是两个代码示例:
public class Main {

   public static void main(String[] args) throws IOException {

       Date date = new Date();

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\textBook.rtf");

       BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);

       int i;

       while((i = bufferedInputStream.read())!= -1){

           System.out.print((char)i);
       }

       Date date1 = new Date();

       System.out.println((date1.getTime() - date.getTime()));
   }
}



public class Main {

   public static void main(String[] args) throws IOException {

       Date date = new Date();

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\26951280.rtf");


       int i;

       while((i = fileInputStream.read())!= -1){

           System.out.print((char)i);
       }

       Date date1 = new Date();

       System.out.println((date1.getTime() - date.getTime()));
   }
}
在我的计算机上读取 1.5 MB 文件时,FileInputStream它在大约 3500 毫秒内完成了工作,但在这里BufferedInputStream它在大约 1700 毫秒内完成了工作。正如您所看到的,缓冲流将程序的性能优化了 2 倍!:) 我们将继续学习 I/O 课程 - 很快再见!
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION