Ограничение размера java файла

Ограничить размер файла при записи в java

Мне нужно ограничить размер файла до 1 ГБ при записи, предпочтительно используя BufferedWriter .

Возможно ли использование 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; > > 

Вы, конечно, теперь должны вручную OutputStream цепочку 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 ГБ очень сложны в случаях, когда вы пишете строки. Каждая строка может содержать неизвестное количество байтов. Я предполагаю, что вы хотите писать данные по строкам в файле.

Тем не менее, вы можете проверить, сколько байтов имеет строка, прежде чем записывать ее в файл, а другой подход – проверить размер файла после записи каждой строки.

Следующий базовый пример записывает одну и ту же строку каждый раз. Вот это просто тест! текст занимает 21 байт в файле в кодировке UTF-8. В конечном итоге после 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(); >> > 

Как вы можете видеть, мы уже выписали из лимита 1 КБ, как описано выше, программа пишет 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 байт и перестанет писать.

  • Запись и проверка: у вас могут быть дополнительные байты, а размер файла может пересечь границу
  • Проверка и запись: у вас может быть меньше байтов, чем предел, если в следующей строке есть много данных. Вы должны быть осторожны с кодировкой.

Тем не менее, есть другие способы сделать эту проверку с помощью некоторой сторонней библиотеки, такой как apache 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 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); > > 

IIUC, есть различные способы сделать это.

  1. Храните записи в патронах и промывайте их и продолжайте проверять размер файла после каждого флеша.
  2. Используйте log4j (или некоторую структуру ведения журнала), которая позволяет нам опрокинуться на новый файл после определенного размера или времени или какой-либо другой точки запуска.
  3. В то время как BufferedReader замечательный, в java есть несколько новых API, которые могли бы ускорить работу. Самый быстрый способ записи огромных данных в текстовый файл Java
Читайте также:  Fixed width css grid

Источник

Ограничение размера файла с помощью java

Я пытаюсь ограничить размер создания одного файла в своем приложении java. Для этого я сделал этот образец кода, который объявляю одну переменную длиной 32 байт, начните метод WriteOnFile, зацикливая его до 32 байт. Проблема в том, что не имеет значения значение, установленное мною в FILE_SIZE (выше или ниже), файл загрузки всегда идет с 400kb – это значит, что мой код работает, так как исходный файл 200Mb, но имеет некоторую логическую ошибку. есть ли другой способ сделать это? Потому что я основывался на этом сообщении Как ограничить размер файла на Java и до сих пор не нашел ничего лучше

Мне было интересно, есть ли у этого что-то с буферизатором…

Заранее спасибо за помощь

