在用java编写时限制文件大小
我需要将文件大小限制为1 GB,同时最好使用在用java编写时限制文件大小,java,file,bufferedwriter,Java,File,Bufferedwriter,我需要将文件大小限制为1 GB,同时最好使用BufferedWriter进行写入 是否可以使用BufferedWriter或我必须使用其他库 像 IIUC,有多种方法可以做到这一点 继续在卡盘中写入数据并刷新,每次刷新后继续检查文件大小 使用log4j(或一些日志框架),它可以让我们在特定的大小、时间或其他触发点之后滚动到新文件 虽然BufferedReader很棒,但是java中有一些新的API可以让它更快 您始终可以编写自己的OutputStream,以限制写入的字节数 以下假设您希望在超出
BufferedWriter
进行写入
是否可以使用BufferedWriter
或我必须使用其他库
像
IIUC,有多种方法可以做到这一点
您始终可以编写自己的
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))) {
//
}
在写行的情况下,将字节精确到1GB是非常困难的。每行可能包含未知数量的字节。我假设您想在文件中逐行写入数据 不过,您可以在将行写入文件之前检查行有多少字节,另一种方法是在写入每行之后检查文件大小 下面的基本示例每次写一行。这只是一个测试!文本以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();
}
}
}
公共类测试{
私有静态final int ONE_KB=1024;
公共静态void main(字符串[]args){
File File=新文件(“D:/test.txt”);
try(BufferedWriter=Files.newBufferedWriter(file.toPath())){
while(file.length()<1KB){
写(“这只是一个测试!”);
writer.flush();
}
System.out.println(“1KB的数据写入文件!”;
}捕获(IOE异常){
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();
}
}
}
公共类测试{
私有静态final int ONE_KB=1024;
公共静态void main(字符串[]args)引发UnsupportedEncodingException{
File File=新文件(“D:/test.txt”);
String data=“这只是一个测试!”;
int dataLength=data.getBytes(“UTF-8”).length;
try(BufferedWriter=Files.newBufferedWriter(file.toPath())){
while(file.length()+数据长度<1KB){
writer.write(数据);
writer.flush();
}
System.out.println(“写入文件的1KB数据!”;
}捕获(IOE异常){
e、 printStackTrace();
}
}
}
在这种方法中,我们在将字节写入文件之前检查字节的长度。因此,它将写入1008字节,并将停止写入
两种方法都存在问题
- 写和检查:您可能会得到一些额外的字节,文件大小可能会超过限制
- 检查并写入:如果下一行中有大量数据,则字节数可能少于限制。你应该注意编码
intmaxsize=1_000_000;
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);
字符集字符集=标准字符集.UTF\u F);
int size=0;
int lineCount=0;
while(lineCountmaxSize){
打破
}
尺寸=尺寸2;
++行数;
}
List linesToWrite=行。子字符串(0,行计数);
Path Path=Path.get(“D:/test.txt”);
write(路径、linesToWrite、字符集);
或者在只解码一次的情况下速度稍微快一点:
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);
}
}
int lineCount=0;
try(FileChannel channel=newrandomAccessFile(“D:/test.txt”,“w”).getChannel()){
ByteBuffer buf=channel.map(FileChannel.MapMode.WRITE,0,maxSize);
lineCount=lines.length;
对于(int i=0;ibuffer.remaining()){
lineCount=i;
打破
}
缓冲区。放置(行);
}
}
选中此项:…将文件大小限制为1GB,以便将内容写入1GB?或者仅当内容小于1 GB时才写入内容?要在内容达到1 GB时停止写入吗@TAskStop,如丢弃任何额外数据,或抛出异常“文件太大”?但如何确定文件大小是否达到1GB
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);
}
}