读文件

http://www.baeldung.com/java-read-file

Java – Read from File

1. Overview

In this tutorial we’ll explore different ways to read from a File in Java; we’ll make use ofBufferedReaderScannerStreamTokenizerDataInputStreamSequenceInputStream andFileChannel.

Then, we will discuss how to read a UTF-8 encoded file and how to create String from contents of a file.

Finally, we’ll explore the new techniques to read from file in Java 7.

This article is part of the “Java – Back to Basic” series here on Baeldung.

2. Read with BufferedReader

Let’s start with a simple way to read from file using BufferedReader; the file itself contains:

1
Hello world

The following code reads from the file using BufferedReader:

1
2
3
4
5
6
7
8
9
10
11
12
@Test
public void whenReadWithBufferedReader_thenCorrect()
  throws IOException {
     String expected_value = "Hello world";
     String file ="src/test/resources/test_read.txt";
      
     BufferedReader reader = new BufferedReader(new FileReader(file));
     String currentLine = reader.readLine();
     reader.close();
 
    assertEquals(expected_value, currentLine);
}

Note that readLine() will return null when the end of the file is reached.

3. Read with Scanner

Next, let’s use a Scanner to read from the File – the file contains:

1
Hello world 1

We’ll use a simple whitespace as the delimiter:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Test
public void whenReadWithScanner_thenCorrect()
  throws IOException {
    String file = "src/test/resources/test_read.txt";
    Scanner scanner = new Scanner(new File(file));
    scanner.useDelimiter(" ");
 
    assertTrue(scanner.hasNext());
    assertEquals("Hello", scanner.next());
    assertEquals("world", scanner.next());
    assertEquals(1, scanner.nextInt());
 
    scanner.close();
}

Note that the default delimiter is the whitespace, but multiple delimiters can be used with aScanner.

4. Read with StreamTokenizer

Next, let’s read a text file into tokens using a StreamTokenizer.

The way the tokenizer works is – first, we need to figure out what the next token is – String or number; we do that by looking at the tokenizer.ttype field.

Then, we’ll read the actual token based on this type:

  • tokenizer.nval – if the type was a number
  • tokenizer.sval – if the type was a String

The file simply contains:

1
Hello 1

The following code reads from the file both the String and the number:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Test
public void whenReadWithStreamTokenizer_thenCorrectTokens()
  throws IOException {
    String file = "src/test/resources/test_read.txt";
   FileReader reader = new FileReader(file);
    StreamTokenizer tokenizer = new StreamTokenizer(reader);
 
    // token 1
    tokenizer.nextToken();
    assertEquals(StreamTokenizer.TT_WORD, tokenizer.ttype);
    assertEquals("Hello", tokenizer.sval);
 
    // token 2   
    tokenizer.nextToken();
    assertEquals(StreamTokenizer.TT_NUMBER, tokenizer.ttype);
    assertEquals(1, tokenizer.nval, 0.0000001);
 
    // token 3
    tokenizer.nextToken();
    assertEquals(StreamTokenizer.TT_EOF, tokenizer.ttype);
    reader.close();
}

Note how the end of file token is used at the end.

5. Read with DataInputStream

We can use DataInputStream to read binary or primitive data type from file.

Let’s start with the actual file itself:

1
Hello

The following test reads the file using a DataInputStream:

1
2
3
4
5
6
7
8
9
10
11
@Test
public void whenReadWithDataInputStream_thenCorrect()
  throws IOException {
    String expectedValue = "Hello";
    String file ="src/test/resources/test_read.txt";
    DataInputStream reader = new DataInputStream(new FileInputStream(file));
    String result = reader.readUTF();
    reader.close();
 
    assertEquals(expectedValue, result);
}

6. Read with SequenceInputStream

Now, let’s look at how to concatenate two input streams into one usingSequenceInputStream; the 2 input files will simply contain:

1
2000

and:

1
5000

Let’s now use a SequenceInputStream to read the two files and merge them into one:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Test
public void whenReadingTwoFilesWithSequenceInputStream_thenCorrect()
  throws IOException {
    int expectedValue1 = 2000;
    int expectedValue2 = 5000;
    String file1 = "src/test/resources/test_read1.txt";
    String file2 = "src/test/resources/test_read2.txt";
    FileInputStream stream1 = new FileInputStream(file1);
    FileInputStream stream2 = new FileInputStream(file2);
 
    SequenceInputStream sequence = new SequenceInputStream(stream1, stream2);
    DataInputStream reader = new DataInputStream(sequence);
 
    assertEquals(expectedValue1, reader.readInt());
    assertEquals(expectedValue2, reader.readInt());
 
    reader.close();
    stream2.close();
}

