add more serialization support for various libraries
[storage-units.git] / README.asciidoc
blobe56d6431bc189ff82940821c6439a4e83c1a6b00
1 = Storage-Units image:https://img.shields.io/badge/email-%40metio-brightgreen.svg?style=social&label=mail["Discuss on Google Groups", link="https://groups.google.com/forum/#!forum/metio"] image:https://img.shields.io/badge/irc-%23metio.wtf-brightgreen.svg?style=social&label=IRC["Chat on IRC", link="http://webchat.freenode.net/?channels=metio.wtf"]
2 Sebastian Hoß <http://seb.xn--ho-hia.de/[@sebhoss]>
3 :github-org: sebhoss
4 :project-name: storage-units
5 :project-group: de.xn--ho-hia.storage_units
6 :coverity-project: 2658
7 :codacy-project: d3cfbbc415c14b79a661d573ac11e68c
8 :toc:
9 :toc-placement: preamble
11 image:https://img.shields.io/badge/license-cc%20zero-000000.svg?style=flat-square["CC Zero", link="http://creativecommons.org/publicdomain/zero/1.0/"]
12 pass:[<span class="image"><a class="image" href="https://maven-badges.herokuapp.com/maven-central/de.xn--ho-hia.storage_units/storage-units"><img src="https://img.shields.io/maven-central/v/de.xn--ho-hia.storage_units/storage-units.svg?style=flat-square" alt="Maven Central"></a></span>]
13 pass:[<span class="image"><a class="image" href="https://www.javadoc.io/doc/de.xn--ho-hia.storage_units/storage-units"><img src="https://www.javadoc.io/badge/de.xn--ho-hia.storage_units/storage-units.svg?style=flat-square&color=blue" alt="Read JavaDocs"></a></span>]
14 image:https://reposs.herokuapp.com/?path={github-org}/{project-name}&style=flat-square["Repository size"]
15 image:https://www.openhub.net/p/{project-name}/widgets/project_thin_badge.gif["Open Hub statistics", link="https://www.openhub.net/p/{project-name}"]
17 image:https://img.shields.io/travis/{github-org}/{project-name}/master.svg?style=flat-square["Build Status", link="https://travis-ci.org/{github-org}/{project-name}"]
18 image:https://img.shields.io/coveralls/{github-org}/{project-name}/master.svg?style=flat-square["Code Coverage", link="https://coveralls.io/github/{github-org}/{project-name}"]
19 image:https://img.shields.io/coverity/scan/{coverity-project}.svg?style=flat-square["Coverity Scan Result", link="https://scan.coverity.com/projects/{github-org}-{project-name}"]
20 image:https://img.shields.io/codacy/grade/{codacy-project}.svg?style=flat-square["Codacy Code Quality", link="https://www.codacy.com/app/mail_7/{project-name}"]
21 image:https://img.shields.io/badge/forkable-yes-brightgreen.svg?style=flat-square["Can this project be forked?", link="https://basicallydan.github.io/forkability/?u={github-org}&r={project-name}"]
22 image:https://img.shields.io/maintenance/yes/.svg?style=flat-square["Is this thing still maintained?"]
23 image:https://img.shields.io/bountysource/team/metio/activity.svg?style=flat-square["Bounties on open tickets", link="https://www.bountysource.com/teams/metio"]
25 https://www.java.com[Java] library for storage-/byte-units. All units defined in link:http://en.wikipedia.org/wiki/ISO/IEC_80000[ISO IEC 80000-13:2008] are supported, as well as other commonly found units, like 1 Kilobyte = 1024 Byte.
27 === Features
29 * Immutable, type- and thread-safe object model for storage units
30 * Convenience factories to create units
31 * Basic arithmetic operators
32 * Comparisons and equality checks between units
33 * Lossless conversion between all units
34 * Human readable text format, including custom formats
35 * Compatible with any `java.lang.Number`
36 * Custom serializers for Jackson, MongoDB & EclipseLink
38 ==== Available Units
40 .Binary units
41 |===
42 | Name | Symbol | Exponential | Absolute | Class
44 | Byte
45 | B
46 | 2 ^0^ Byte
47 | 1 Byte
48 | `Byte`
50 | Kibibyte
51 | KiB
52 | 2 ^10^ Byte
53 | 1 024 Byte
54 | `Kibibyte`
56 | Mebibyte
57 | MiB
58 | 2 ^20^ Byte
59 | 1 048 576 Byte
60 | `Mebibyte`
62 | Gibibyte
63 | GiB
64 | 2 ^30^ Byte
65 | 1 073 741 824 Byte
66 | `Gibibyte`
68 | Tebibyte
69 | TiB
70 | 2 ^40^ Byte
71 | 1 099 511 627 776 Byte
72 | `Tebibyte`
74 | Pebibyte
75 | PiB
76 | 2 ^50^ Byte
77 | 1 125 899 906 842 624 Byte
78 | `Pebibyte`
80 | Exbibyte
81 | EiB
82 | 2 ^60^ Byte
83 | 1 152 921 504 606 846 976 Byte
84 | `Exbibyte`
86 | Zebibyte
87 | ZiB
88 | 2 ^70^ Byte
89 | 1 180 591 620 717 411 303 424 Byte
90 | `Zebibyte`
92 | Yobibyte
93 | YiB
94 | 2 ^80^ Byte
95 | 1 208 925 819 614 629 174 706 176 Byte
96 | `Yobibyte`
97 |===
99 .Decimal units
100 |===
101 | Name | Symbol | Exponential | Absolute | Class
103 | Byte
104 | B
105 | 10 ^0^ Byte
106 | 1 Byte
107 | `Byte`
109 | Kilobyte
110 | kB
111 | 10 ^3^ Byte
112 | 1 000 Byte
113 | `Kilobyte`
115 | Megabyte
116 | MB
117 | 10 ^6^ Byte
118 | 1 000 000 Byte
119 | `Megabyte`
121 | Gigabyte
122 | GB
123 | 10 ^9^ Byte
124 | 1 000 000 000 Byte
125 | `Gigabyte`
127 | Terabyte
128 | TB
129 | 10 ^12^ Byte
130 | 1 000 000 000 000 Byte
131 | `Terabyte`
133 | Petabyte
134 | PB
135 | 10 ^15^ Byte
136 | 1 000 000 000 000 000 Byte
137 | `Petabyte`
139 | Exabyte
140 | EB
141 | 10 ^18^ Byte
142 | 1 000 000 000 000 000 000 Byte
143 | `Exabyte`
145 | Zettabyte
146 | ZB
147 | 10 ^21^ Byte
148 | 1 000 000 000 000 000 000 000 Byte
149 | `Zettabyte`
151 | Yottabyte
152 | YB
153 | 10 ^24^ Byte
154 | 1 000 000 000 000 000 000 000 000 Byte
155 | `Yottabyte`
156 |===
158 == Usage
160 === Factories
162 Each unit implements a Byte-based static factory method (`valueOf(BigInteger)` or `valueOf(long)`) that can be used to represent a given number of bytes in a specific unit. Note that `Long.MAX_VALUE == 8 Exabyte`, thus use `BigInteger` if you want to work with anything bigger than a eight Exabyte. When in doubt, always use `BigInteger`.
164 [source,java]
165 ----
166 // 'long' based
167 Kilobyte unit = Kilobyte.valueOf(500)               // 500 Byte or "0.50 kB"
168 Kibibyte unit = Kibibyte.valueOf(512)               // 512 Byte or "0.50 KiB"
170 Megabyte unit = Megabyte.valueOf(1_000_000)             // 1 000 000 Byte or "1.00 MB"
171 Mebibyte unit = Mebibyte.valueOf(1_048_576)             // 1 048 576 Byte or "1.00 MiB"
173 // 'BigInteger' based
174 Kilobyte unit = Kilobyte.valueOf(BigInteger.valueOf(500))               // 500 Byte or "0.50 kB"
175 Kibibyte unit = Kibibyte.valueOf(BigInteger.valueOf(512))               // 512 Byte or "0.50 KiB"
177 Megabyte unit = Megabyte.valueOf(BigInteger.valueOf(1000000))               // 1 000 000 Byte or "1.00 MB"
178 Mebibyte unit = Mebibyte.valueOf(BigInteger.valueOf(1_048_576))             // 1 048 576 Byte or "1.00 MB"
179 ----
181 The `StorageUnits` class offers three factory methods that automatically pick the best-matching unit for a given number of bytes.
183 ==== Binary Units
185 [source,java]
186 ----
187 // 'long' based
188 StorageUnit<?> unit = StorageUnits.binaryValueOf(256)       // Kibibyte (0.25 KiB)
189 StorageUnit<?> unit = StorageUnits.binaryValueOf(1048576)   // Mebibyte (1.00 MiB)
191 // 'BigInteger' based
192 StorageUnit<?> unit = StorageUnits.binaryValueOf(BigInteger.valueOf(256))     // Kibibyte (0.25 MiB)
193 StorageUnit<?> unit = StorageUnits.binaryValueOf(BigInteger.valueOf(1048576)) // Mebibyte (1.00 MiB)
194 ----
196 ==== Decimal Units
198 [source,java]
199 ----
200 // 'long' based
201 StorageUnit<?> unit = StorageUnits.decimalValueOf(120000)    // Kilobyte (120.00 kB)
202 StorageUnit<?> unit = StorageUnits.decimalValueOf(1000000)   // Megabyte (1.00 MB)
204 // 'BigInteger' based
205 StorageUnit<?> unit = StorageUnits.decimalValueOf(BigInteger.valueOf(120000))    // Kilobyte (120.00 kB)
206 StorageUnit<?> unit = StorageUnits.decimalValueOf(BigInteger.valueOf(1000000))   // Megabyte (1.00 MB)
207 ----
209 Additionally high-level factory methods are also available in the `StorageUnits` class.
211 [source,java]
212 ----
213 import static wtf.metio.storageunits.StorageUnits.*;
215 Kibibyte unit = kibibyte(1)   // 1 024 Byte
216 Mebibyte unit = mebibyte(1)   // 1 048 576 Byte
217 Gibibyte unit = gibibyte(1)   // 1 073 741 824 Byte
218 Tebibyte unit = tebibyte(1)   // 1 099 511 627 776 Byte
219 Pebibyte unit = pebibyte(1)   // 1 125 899 906 842 624 Byte
220 Exbibyte unit = exbibyte(1)   // 1 152 921 504 606 846 976 Byte
221 Zebibyte unit = zebibyte(1)   // 1 180 591 620 717 411 303 424 Byte
222 Yobibyte unit = yobibyte(1)   // 1 208 925 819 614 629 174 706 176 Byte
224 Kilobyte unit = kilobyte(1)   // 1 000 Byte
225 Megabyte unit = megabyte(1)   // 1 000 000 Byte
226 Gigabyte unit = gigabyte(1)   // 1 000 000 000 Byte
227 Terabyte unit = terabyte(1)   // 1 000 000 000 000 Byte
228 Petabyte unit = petabyte(1)   // 1 000 000 000 000 000 Byte
229 Exabyte unit = exabyte(1)     // 1 000 000 000 000 000 000 Byte
230 Zettabyte unit = zettabyte(1) // 1 000 000 000 000 000 000 000 Byte
231 Yottabyte unit = yottabyte(1) // 1 000 000 000 000 000 000 000 000 Byte
232 ----
234 === Add, Subtract, Multiply, Divide
236 Each unit implements the basic four math operations. All operations retain their original type, e.g. `[Kilobyte] + [Megabyte] = [Kilobyte]`
238 [source,java]
239 ----
240 import static wtf.metio.storageunits.StorageUnits.*;
242 kilobyte(4).add(kilobyte(8))        // 4 Kilobyte + 8 Kilobyte = 12 Kilobyte = 12 000 Byte
243 kibibyte(1).add(1024)               // 1 Kibibyte + 1 024 Byte = 2 Kibibyte = 2 048 Byte
244 kibibyte(1).subtract(24)            // 1 024 Byte - 24 Byte = 1 000 Byte
245 megabyte(5).subtract(kilobyte(500)) // 5 Megabyte - 500 Kilobyte = 4.5 Megabyte = 4 500 Kilobyte = 4 500 000 Byte
246 gigabyte(1).multiply(5)             // 1 Gigabyte times 5 = 5 Gigabyte
247 terabyte(1).divide(5)               // 1 Terabyte divided by 5 = 0.2 Terabyte = 200 Gigabyte
248 ----
250 === Comparison & Equality
252 Each unit is comparable to each other unit.
254 [source,java]
255 ----
256 import static wtf.metio.storageunits.StorageUnits.*;
258 kibibyte(1024).compareTo(mebibyte(1)) == 0 // true
259 kibibyte(1000).compareTo(mebibyte(1)) == 0 // false
260 petabyte(3).compareTo(terabyte(3000)) == 0 // true
262 megabyte(1000).equals(gigabyte(1))         // true
263 megabyte(1024).equals(gigabyte(1))         // false
264 terabyte(12).equals(gigabyte(12000))       // true
265 ----
267 === Formatting
269 Each unit prints a human-readable string, representing the amount of bytes in the given unit using the symbol specified in ISO IEC 80000-13:2008.
271 [source,java]
272 ----
273 import static wtf.metio.storageunits.StorageUnits.*;
275 // default pattern '0.00'
276 terabyte(2).toString()                         // "2.00 TB"
277 gigabyte(1).add(megabyte(200)).toString()      // "1.20 GB"
278 petabyte(1).subtract(terabyte(250)).toString() // "0.75 PB"
280 // use custom pattern
281 kilobyte(212345).toString("0.0")                                    // "212345.0 kB"
282 gibibyte(2123458).asTebibyte().toString("#,###.000")                // "2,073.689 TiB"
283 kilobyte(120).asMegabyte().add(gigabyte(1)).toString("#,##0.00000") // "1,000.12000 MB"
285 // use custom pattern with specific Locale
286 kilobyte(212345).toString("0.0", Locale.GERMAN)                     // "212345,0 kB"
287 gibibyte(2123458).asTebibyte().toString("#,###.000", Locale.GERMAN) // "2.073,689 TiB"
289 // use custom format
290 Format customFormat = new DecimalFormat("#.00000");
291 terabyte(4).asTebibyte().toString(customFormat) // "3.63798 TiB"
293 // without creating unit type first
294 long numberOfBytes = 1_000_000_000_000_000L;
295 formatAsPetabyte(numberOfBytes) // "1.00 PB"
296 formatAsTerabyte(numberOfBytes) // "1000.00 TB"
297 formatAsPebibyte(numberOfBytes) // "0.89 PiB"
299 // use custom pattern
300 formatAsTerabyte(numberOfBytes, "#0.#####") // "1000 TB"
301 formatAsPebibyte(numberOfBytes, "#0.#####") // "0.88818 PiB"
303 // use custom pattern with specific Locale
304 formatAsTerabyte(numberOfBytes, "#0.#####", Locale.GERMAN) // "1000 TB"
305 formatAsPebibyte(numberOfBytes, "#0.#####", Locale.GERMAN) // "0,88818 PiB"
307 // use custom format
308 formatAsTerabyte(numberOfBytes, customFormat) // "1000.00000 TB"
309 formatAsPebibyte(numberOfBytes, customFormat) // ".88818 PiB"
310 ----
312 === Conversions
314 Each unit can be converted to each other unit without loss of information.
316 [source,java]
317 ----
318 import static wtf.metio.storageunits.StorageUnits.*;
320 Megabyte unit = kilobyte(1000).asMegabyte() // "1.00 MB"
321 Kilobyte unit = gigabyte(12).asKilobyte()   // "12000000.00 kB"
322 Gigabyte unit = terabyte(1).asGigabyte()    // "1000.00 GB"
324 // convert to best-match
325 kilobyte(1100).asBestMatchingUnit()          // "1.10 MB"
326 kilobyte(1100).asBestMatchingBinaryUnit()    // "1.05 MiB"
327 kilobyte(1100).asBestMatchingDecimalUnit()   // "1.10 MB"
328 kilobyte(1100).asBestMatchingCommonUnit()    // "1.05 MB"
329 ----
331 Each unit can be expressed as a fraction of another unit (precise up to 24 decimal places)
333 [source,java]
334 ----
335 import static wtf.metio.storageunits.StorageUnits.*;
337 BigDecimal kilobytes = megabyte(1).inKilobyte()  // 1 000
338 BigInteger bytes = kibibyte(2).inByte()          // 2 048
339 BigDecimal terabytes = gigabyte(15).inTerabyte() // 0.015
340 ----
342 === Serialization
344 The storage-units-(eclipselink|mongodb|jackson) modules provide custom serializers to store storage units.
346 ==== EclipseLink
348 Use any of the three converters like this:
350 [source, java]
351 ----
352 @Entity
353 public class HardDisk implements Serializable {
355     @Basic
356     @Converter (
357         name="binaryConverter",
358         converterClass=de.xn__ho_hia.storage_unit.eclipselink.BinaryStorageUnitConverter.class
359     )
360     @Convert("binaryConverter")
361     public StorageUnit<?> getFreeSize() {
362         return freeSize;
363     }
365     @Basic
366     @Converter (
367         name="commonConverter",
368         converterClass=de.xn__ho_hia.storage_unit.eclipselink.CommonStorageUnitConverter.class
369     )
370     @Convert("commonConverter")
371     public StorageUnit<?> getUsedSize() {
372         return usedSize;
373     }
375     @Basic
376     @Converter (
377         name="decimalConverter",
378         converterClass=de.xn__ho_hia.storage_unit.eclipselink.DecimalyStorageUnitConverter.class
379     )
380     @Convert("decimalConverter")
381     public StorageUnit<?> getTotalSize() {
382         return totalSize;
383     }
386 ----
388 ==== MongoDB
390 Use any of the three codecs like this:
392 [source, java]
393 ----
394 CodecRegistry binaryRegistry = CodecRegistries.fromCodecs(new BinaryStorageUnitCodec(), ...);
395 CodecRegistry commonRegistry = CodecRegistries.fromCodecs(new CommonStorageUnitCodec(), ...);
396 CodecRegistry decimalRegistry = CodecRegistries.fromCodecs(new DecimalStorageUnitCodec(), ...);
397 ----
399 ==== Jackson
401 Use the provided `StorageUnitModule` like this:
403 [source, java]
404 ----
405 ObjectMapper objectMapper = new ObjectMapper();
406 objectMapper.registerModule(new StorageUnitModule()); // defaults to binary units
407 objectMapper.registerModule(new StorageUnitModule(StorageUnitModule.PreferredUnitType.BINARY));
408 objectMapper.registerModule(new StorageUnitModule(StorageUnitModule.PreferredUnitType.COMMON));
409 objectMapper.registerModule(new StorageUnitModule(StorageUnitModule.PreferredUnitType.DECIMAL));
410 ----
412 === Integration
414 To use this project just declare the following dependency inside your POM:
416 [source,xml,subs="attributes,verbatim"]
417 ----
418 <dependencies>
419   <dependency>
420     <groupId>{project-group}</groupId>
421     <artifactId>storage-units</artifactId>
422     <version>${version.storage-units}</version>
423   </dependency>
425   <!-- EclipseLink ONLY -->
426   <dependency>
427     <groupId>{project-group}</groupId>
428     <artifactId>storage-units-eclipselink</artifactId>
429     <version>${version.storage-units}</version>
430   </dependency>
431   <!-- EclipseLink ONLY -->
433   <!-- MongoDB ONLY -->
434   <dependency>
435     <groupId>{project-group}</groupId>
436     <artifactId>storage-units-mongodb</artifactId>
437     <version>${version.storage-units}</version>
438   </dependency>
439   <!-- MongoDB ONLY -->
441   <!-- Jackson ONLY -->
442   <dependency>
443     <groupId>{project-group}</groupId>
444     <artifactId>storage-units-jackson</artifactId>
445     <version>${version.storage-units}</version>
446   </dependency>
447   <!-- Jackson ONLY -->
448 </dependencies>
449 ----
451 Replace `${version.storage-units}` with the link:++http://search.maven.org/#search%7Cga%7C1%7Cg%3Ade.xn--ho-hia.storage_units++[latest release].
453 == Reference
455 Originally inspired by link:https://github.com/twitter/util#space[Twitters util] package.
457 == Alternatives
459 * link:https://github.com/JakeWharton/byteunits[Byte Units]
460 * link:https://github.com/trivago/triava[triava]
462 == License
464 To the extent possible under law, the author(s) have dedicated all copyright
465 and related and neighboring rights to this software to the public domain
466 worldwide. This software is distributed without any warranty.
468 You should have received a copy of the CC0 Public Domain Dedication along
469 with this software. If not, see http://creativecommons.org/publicdomain/zero/1.0/.
471 == Mirrors
473 * https://github.com/sebhoss/{project-name}
474 * http://repo.or.cz/{project-name}.git