public static final byte FILE_SIZE = 32; private static void WriteOnFile(BufferedWriter writer, String crawlingNode) < try < while(file.length()> catch (IOException e) < JOptionPane.showMessageDialog(null, "Failed to write URL Node"); e.printStackTrace(); >> 

Я нашел свой собственный ответ. Да, это должно быть с буферизированным писателем. Буферный писатель имеет буфер по умолчанию 8 КБ для READ. Для написания этого буфера сбрасывается каждый 400 кб в моем приложении. Чтобы записать файл с меньшим размером, нам нужно использовать другой способ записи типа OutputSteam..

Я просто немного потрудился, и я мог писать файлы размером 32 байта, ограничивая метод write BufferWriter напрямую:

 writer.write(crawlingNode, 0, 32); 

С этим вызовом в файл записываются только первые 32 символа. Поскольку моя кодировка была UTF-8, это означает, что каждый символ занимает один байт, размер моего выходного файла составляет всего 32 байта. Запись только 16 символов привела к файлу из 16 байт и так далее.

Так что, возможно, вы могли бы использовать это, не применяя некоторые другие большие вещи.

РЕДАКТИРОВАТЬ:

Если ваша строка имеет меньше символов, чем 32, используйте следующий вызов:

writer.write(crawlingNode, 0, crawlingNode.length); 

Используйте поток, чтобы ограничить размер файла, не полагайтесь на file.length().

Но вы также можете написать свой собственный.

Источник

Как ограничить размер файла в Java

Я создаю файл в своем приложении, и я продолжаю писать некоторый контент в этот файл. Но после того, как мой файл достигнет некоторого размера, скажем, 100 строк, я хочу стереть первую строку и записать новую строку внизу. Требование — мой файл должен быть ограничен, но он должен поддерживать последний контент, который я написал в файл. Пожалуйста, дайте мне знать, если это возможно на Java? Пожалуйста, дайте мне знать, есть ли альтернатива для этого.

Читайте также:  What does implements do in java

Может быть, у вас может быть код, который разделит ваш файл на другой, если количество строк превышает 100 строк, и удалите старую? Конечно, это дороже, чем то, что вы искали, но это может решить вашу проблему.

3 ответа

Пожалуйста, дайте мне знать, возможно ли это на Java?

Это невозможно сделать простым способом. Вы можете только обрезать последнюю часть файла. (Это предел наследования от базовой файловой системы и по тем же причинам, почему вы не можете вставлять байты в середине файла.)

Вы можете сделать это вручную:

  • Вычисление длины байта, n , первой строки.
  • Для i = n . length of file
    • Записать байт в pos i в pos i — n

    Пожалуйста, дайте мне знать, есть ли альтернатива для этого.

    Я предлагаю вам решить его с помощью циклического буфера или чего-то подобного. Тем не менее, у вас возникнут проблемы, если не все строки будут одинаково длинными, если вы не сохраните буфер в памяти и не выгрузите его в (очищенный) файл.

    Это работает, но может быть очень медленным процессом в зависимости от того, как вы его реализуете. По крайней мере, сохраните 100 строк в памяти в структуре данных, например Vector, чтобы каждый раз вам не приходилось читать файл, просто пишите его каждый раз, когда вы бросаете первый элемент и добавляете новый конечный элемент.

    Другой альтернативой будет сохранение каждой строки в собственном файле. Затем вы просто удаляете файл и создаете новый, для каждой новой строки после 100-го.

    [намного позже] Подумали о другом способе записи фиксированной длины, если ваши строки имеют прогнозируемый размер. Каждая строка представляет собой пробел, за которым следует текст, а затем пробелы, чтобы вычеркнуть запись, с концевыми символами на конце, если это необходимо. Каждый раз, когда вы пишете запись, вы добавляете ее звездочкой, чтобы пометить ее как текущую строку, а затем проиндексируйте ее в предыдущую строку (с оператором modulo, чтобы она автоматически обернулась) и замените звездочку пробелом. Пример 10-строчного файла журнала будет выглядеть примерно так:
     this happened at that time blah blah happened *this is the current record this was the fourth event to occur after startup this was the fifth event to occur after startup this was the sixth event to occur after startup this was the seventh event to occur after startup this was the eighth event to occur after startup this was the ninth event to occur after startup this was the tenth event to occur after startup 

    Таким образом вам нужно только открыть файл, индексировать текущую строку (что вы знаете, потому что вы отслеживаете в своей программе, в противном случае при перезапуске, петля, чтобы найти звездочку), и перезапишите ее, отложив ее с пробелами до выбранной длины. затем индексируйте одну запись и замените звездочку пробелом.

    Источник

    Как ограничить размер файла в Java

    Я создаю файл в своем приложении, и я продолжаю записывать в этот файл некоторый контент. Но после того, как мой файл достигает некоторого размера, скажем, 100 строк, я хочу стереть первую строку и записать новую строку внизу. Требование состоит в том, что мой файл должен быть ограничен, но он должен поддерживать последнее содержимое, которое я записал в файл. Пожалуйста, дайте мне знать, возможно ли это на Java? Пожалуйста, дайте мне знать, если есть какая-либо альтернатива для этого.

    Может быть, вы могли бы иметь код, который будет разбивать ваш файл на другой, когда количество строк больше 100 строк, и удалять старый? Конечно, это дороже процессорного времени, чем то, что вы искали, но это может решить вашу проблему. — newbie

    3 ответы

    1. Вычисляя длину байта, n , первой строки.
    2. Для i = n . length of file
      1. Записать байт в pos i позировать i — n

      Пожалуйста, дайте мне знать, если есть какая-либо альтернатива для этого.

      Я предлагаю вам решить ее с помощью циклического буфера или чего-то подобного. Тем не менее, у вас могут возникнуть проблемы, если не все строки будут одинаковой длины, если только вы не сохраните буфер в памяти и не сбросите его в (очищенный) файл.

      Это выполнимо, но может быть очень медленным процессом в зависимости от того, как вы его реализуете. По крайней мере, держите 100 строк в памяти в структуре данных, такой как вектор, чтобы вам не приходилось каждый раз читать файл, просто записывайте его каждый раз, когда вы отбрасываете первый элемент и добавляете новый последний элемент.

      Другой альтернативой может быть хранение каждой строки в отдельном файле. Затем вы просто удаляете файл и создаете новый для каждой новой строки после сотой.

      [намного позже] Мы придумали другой способ, записи фиксированной длины, если ваши строки имеют предсказуемый размер. Каждая строка представляет собой пробел, за которым следует текст, за которым следуют пробелы для дополнения записи, с символами конца строки в конце, если это необходимо. Каждый раз, когда вы пишете запись, вы добавляете к ней звездочку, чтобы пометить ее как текущую строку, а затем индексируете предыдущую строку (с оператором по модулю, чтобы она автоматически переносилась) и заменяете эту звездочку пробелом. Пример 10-строчного лог-файла будет выглядеть примерно так:
       this happened at that time blah blah happened *this is the current record this was the fourth event to occur after startup this was the fifth event to occur after startup this was the sixth event to occur after startup this was the seventh event to occur after startup this was the eighth event to occur after startup this was the ninth event to occur after startup this was the tenth event to occur after startup 

      Таким образом, вам нужно только открыть файл, проиндексировать текущую строку (которую вы знаете, потому что отслеживаете в своей программе; в противном случае при перезапуске выполните цикл, чтобы найти звездочку), и перезапишите его, дополнив пробелами для выбранная длина. затем проиндексируйте одну запись и замените звездочку пробелом.

      Источник

Оцените статью