更新時間:2022-07-28 11:10:50 來源:動力節點 瀏覽1733次
在本Java教程中,我們將探索使用 Java 寫入文件的不同方法。我們將使用BufferedWriter、PrintWriter、FileOutputStream、DataOutputStream、RandomAccessFile、FileChannel和 Java 7 Files實用程序類。
我們還將研究在寫入時鎖定文件,并討論寫入文件的一些最終要點。
本教程是Baeldung 上的 Java“回歸基礎”系列的一部分。
讓我們從簡單開始,使用BufferedWriter將String寫入新文件:
public void whenWriteStringUsingBufferedWritter_thenCorrect()
throws IOException {
String str = "Hello";
BufferedWriter writer = new BufferedWriter(new FileWriter(fileName));
writer.write(str);
writer.close();
}
文件中的輸出將是:
Hello
然后我們可以將字符串附加到現有文件:
@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();
}
該文件將是:
Hello World
接下來,讓我們看看如何使用PrintWriter將格式化文本寫入文件:
@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();
}
生成的文件將包含:
Some String
Product name is iPhone and its price is 1000$
請注意,我們不僅將原始字符串寫入文件,而且還使用printf方法寫入了一些格式化文本。
我們可以使用FileWriter、BufferedWriter甚至System.out創建 writer 。
現在讓我們看看如何使用FileOutputStream將二進制數據寫入文件。
以下代碼將String轉換為字節并使用FileOutputStream將字節寫入文件:
@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();
}
文件中的輸出當然是:
Hello
接下來,讓我們看一下如何使用DataOutputStream將String寫入文件:
@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);
}
現在讓我們說明如何在現有文件中寫入和編輯,而不僅僅是寫入一個全新的文件或附加到現有文件。簡單地說:我們需要隨機訪問。
RandomAccessFile使我們能夠在給定偏移量的文件中的特定位置寫入 - 從文件的開頭 - 以字節為單位。
此代碼寫入一個整數值,偏移量從文件開頭給出:
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();
}
如果我們想讀取存儲在特定位置的int,我們可以使用這個方法:
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;
}
為了測試我們的函數,讓我們寫一個整數,編輯它,最后讀回它:
@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));
}
如果我們正在處理大文件,FileChannel可以比標準 IO 更快。以下代碼使用FileChannel將String寫入文件:
@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();
}
Java 7 引入了一種使用文件系統的新方法,以及一個新的實用程序類:Files。
使用Files類,我們可以創建、移動、復制和刪除文件和目錄。它還可以用于讀取和寫入文件:
@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);
}
現在讓我們嘗試寫入一個臨時文件。以下代碼創建一個臨時文件并向其中寫入一個字符串:
@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();
}
正如我們所見,有趣和不同的只是臨時文件的創建。在那之后,寫入文件是相同的。
最后,在寫入文件時,我們有時需要額外確保沒有其他人同時寫入該文件。基本上,我們需要能夠在寫入時鎖定該文件。
讓我們使用FileChannel在寫入之前嘗試鎖定文件:
@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();
}
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習