我有一个tasks列表对象,正在迭代并将每个任务对象附加到StringBuilder新行之后,如下所示。现在,我将继续在同一字符串生成器中附加任务对象,直到达到60000字节的大小限制。一旦达到限制,我将在地图中将此字符串填充为一个值,键将是带有增量索引的文件名。然后,我将重置字符串生成器和其他内容,然后再次重复此过程。
tasks
StringBuilder
因此,如果我有一个大tasks对象,那么我将拆分为多个字符串对象,其大小应始终小于60000字节。
我得到了下面的代码,但是我总是看到映射中的值的大小大于60000字节。我做错了什么?另外,我HashMap在两个不同的地方进行填充- 一个是达到限制,另一个是没有达到限制。
HashMap
public void populate(final List<Task> tasks) { Map<String, String> holder = new HashMap<>(); int size = 0; int index = 0; StringBuilder sb = new StringBuilder(); for (Task task : tasks) { sb.append(task).append(System.getProperty("line.separator")); size = sb.toString().getBytes(StandardCharsets.UTF_8).length; if (size > 60000) { String fileName = "tasks_info_" + index + ".txt"; holder.put(fileName, sb.toString()); index++; sb = new StringBuilder(); size = 0; } } // for cases where we don't reach the limit if(sb.toString().length > 0) { String fileName = "tasks_info_" + index + ".txt"; holder.put(fileName, sb.toString()); } System.out.println(holder); }
注意: 如果每个Task对象都大于个60000 bytes,则我将立即将该对象放下并移至下一个条目。但实际上,它不会发生。
60000 bytes
更新:
public void populate(final List<Task> tasks, final long timestamp) { Map<String, String> holder = new HashMap<>(); int size = 0; int index = 0; int nl = System.getProperty("line.separator").getBytes(StandardCharsets.UTF_8).length; StringBuilder sb = new StringBuilder(); // new change sb.append(timestamp).append(System.getProperty("line.separator")); for (Task task : tasks) { int ts = String.valueOf(task).getBytes(StandardCharsets.UTF_8).length; if (size + ts + nl > 60000) { String fileName = "tasks_info_" + index + ".txt"; holder.put(fileName, sb.toString()); index++; sb = new StringBuilder(); // new change sb.append(timestamp).append(System.getProperty("line.separator")); size = 0; } sb.append(task).append(System.getProperty("line.separator")); size += ts + nl; } // for cases where we don't reach the limit if (size > 0) { // size can only be 0 if you have 0 tasks String fileName = "tasks_info_" + index + ".txt"; holder.put(fileName, sb.toString()); } System.out.println(holder); }
其他答案已经提到了它不起作用的原因(在超出限制后添加)。但是我认为到目前为止,所有实现都不正确,这不仅是因为省略了换行符的大小。
public Map<String, String> populate(final List<Task> tasks) { Map<String, String> holder = new HashMap<>(); if (tasks.size() == 0) return holder; int index = 0; int nl = System.getProperty("line.separator").getBytes(StandardCharsets.UTF_8).length; StringBuilder sb = new StringBuilder(); sb.append(System.currentTimeMillis()).append(System.getProperty("line.separator")); int size = sb.toString().getBytes(StandardCharsets.UTF_8).length; for (Task task : tasks) { int ts = String.valueOf(task).getBytes(StandardCharsets.UTF_8).length; if (size + ts + nl > 60000) { String fileName = "tasks_info_" + index + ".txt"; holder.put(fileName, sb.toString()); index++; sb = new StringBuilder(); sb.append(System.currentTimeMillis()).append(System.getProperty("line.separator")); size = sb.toString().getBytes(StandardCharsets.UTF_8).length; } sb.append(task).append(System.getProperty("line.separator")); size += ts + nl; } String fileName = "tasks_info_" + index + ".txt"; holder.put(fileName, sb.toString()); return holder; }