7. Read with FileChannel

If we are reading a large file, FileChannel can be faster than standard IO.

The contents of the file:

1
Hello world

The following code reads data bytes from the file using FileChannel and RandomAccessFile:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Test
public void whenReadWithFileChannel_thenCorrect()
  throws IOException {
    String expected_value = "Hello world";
    String file = "src/test/resources/test_read.txt";
    RandomAccessFile reader = new RandomAccessFile(file, "r");
    FileChannel channel = reader.getChannel();
 
    int bufferSize = 1024;
    if (bufferSize > channel.size()) {
        bufferSize = (int) channel.size();
    }
    ByteBuffer buff = ByteBuffer.allocate(bufferSize);
    channel.read(buff);
    buff.flip();
     
    assertEquals(expected_value, new String(buff.array()));
    channel.close();
    reader.close();
}

8. Read UTF-8 encoded file

Now, let’s see how to read a UTF-8 encoded file using BufferedReader:

1
2
3
4
5
6
7
8
9
10
11
12
@Test
public void whenReadUTFEncodedFile_thenCorrect()
  throws IOException {
    String expected_value = "青空";
    String file = "src/test/resources/test_read.txt";
    BufferedReader reader = new BufferedReader
      (new InputStreamReader(new FileInputStream(file), "UTF-8"));
    String currentLine = reader.readLine();
    reader.close();
 
    assertEquals(expected_value, currentLine);
}

9. Read a file into a String

We can make good use of StringBuilder to read the entire contents of a file into a String. Let’s start with the file:

1
2
3
Hello world
 
Test line

The following code append data read from the file into a StringBuilder line by line:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Test
public void whenReadFileContentsIntoString_thenCorrect()
  throws IOException {
    String expected_value = "Hello world n Test line n";
    String file = "src/test/resources/test_read.txt";
    BufferedReader reader = new BufferedReader(new FileReader(file));
    StringBuilder builder = new StringBuilder();
    String currentLine = reader.readLine();
    while (currentLine != null) {
        builder.append(currentLine);
        builder.append("n");
        currentLine = reader.readLine();
    }
     
    reader.close();
    assertEquals(expected_value, builder.toString());
}

10. Read from File using Java 7

Java 7 introduces a new way of working with files and the filesystem – let’s make use of that to read files.

10.1. Read a Small File with Java 7

The file contents:

1
Hello world

The following code shows how to read small file using the new Files class:

1
2
3
4
5
6
7
8
9
10
@Test
public void whenReadSmallFileJava7_thenCorrect()
  throws IOException {
    String expected_value = "Hello world";
 
    Path path = Paths.get("src/test/resources/test_read.txt");
 
    String read = Files.readAllLines(path).get(0);
    assertEquals(expected_value, read);
}

Note that you can use the readAllBytes() method as well if you need binary data.

10.2. Read a Large File with Java 7

If we want to read a large file with Files class, we can use the BufferedReader.

The file contents:

1
Hello world

The following code reads the file using the new Files class and BufferedReader:

1
2
3
4
5
6
7
8
9
10
11
@Test
public void whenReadLargeFileJava7_thenCorrect()
  throws IOException {
    String expected_value = "Hello world";
 
    Path path = Paths.get("src/test/resources/test_read.txt");
 
    BufferedReader reader = Files.newBufferedReader(path);
    String line = reader.readLine();
    assertEquals(expected_value, line);
}

11. Conclusion

As you can see, there are many possibilities of reading data from a file using plain Java. You can go for BufferedReader to read line by line, Scanner to read using different delimiters, StreamTokenizer to read file into tokens, DataInputStream to read binary data and primitive data types, SequenceInput Stream to link multiple files into one stream,FileChannel to read faster from large files, etc.

写文件

Java – Write to File

1. Overview

In this tutorial we’ll explore different ways to write to a file using Java. We’ll make use ofBufferedWriterPrintWriterFileOutputStreamDataOutputStreamRandomAccessFile,FileChannel and the Java 7 Files utility class.

We’ll also take a look at locking the file while writing and discuss some final take-aways on writing to file.

This article is part of the “Java – Back to Basic” series here on Baeldung.

