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); } }