Java I/O
File API
- io.file.look_for_new_big_image (обязательно)
- io.file.copy_dir (обязательно)
- io.file.random_access
Charset
- ???
File API
io.file.look_for_new_big_image
import java.io.File;
public class FileLab_LookFor {
public static void main(String[] args) {
File file = new File("d:/tmp");
print(file);
}
public static void print(File root) {
if (root.isFile()) {
System.out.println(root);
} else {
File[] fileArray = root.listFiles();
for (File file : fileArray) {
print(file);
}
}
}
}
Модифицируйте/допишите его, что бы он
1) Собирал только имена файлов, которые представляют собой большие (File.length() > 1024*1024) картинки (имя файла заканчивается (String.endsWith(String)) на ".jpg"/".png"/".bmp"/".gif".
2) Собирал массив файлов, а не выводил в консоль.
3) Для реализации пункта 1 рекомендуется (но не обязательно) использовать FileFilter
3) Для реализации пункта 1 рекомендуется (но не обязательно) использовать FileFilter
public class FileLab_LookFor {
public static void main(String[] args) {
File[] bigImages = lookForBigImage(new File("d:/tmp"));
}
public static File[] lookForBigImage(File root) {...}
}
Вам может помочь метод
public static File[] concatenate(File[] file0, File[] file1) {
File[] result = new File[file0.length + file1.length];
System.arraycopy(file0, 0, result, 0, file0.length);
System.arraycopy(file1, 0, result, file0.length, file1.length);
return result;
}
io.file.copy_dir
Данный код создает копию структуры папок
import java.io.File;
public class FileLab_CopyDir {
public static void main(String[] args) {
copy(new File("d:/tmp"), new File("d:/tmp2"));
}
private static void copy(File src, File dst) {
if (src.isDirectory()) {
if (!dst.exists()) {
dst.mkdir();
}
for (File srcSubDir : src.listFiles()) {
String subDirName = srcSubDir.getName();
copy(srcSubDir, new File(dst, subDirName));
}
}
}
}
Модифицируйте/допишите код, что бы он создавал не только копию папок, но и копии всех файлов.
io.file.random_access
Есть класс Record
public class Record {
public static int MAX_DATA_LENGTH = 64;
private final int id;
private final byte[] data;
public Record(int id, byte[] data) {
if (data == null) {
throw new IllegalArgumentException("'data' must be not null");
}
if (data.length > MAX_DATA_LENGTH) {
throw new IllegalArgumentException("'data.length' must be less or equals than " + MAX_DATA_LENGTH);
}
this.id = id;
this.data = data;
}
public int getId() {
return id;
}
public byte[] getData() {
return data;
}
}
который содержит два поля: id типа int и data типа byte[]. Поле дата переменной длины - от 0 до 64 байт. Значение null - недопустимо.
Вот класс, который "делает" из RandomAccessFile - "хранилище для Record" с произвольным доступом:
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
public class RecordStorage implements AutoCloseable {
private static final int INT_SIZE_IN_BYTES = 4;
private final RandomAccessFile file;
public RecordStorage(String fileName) throws FileNotFoundException {
this.file = new RandomAccessFile(fileName, "rw");
}
public void write(Record record, int index) throws IOException {
// seek to record position in file
file.seek(index * (INT_SIZE_IN_BYTES + Record.MAX_DATA_LENGTH));
// write fields
file.writeInt(record.getId());
file.write(record.getData());
}
public Record read(int index) throws IOException {
// seek to record position in file
file.seek(index * (INT_SIZE_IN_BYTES + Record.MAX_DATA_LENGTH));
// read fields
int id = file.readInt();
byte[] data = new byte[Record.MAX_DATA_LENGTH];
file.readFully(data);
// return
return new Record(id, data);
}
public void flush() throws IOException {
file.getChannel().force(true);
file.getFD().sync();
}
@Override
public void close() throws IOException {
file.close();
}
}
Вот класс, демонстрирующий использование этого хранилища:
import java.io.IOException;
import java.util.Arrays;
import java.util.Random;
public class Application {
private static final int COUNT = 1000;
public static void main(String[] args) throws IOException {
String fileName = "c:/tmp/data.bin";
initStorageData(fileName);
testStorageData(fileName);
}
private static void initStorageData(String fileName) throws IOException {
try (RecordStorage storage = new RecordStorage(fileName)) {
for (int k = 0; k < COUNT; k++) {
Record newRecord = generateRecord(k);
storage.write(newRecord, k);
}
storage.flush();
}
}
private static void testStorageData(String fileName) throws IOException {
try (RecordStorage_q storage = new RecordStorage(fileName)) {
for (int k = COUNT - 1; k >= 0; k--) {
Record expected = generateRecord(k);
Record actual = storage.read(k);
if (actual.getId() != expected.getId()) {
throw new AssertionError("k = " + k + ", actual.getId() = " + actual.getId() + ", expected.getId() = " + expected.getId());
}
if (!Arrays.equals(actual.getData(), expected.getData())) {
throw new AssertionError("k = " + k + ", \n actual.getData() = " + Arrays.toString(actual.getData()) + ", \nexpected.getData() = " + Arrays.toString(expected.getData()));
}
}
}
}
private static Record generateRecord(int k) {
Random rnd = new Random(k);
// random int
int id = rnd.nextInt();
// create array of random length
byte[] data = new byte[rnd.nextInt(Record.MAX_DATA_LENGTH)];
// byte[] data = new byte[Record.MAX_DATA_LENGTH];
// fill array by random bytes
rnd.nextBytes(data);
return new Record(id, data);
}
}
В данном случае, RecordStorage позволяет хранить записи исключительно одинакового размера - 64 байта.
Задача: изменить RecordStorage для того, что бы можно было раскомментировать красную строчку и закомментировать синюю. Т.е. перейти к записям произвольной длины в диапазоне 0-64 байта. Предлагается в RandomAccessFile сохранять также длину поля Record.getData().
Задача: изменить RecordStorage для того, что бы можно было раскомментировать красную строчку и закомментировать синюю. Т.е. перейти к записям произвольной длины в диапазоне 0-64 байта. Предлагается в RandomAccessFile сохранять также длину поля Record.getData().
Charsetxxx
x
xxx
x
xxx
x