2. Write with BufferedWriter

Let’s start simple – and use BufferedWriter to write a String to a new file:

1
2
3
4
5
6
7
8
public void whenWriteStringUsingBufferedWritter_thenCorrect()
  throws IOException {
    String str = "Hello";
    BufferedWriter writer = new BufferedWriter(new FileWriter(fileName));
    writer.write(str);
     
    writer.close();
}

The output in the file will be:

Hello

We can then append a String to the existing file:

1
2
3
4
5
6
7
8
9
10
@Test
public void whenAppendStringUsingBufferedWritter_thenOldContentShouldExistToo()
  throws IOException {
    String str = "World";
    BufferedWriter writer = new BufferedWriter(new FileWriter(fileName, true));
    writer.append(' ');
    writer.append(str);
     
    writer.close();
}

The file will then be:

1
Hello World

3. Write with PrintWriter

Next – let’s see how we can use a PrintWriter to write formatted text to a file:

1
2
3
4
5
6
7
8
9
@Test
public void givenWritingStringToFile_whenUsingPrintWriter_thenCorrect()
  throws IOException {
    FileWriter fileWriter = new FileWriter(fileName);
    PrintWriter printWriter = new PrintWriter(fileWriter);
    printWriter.print("Some String");
    printWriter.printf("Product name is %s and its price is %d $", "iPhone", 1000);
    printWriter.close();
}

The resulting file will contain:

1
2
Some String
Product name is iPhone and its price is 1000$

Note how we’re not only writing a raw String to file, but also some formatted text with theprintf method.

We can create the writer using FileWriterBufferedWriter or even System.out.

4. Write with FileOutputStream

Let’s now see how we can use FileOutputStream to write binary data to a file. The following code converts a String int bytes and writes the bytes to file using aFileOutputStream:

1
2
3
4
5
6
7
8
9
10
@Test
public void givenWritingStringToFile_whenUsingFileOutputStream_thenCorrect()
  throws IOException {
    String str = "Hello";
    FileOutputStream outputStream = new FileOutputStream(fileName);
    byte[] strToBytes = str.getBytes();
    outputStream.write(strToBytes);
 
    outputStream.close();
}

The output in the file will of course be:

1
Hello

5. Write with DataOutputStream

Next – let’s take a look at how we can use a DataOutputStream to write a String to file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Test
public void givenWritingToFile_whenUsingDataOutputStream_thenCorrect()
  throws IOException {
    String value = "Hello";
    FileOutputStream fos = new FileOutputStream(fileName);
    DataOutputStream outStream = new DataOutputStream(new BufferedOutputStream(fos));
    outStream.writeUTF(value);
    outStream.close();
 
    // verify the results
    String result;
    FileInputStream fis = new FileInputStream(fileName);
    DataInputStream reader = new DataInputStream(fis);
    result = reader.readUTF();
    reader.close();
 
    assertEquals(value, result);
}

6. Write with RandomAccessFile

Let’s now illustrate how to write and edit inside an existing file – rather than just writing to a completely new file or appending to an existing one. Simply put – we need random access.

RandomAccessFile enable us to write at a specific position in the file given the offset – from the beginning of the file – in bytes. The following code writes an integer value with offset given from the beginning of the file:

1
2
3
4
5
6
7
private void writeToPosition(String filename, int data, long position)
  throws IOException {
    RandomAccessFile writer = new RandomAccessFile(filename, "rw");
    writer.seek(position);
    writer.writeInt(data);
    writer.close();
}

If we want to read the int stored at specific location, we can use the following method:

1
2
3
4
5
6
7
8
9
private int readFromPosition(String filename, long position)
  throws IOException {
    int result = 0;
    RandomAccessFile reader = new RandomAccessFile(filename, "r");
    reader.seek(position);
    result = reader.readInt();
    reader.close();
    return result;
}

To test our functions, let’s write an integer – edit it – and, finally, read it back:

1
2
3
4
5
6
7
8
9
10
11
12
@Test
public void whenWritingToSpecificPositionInFile_thenCorrect()
  throws IOException {
    int data1 = 2014;
    int data2 = 1500;
     
    writeToPosition(fileName, data1, 4);
    assertEquals(data1, readFromPosition(fileName, 4));
     
    writeToPosition(fileName2, data2, 4);
    assertEquals(data2, readFromPosition(fileName, 4));
}

7. Write with FileChannel

