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