Skip to content

Commit 719af20

Browse files
committed
array db example added
1 parent 276b677 commit 719af20

File tree

4 files changed

+165
-1
lines changed

4 files changed

+165
-1
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
0001, 87895432, T
2+
0802, 51920654, F
3+
6521, 77142754, T
4+
3215,97142097, T

java-io/pom.xml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,17 @@
99
<version>1.0-SNAPSHOT</version>
1010

1111

12-
12+
<build>
13+
<plugins>
14+
<plugin>
15+
<groupId>org.apache.maven.plugins</groupId>
16+
<artifactId>maven-compiler-plugin</artifactId>
17+
<configuration>
18+
<source>1.8</source>
19+
<target>1.8</target>
20+
</configuration>
21+
</plugin>
22+
</plugins>
23+
</build>
1324

1425
</project>
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
package mk.ukim.finki.os.examples.arraydb;
2+
3+
import java.io.*;
4+
5+
/**
6+
* @author Riste Stojanov
7+
*/
8+
public class CsvToOrderedBinaryDatabase {
9+
10+
private static final int ROW_NUMBER_BYTES = 8; // 1 long x 8 bytes
11+
private static final int VALUE_BYTES = 8; // 8 chars x 1 byte
12+
private static final int STATUS_BYTES = 1; // 1 char x 1 byte
13+
private static final int ADDITIONAL_CONTROL_BYTES = 4; // 2 for each utf string
14+
private static final long ELEMENT_SIZE = ROW_NUMBER_BYTES + VALUE_BYTES + STATUS_BYTES + ADDITIONAL_CONTROL_BYTES;
15+
private static String CSV_FILE = "data/CsvToOrderedBinaryDatabase.csv";
16+
private static String DB_FILE = "data/CsvToOrderedBinaryDatabase.osdb";
17+
18+
public static void main(String[] args) throws IOException {
19+
parseCsv(CSV_FILE, DB_FILE);
20+
21+
}
22+
23+
public static void parseCsv(String csvFile, String binFile) throws IOException {
24+
// Java 8 try with resources that replaces the try-finally block
25+
// see: https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
26+
try (
27+
BufferedReader csvReader = openCsv(csvFile);
28+
RandomAccessFile randomAccessFile = createOrOpenDatabase(binFile)
29+
) {
30+
String line;
31+
// one line at a time in memory. OK until the line is not too long
32+
// we have specification that the line is 13 characters + semicolons and spaces. It will fit in memory :)
33+
while ((line = csvReader.readLine()) != null) {
34+
saveLine(line, randomAccessFile);
35+
}
36+
}
37+
// how can we validate ourselves?
38+
printDatabase(binFile);
39+
}
40+
41+
42+
private static BufferedReader openCsv(String csvFile) throws FileNotFoundException {
43+
File file = new File(csvFile);
44+
if (!file.exists()) {
45+
throw new IllegalStateException("csv file not found! absolutePath: "
46+
+ file.getAbsolutePath());
47+
}
48+
return new BufferedReader(new FileReader(file));
49+
}
50+
51+
private static RandomAccessFile createOrOpenDatabase(String binFile) throws FileNotFoundException {
52+
return new RandomAccessFile(binFile, "rw");
53+
}
54+
55+
private static void saveLine(String line, RandomAccessFile randomAccessFile) throws IOException {
56+
//TODO: change the code to write it in the right place
57+
58+
String[] elements = validateAndGetElements(line);
59+
//ADVICE: Always use trim() before parsing type (unless white spaces are expected)
60+
Long rowNumber = Long.parseLong(
61+
elements[0].trim() // .trim removes the invisible characters at the beginning and at the end of the string
62+
);
63+
String value = elements[1].trim();
64+
String status = elements[2].trim();
65+
validateElements(value, status);
66+
randomAccessFile.writeLong(rowNumber);
67+
// if the characters are cyrillic, there will be 2 bytes per character
68+
System.out.println("Value length: " + value.getBytes().length);
69+
70+
// Documentation snippet from DataOutputStream.writeUTF:
71+
// First, two bytes are written to out as if by the <code>writeShort</code>
72+
// method giving the number of bytes to follow ...
73+
randomAccessFile.writeUTF(value);
74+
System.out.println("Status length: " + status.getBytes().length);
75+
randomAccessFile.writeUTF(status);
76+
}
77+
78+
private static String[] validateAndGetElements(String line) {
79+
String[] elements = line.split(",");
80+
if (elements.length != 3) {
81+
throw new IllegalArgumentException("Line does not have exactly 3 elements! line: " + line);
82+
}
83+
return elements;
84+
}
85+
86+
private static void validateElements(String value, String status) {
87+
if (value.length() != 8) {
88+
throw new IllegalArgumentException("Invalid value length! expected 8 characters. value=" + value);
89+
}
90+
if (status.length() != 1) {
91+
throw new IllegalArgumentException("Invalid value length! expected 1 characters. status=" + status);
92+
}
93+
}
94+
95+
96+
private static void printDatabase(String binFile) throws IOException {
97+
try (
98+
RandomAccessFile randomAccessFile = new RandomAccessFile(binFile, "r")
99+
) {
100+
Long numberOfElements = randomAccessFile.length() / ELEMENT_SIZE;
101+
System.out.println("file size: " + randomAccessFile.length());
102+
int index = 0;
103+
System.out.println("number of elements: " + numberOfElements);
104+
while (index < numberOfElements) {
105+
printElement(randomAccessFile, index);
106+
index++;
107+
}
108+
}
109+
}
110+
111+
private static void printElement(RandomAccessFile randomAccessFile, int index) throws IOException {
112+
byte[] valueBytes = new byte[VALUE_BYTES];
113+
byte[] statusBytes = new byte[STATUS_BYTES];
114+
115+
// go to the position of the element
116+
randomAccessFile.seek(index * ELEMENT_SIZE);
117+
118+
//read from the random access file
119+
Long rowNumber = randomAccessFile.readLong();
120+
121+
String value = randomAccessFile.readUTF();
122+
String status = randomAccessFile.readUTF();
123+
System.out.println("file pointer: " + randomAccessFile.getFilePointer());
124+
125+
System.out.println(rowNumber + ", " + value + ", " + status);
126+
}
127+
128+
129+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Текстуално читање, бинарно запишување
2+
===========================
3+
Потребно е да исчитате csv датотека, и да ја запишете во бинарна датотека. Елементите од csv датотеката се реден
4+
број – 4 карактери, вредност – 8 ASCII карактери и статус – 1 ASCII карактер:
5+
6+
0001, 87895432, T
7+
8+
0802, 51920654, F
9+
10+
6521, 77142754, T
11+
12+
3215, 97142097, T
13+
14+
15+
При исчитувањето потребно е да го запазите сортирањето во бинарната датотека – сортирање во растечки редослед
16+
по вредноста на редниот број. Затоа, потребно е секој исчитан ред од csv датотеката да го запишете во бинарната
17+
датотека на позиција одредена според редниот број: реден број 0001 – позиција 1, реден број 0802 – позиција 802,
18+
реден број 6521 – позиција 6521… Го запишувате повторно целиот ред (бинарно) - поле по поле без никакви сепаратори.
19+
20+
Напишете го методот 'parseCsv(String csvFile, String binFile)', каде двата стринга се патека до соодветните датотеки.

0 commit comments

Comments
 (0)