If you are dealing with large files, FileChannel can be faster than standard IO. The following code write String to a file using FileChannel:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Test
public void givenWritingToFile_whenUsingFileChannel_thenCorrect()
  throws IOException {
    RandomAccessFile stream = new RandomAccessFile(fileName, "rw");
    FileChannel channel = stream.getChannel();
    String value = "Hello";
    byte[] strBytes = value.getBytes();
    ByteBuffer buffer = ByteBuffer.allocate(strBytes.length);
    buffer.put(strBytes);
    buffer.flip();
    channel.write(buffer);
    stream.close();
    channel.close();
 
    // verify
    RandomAccessFile reader = new RandomAccessFile(fileName, "r");
    assertEquals(value, reader.readLine());
    reader.close();
}

8. Write to file using Java 7

Java 7 introduces a new way of working with the filesystem, along with a new utility class –Files. Using the Files class, we can create, move, copy, delete files and directories as well; it also can be used to read and write to a file:

1
2
3
4
5
6
7
8
9
10
11
12
13
@Test
public void givenUsingJava7_whenWritingToFile_thenCorrect()
  throws IOException {
    String str = "Hello";
 
    Path path = Paths.get(fileName);
    byte[] strToBytes = str.getBytes();
 
    Files.write(path, strToBytes);
 
    String read = Files.readAllLines(path).get(0);
    assertEquals(str, read);
}

9. Write to temporary file

Now, let’s try to write to temporary file. The following code creates a temporary file and writes a String to it:

1
2
3
4
5
6
7
8
9
10
11
12
@Test
public void whenWriteToTmpFile_thenCorrect() throws IOException {
    String toWrite = "Hello";
    File tmpFile = File.createTempFile("test", ".tmp");
    FileWriter writer = new FileWriter(tmpFile);
    writer.write(toWrite);
    writer.close();
 
    BufferedReader reader = new BufferedReader(new FileReader(tmpFile));
    assertEquals(toWrite, reader.readLine());
    reader.close();
}

So, as you can see – it’s just the creation of the temporary file that is interesting and different – after that point, writing to the file is the same.

10. Lock File Before Writing

Finally, when writing to a file, you sometimes need to make extra sure that no one else is writing to that file at the same time. Basically – you need to be able to lock that file while writing.

Let’s make use of the FileChannel to try locking the file before writing to it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Test
public void whenTryToLockFile_thenItShouldBeLocked()
  throws IOException {
    RandomAccessFile stream = new RandomAccessFile(fileName, "rw");
    FileChannel channel = stream.getChannel();
 
    FileLock lock = null;
    try {
        lock = channel.tryLock();
    } catch (final OverlappingFileLockException e) {
        stream.close();
        channel.close();
    }
    stream.writeChars("test lock");
    lock.release();
 
    stream.close();
    channel.close();
}

Note that if the file is already locked when we try to acquire the lock, anOverlappingFileLockException will be thrown.

11. Notes

After exploring so many methods of writing to a file, let’s discuss some important notes:

  • If we try to read from a file that doesn’t exist, a FileNotFoundException will be thrown
  • If we try to write to a file that doesn’t exist, the file will be created first and no exception will be thrown
  • It is very important to close the stream after using it, as it is not closed implicitly, to release any resources associated with it
  • In output stream, the close() method calls flush() before releasing the resources which forces any buffered bytes to be written to the stream

Looking at the common usage practices, we can see – for example – that PrintWriter is used to write formatted text; FileOutputStream to write binary data; DataOutputStream to write primitive data types; RandomAccessFile to write to a specific position; FileChannel to write faster in larger files. Some of the APIs of these classes do allow more, but this is a good place to start.

12. Conclusion

This article illustrates the many options of writing data to a File using Java.

The implementation of all these examples and code snippets can be found in my github project – this is an Eclipse based project, so it should be easy to import and run as it is.

