2016-08-23 58 views
2

ファイルサイズを1 GBに制限する必要があります。書き込みは、好ましくはBufferedWriterです。Javaでの書き込み中のファイルサイズの制限

BufferedWriterを使用することは可能ですか他のライブラリを使用する必要がありますか?

try (BufferedWriter writer = Files.newBufferedWriter(path)) { 
    //... 
    writer.write(lines.stream()); 
} 
+0

これをチェックしてください:http://stackoverflow.com/questions/17746114/limiting-file-size-creation-with-java – Azodious

+0

* .. 1GBにファイルサイズを制限する*したがって、1GBまでのコンテンツを書きたいと思っていますか?または、1 GB未満の場合にのみコンテンツを書きたいと思っていますか? –

+1

1GBに達したら書込みを停止したい。@TAsk – hacker

答えて

5

あなたはいつも書かバイトの数を制限するために、独自の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))) { 
    // 
} 
-1

IIUCのように、それを行うための様々な方法があります。

  1. データをチャックに書き込んだり、フラッシュしたり、フラッシュするたびにファイルサイズをチェックしたりしてください。
  2. log4j(またはいくつかのロギングフレームワーク)を使用すると、特定のサイズや時間などのトリガーポイントの後に新しいファイルにロールオーバーすることができます。
  3. BufferedReaderは優れていますが、javaには新しいAPIがいくつか追加されています。 Fastest way to write huge data in text file Java
2

行を書き込む場合、正確なバイト数は1 GBまで非常に困難です。各行には、未知数のバイトが含まれている場合があります。私は、ファイルごとに行ごとにデータを書きたいと仮定しています。

ただし、行がファイルに書き込む前にいくつのバイトがあるかを調べることができます。もう1つのアプローチは、各行を書き込んだ後でファイルサイズを確認することです。

次の基本例は、毎回同じ行を書き込みます。ここではこれは単なるテストです!テキストは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(); 
     } 
    } 
} 

あなたはプログラムが1029バイトではなく1024未満のバイトを書き込み、上記のように、我々はすでに1キロバイトの限界の外に書かれている見ることができるように。

第2のアプローチは、ファイルに書き込む前に、特定のエンコーディングに従ってバイトをチェックしています。

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 apacheのようないくつかのサードパーティ製のライブラリと、この検証を行うための他の方法があると私はそれより厄介次に、従来のJavaの方法を見つけます。

0
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); 
    } 
} 
関連する問題