22
22
import org .slf4j .LoggerFactory ;
23
23
24
24
import java .io .*;
25
+ import java .util .Arrays ;
25
26
import java .util .LinkedHashMap ;
26
27
import java .util .Map ;
27
28
@@ -51,9 +52,18 @@ public synchronized boolean loadExisting() {
51
52
if (!da .loadExisting ())
52
53
return false ;
53
54
55
+ if (da .getCapacity () > Integer .MAX_VALUE ) {
56
+ throw new IllegalStateException ("Properties file is too large: " + da .getCapacity ());
57
+ }
54
58
int len = (int ) da .getCapacity ();
55
59
byte [] bytes = new byte [len ];
56
- da .getBytes (0 , bytes , len );
60
+ int segmentSize = da .getSegmentSize ();
61
+ for (int bytePos = 0 ; bytePos < len ; bytePos += segmentSize ) {
62
+ int partLen = Math .min (bytes .length - bytePos , segmentSize );
63
+ byte [] part = new byte [partLen ];
64
+ da .getBytes (bytePos , part , part .length );
65
+ System .arraycopy (part , 0 , bytes , bytePos , partLen );
66
+ }
57
67
try {
58
68
loadProperties (map , new StringReader (new String (bytes , UTF_CS )));
59
69
return true ;
@@ -63,21 +73,23 @@ public synchronized boolean loadExisting() {
63
73
}
64
74
65
75
public synchronized void flush () {
66
- try {
67
- StringWriter sw = new StringWriter ();
68
- saveProperties (map , sw );
69
- // TODO at the moment the size is limited to da.segmentSize() !
70
- byte [] bytes = sw .toString ().getBytes (UTF_CS );
71
- da .setBytes (0 , bytes , bytes .length );
72
- da .flush ();
73
- // todo: would not be needed if the properties file used a format that is compatible with common text tools
74
- if (dir .getDefaultType ().isStoring ()) {
75
- try (BufferedWriter writer = new BufferedWriter (new FileWriter (dir .getLocation () + "/properties.txt" ))) {
76
- writer .write (sw .toString ());
77
- }
76
+ String props = saveProperties (map );
77
+ byte [] bytes = props .getBytes (UTF_CS );
78
+ da .ensureCapacity (bytes .length );
79
+ int segmentSize = da .getSegmentSize ();
80
+ for (int bytePos = 0 ; bytePos < bytes .length ; bytePos += segmentSize ) {
81
+ int partLen = Math .min (bytes .length - bytePos , segmentSize );
82
+ byte [] part = Arrays .copyOfRange (bytes , bytePos , bytePos + partLen );
83
+ da .setBytes (bytePos , part , part .length );
84
+ }
85
+ da .flush ();
86
+ // todo: would not be needed if the properties file used a format that is compatible with common text tools
87
+ if (dir .getDefaultType ().isStoring ()) {
88
+ try (BufferedWriter writer = new BufferedWriter (new FileWriter (dir .getLocation () + "/properties.txt" ))) {
89
+ writer .write (props );
90
+ } catch (IOException e ) {
91
+ throw new RuntimeException (e );
78
92
}
79
- } catch (IOException ex ) {
80
- throw new RuntimeException (ex );
81
93
}
82
94
}
83
95
@@ -147,10 +159,20 @@ public synchronized String toString() {
147
159
return da .toString ();
148
160
}
149
161
162
+ static String saveProperties (Map <String , String > map ) {
163
+ StringBuilder builder = new StringBuilder ();
164
+ for (Map .Entry <String , String > e : map .entrySet ()) {
165
+ builder .append (e .getKey ());
166
+ builder .append ('=' );
167
+ builder .append (e .getValue ());
168
+ builder .append ('\n' );
169
+ }
170
+ return builder .toString ();
171
+ }
172
+
150
173
static void loadProperties (Map <String , String > map , Reader tmpReader ) throws IOException {
151
- BufferedReader reader = new BufferedReader (tmpReader );
152
- String line ;
153
- try {
174
+ try (BufferedReader reader = new BufferedReader (tmpReader )) {
175
+ String line ;
154
176
while ((line = reader .readLine ()) != null ) {
155
177
if (line .startsWith ("//" ) || line .startsWith ("#" )) {
156
178
continue ;
@@ -170,8 +192,6 @@ static void loadProperties(Map<String, String> map, Reader tmpReader) throws IOE
170
192
String value = line .substring (index + 1 );
171
193
map .put (field .trim (), value .trim ());
172
194
}
173
- } finally {
174
- reader .close ();
175
195
}
176
196
}
177
197
}
0 commit comments