java 文件读写--转载的更多相关文章

  1. java 文件读写的有用工具

    java 文件读写的有用工具 package org.rui.io.util; import java.io.BufferedReader; import java.io.File; import j ...

  2. java文件读写的两种方式

    今天搞了下java文件的读写,自己也总结了一下,但是不全,只有两种方式,先直接看代码: public static void main(String[] args) throws IOExceptio ...

  3. java文件读写操作

    Java IO系统里读写文件使用Reader和Writer两个抽象类,Reader中read()和close()方法都是抽象方法.Writer中 write(),flush()和close()方法为抽 ...

  4. java文件读写操作类

    借鉴了项目以前的文件写入功能,实现了对文件读写操作的封装 仅仅需要在读写方法传入路径即可(可以是绝对或相对路径) 以后使用时,可以在此基础上改进,比如: 写操作: 1,对java GUI中文本框中的内 ...

  5. Java 文件读写操作

    1[1]按字节读写,一次只读取一个字节,效率比较低 package bk1; import java.io.File; import java.io.FileInputStream; import j ...

  6. Java文件读写分析

    本文内容:IO流操作文件的细节分析:分析各种操作文件的方式. 读写一个文件 从一个示例开始分析,如何操作文件: /** * 向一个文件中写入数据 * @throws IOException */ pr ...

  7. java文件读写操作指定编码格式

    读文件: BufferedReader 从字符输入流中读取文本,缓冲各个字符,从而提供字符.数组和行的高效读取. 可以指定缓冲区的大小,或者可使用默认的大小.大多数情况下,默认值就足够大了. 通常,R ...

  8. java文件读写工具类

    依赖jar:commons-io.jar 1.写文件 // by FileUtilsList<String> lines = FileUtils.readLines(file, " ...

  9. java 文件读写工具 FileUtil

    代码如下: package com.wiscom.utils; import java.io.BufferedReader; import java.io.File; import java.io.F ...

随机推荐

  1. 参考《深度学习原理与应用实践》中文PDF

    读国内关于深度学习的书籍,可以看看<深度学习原理与应用实践>,对深度学习原理的介绍比较简略(第3.4章共18页).只介绍了"神经网络"和"卷积神经网络&quo ...

  2. 洛谷——P1518 两只塔姆沃斯牛 The Tamworth Two

    https://www.luogu.org/problem/show?pid=1518 题目背景 题目描述 两只牛逃跑到了森林里.农夫John开始用他的专家技术追捕这两头牛.你的任务是模拟他们的行为( ...

  3. C# 之 继承

    继承     继承是OOP最重要的特性之中的一个.不论什么类都能够从还有一个类中继承,这就是说,这个类拥有它继承的类的全部成员. 在OOP中,被继承的类称为父类. 在C#中的对象仅能直接派生于一个基类 ...

  4. Top 16 Java 应用类 - 这些功能再也不用自己写了

    Java中有很多应用类.这些类定义静态方法能够解决非常多常见的问题.以下是通过5万个开源项目统计得到的最热门的16个应用类. 类按热门程序排列.类的方法也是按热门程序排序. 浏览这个类能够看看有哪些功 ...

  5. vim基础学习之搜索功能

    当我们使用vim看源码的时候,我们可能会碰到一个方法或者变量,我们想要知道这个变量在其他地方的使用情况.这时候我们经常的做法就是退出当前的文件,或者是重新切换一个终端,然后使用grep或者find等s ...

  6. android 图片特效处理之模糊效果

    这篇将讲到图片特效处理的模糊效果.跟前面一样是对像素点进行处理,算法是通用的,但耗时会更长,至于为什么,看了下面的代码你就会明白. 算法: 一.简单算法:将像素点周围八个点包括自身一共九个点的RGB值 ...

  7. js闭包注意事项

    /关于闭包使用应该注意的 // 1 闭包在父函数每次调用都会产生不同的闭包 // 2 闭包中子函数使用父函数变量的变量不是复制 是引用 // 3 闭包在循环中使用

  8. OpenCV —— 跟踪与运动

    理解物体运动主要包含两个部分:识别和建模 识别在视频流后续的帧中找出之前某帧镇南关的感兴趣物体 寻找角点 可跟踪的特征点都称为角点,从直观上讲,角点(而非边缘)是一类含有足够信息且能从当前帧和下一帧中 ...

  9. cap理论理解

    一个分布式系统里面,节点组成的网络本来应该是连通的.然而可能因为一些故障,使得有些节点之间不连通了,整个网络就分成了几块区域.数据就散布在了这些不连通的区域中.这就叫分区. 当你一个数据项只在一个节点 ...

  10. 2017国家集训队作业[agc014d]Black and White Tree

    2017国家集训队作业[agc014d]Black and White Tree 题意: ​ 有一颗n个点的树,刚开始每个点都没有颜色.Alice和Bob会轮流对这棵树的一个点涂色,Alice涂白,B ...