try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
テキストの書き込みは FileWriter あるいは BufferedWriter を使う。
パイプ接続で前段の標準出力を受ける場合は System.in を使う。
try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
FileWriter fw = new FileWriter(new File(pathout)) ) {
String line;
while ((line = br.readLine()) != null) {
fw.write(line);
}
} catch (Exception e) {
e.printStackTrace();
}
try (FileInputStream fis = new FileInputStream("input.jpg");
FileOutputStream fos = new FileOutputStream("output.jpg")) {
int data;
while ((data = fis.read()) != -1) { // read()は読み取ったバイト数をint型で返し、
fos.write(data); // ファイルの終わりに達した場合は-1を返す
}
} catch (Exception e) {
e.printStackTrace();
}
下の例では、BufferedInputStream を介在させることにより、 合計約1GBの読み込みが100倍以上高速化され実行時間は 0.3分となった。
読み込み終了は EOFException での検出となるため、catch は二つに分ける必要がある。
try (DataInputStream dis = new DataInputStream(
new BufferedInputStream(
new FileInputStream("c:/osm/" + name + "_idlonlat.dat")))) {
while (true) {
long nid = dis.readLong();
int lon = dis.readInt();
int lat = dis.readInt();
put(nid, lon, lat);
}
} catch (EOFException e) {
System.out.println(""); // ファイル読み込み完了
} catch (Exception e) {
e.printStackTrace();
}
try (DataOutputStream dos = new DataOutputStream(
new BufferedOutputStream(new FileOutputStream(path)))) {
for (int i = 0; i < cntNodes; i++) {
dos.writeInt(sids[i]);
dos.writeInt(lons[i]);
dos.writeInt(lats[i]);
}
} catch (Exception e) {
e.printStackTrace();
}
long fileSize = Files.size(Paths.get("c:/osm/japan.osm"));
boolean fExists = Files.exists(Paths.get("c:/osm/japan.osm"));
パスの途中にあるディレクトリもなければ作成される。
Files.createDirectories(Paths.get("c:/map/japan-high7/113"));
FileTime fileTime = Files.getLastModifiedTime(Paths.get("c:/osm/japan.osm"));
テキストファイルを行単位で読み込み、ASCII文字が中心の場合、約1GBの複数のファイルに分割するプログラムを 下に示す。
行単位で読み込み、 改行コードを除いた文字数が 1000,000,000 以上になったとき、出力ファイルを更新している。 OSM(OpenStreetMap)の日本地図領域ファイルの場合、若干、日本語など一文字が2バイト以上になるものがあることと、 改行コードの影響で、個々のファイルサイズは最後の端数ファイルを除き、1000,000,000バイトをやや上回る。
約40GBファイルの分割にパソコンで2時間ほど要した。 バイナリデータの読み込みとして、1回あたりの読み込みサイズを大きくして、 改行コードの検出をスキャンで行えば、高速化が図れる。
ファイルの切れ目に拘らず、1GB単位での分割の場合にもはるかに高速分割ができる。
/*
javac -d ./class splitter/*.java
java -Dfile.encoding=UTF-8 -classpath ./class Splitter japan
*/
import java.io.*;
import java.nio.*;
import java.nio.file.*;
import java.util.*;
public class Splitter {
static void splitFile(String name) throws IOException {
String dirDst = "d:/osms/" + name + "/";
String pathSrc = "c:/map/data/" + name + ".osm";
// 元ファイルを1行ずつ読み込む
try (BufferedReader bufferedReader = Files.newBufferedReader(Paths.get(pathSrc))) {
int length = 0;
String str;
boolean run = true;
for (int splitCount = 0; run; splitCount++) {
String pathDst = dirDst + splitCount + ".osm";
System.out.printf("%s\n", pathDst);
try (BufferedWriter bufferedWriter = Files.newBufferedWriter(Paths.get(pathDst))) {
while (length < 1000000000) {
if ((str = bufferedReader.readLine()) != null) {
bufferedWriter.write(str);
bufferedWriter.newLine();
length += str.length();
} else {
run = false;// 読み込む行がなくなった場合、処理を終了する
break;
}
}
length = 0;
}
}
}
}
public static void main(String[] args) throws Exception {
long start = System.currentTimeMillis();
splitFile(args[0]);
long elapsed = System.currentTimeMillis() - start;
System.out.printf("SPlitter実行時間 = %.2f分\n", elapsed/1000.0/60);
}
}