我需要將文件大小限制爲1 GB,而最好使用BufferedWriter
。使用java編寫文件時限制文件大小
是否有可能使用BufferedWriter
或者我必須使用其他庫?
像
try (BufferedWriter writer = Files.newBufferedWriter(path)) {
//...
writer.write(lines.stream());
}
我需要將文件大小限制爲1 GB,而最好使用BufferedWriter
。使用java編寫文件時限制文件大小
是否有可能使用BufferedWriter
或者我必須使用其他庫?
像
try (BufferedWriter writer = Files.newBufferedWriter(path)) {
//...
writer.write(lines.stream());
}
你總是可以編寫自己的OutputStream
限制的書面字節數。
以下假定您想要在超過尺寸時拋出異常。
public final class LimitedOutputStream extends FilterOutputStream {
private final long maxBytes;
private long bytesWritten;
public LimitedOutputStream(OutputStream out, long maxBytes) {
super(out);
this.maxBytes = maxBytes;
}
@Override
public void write(int b) throws IOException {
ensureCapacity(1);
super.write(b);
}
@Override
public void write(byte[] b) throws IOException {
ensureCapacity(b.length);
super.write(b);
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
ensureCapacity(len);
super.write(b, off, len);
}
private void ensureCapacity(int len) throws IOException {
long newBytesWritten = this.bytesWritten + len;
if (newBytesWritten > this.maxBytes)
throw new IOException("File size exceeded: " + newBytesWritten + " > " + this.maxBytes);
this.bytesWritten = newBytesWritten;
}
}
你現在當然必須手動設置Writer
/OutputStream
鏈。
final long SIZE_1GB = 1073741824L;
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
new LimitedOutputStream(Files.newOutputStream(path), SIZE_1GB),
StandardCharsets.UTF_8))) {
//
}
IIUC,有多種方法可以做到這一點。
在編寫行的情況下,對於1 GB的確切字節非常困難。每行可能包含未知數量的字節。我假設你想在文件中逐行寫入數據。
但是,您可以在將行寫入文件之前檢查行數有多少,另一種方法是在寫入每行之後檢查文件大小。
以下基本示例每次寫入同一行。這裏這只是一個測試!文本使用UTF-8編碼在文件上佔用21個字節。最終在49次寫入後達到1029字節並停止寫入。
public class Test {
private static final int ONE_KB = 1024;
public static void main(String[] args) {
File file = new File("D:/test.txt");
try (BufferedWriter writer = Files.newBufferedWriter(file.toPath())) {
while (file.length() < ONE_KB) {
writer.write("This is just a test !");
writer.flush();
}
System.out.println("1 KB Data is written to the file.!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
正如你可以看到,我們已經寫出來1KB的限制如上程序寫入1029個字節和不小於1024個字節。
第二種方法是在寫入文件之前根據特定的編碼檢查字節。
public class Test {
private static final int ONE_KB = 1024;
public static void main(String[] args) throws UnsupportedEncodingException {
File file = new File("D:/test.txt");
String data = "This is just a test !";
int dataLength = data.getBytes("UTF-8").length;
try (BufferedWriter writer = Files.newBufferedWriter(file.toPath())) {
while (file.length() + dataLength < ONE_KB) {
writer.write(data);
writer.flush();
}
System.out.println("1 KB Data written to the file.!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
在這種方法中,我們在它之前寫入文件校驗字節的長度。所以,它會寫1008字節,它將停止寫入。
問題有兩種方法,
不過,也有其他的方法來做到這一點的驗證與一些第三方庫像阿帕奇IO,我覺得它更麻煩那麼傳統的Java方法。
int maxSize = 1_000_000_000;
Charset charset = StandardCharsets.UTF_F);
int size = 0;
int lineCount = 0;
while (lineCount < lines.length) {
long size2 = size + (lines[lineCount] + "\r\n").getBytes(charset).length;
if (size2 > maxSize) {
break;
}
size = size2;
++lineCount;
}
List<String> linesToWrite = lines.substring(0, lineCount);
Path path = Paths.get("D:/test.txt");
Files.write(path, linesToWrite , charset);
或在解碼只有一次有點快:
int lineCount = 0;
try (FileChannel channel = new RandomAccessFile("D:/test.txt", "w").getChannel()) {
ByteBuffer buf = channel.map(FileChannel.MapMode.WRITE, 0, maxSize);
lineCount = lines.length;
for (int i = 0; i < lines.length; i++) {
bytes[] line = (lines.get(i) + "\r\n").getBytes(charset);
if (line.length > buffer.remaining()) {
lineCount = i;
break;
}
buffer.put(line);
}
}
檢查:http://stackoverflow.com/questions/17746114/limiting-file-size-creation-with-java – Azodious
* ..限制文件大小爲1 GB *所以,你想寫內容高達1GB?或者只有在內容小於1 GB時纔想寫內容? –
想要停止寫入,一旦它達到1 GB .. @TAsk – hacker