Mercurial > hg > monetdb-java
view src/main/java/org/monetdb/util/FileTransferHandler.java @ 579:72f4437de9be onclient
Reencode downloads if necessary
author | Joeri van Ruth <joeri.van.ruth@monetdbsolutions.com> |
---|---|
date | Thu, 14 Oct 2021 16:11:52 +0200 (2021-10-14) |
parents | 687034945b3f |
children | 5aef0ea654b1 |
line wrap: on
line source
/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 1997 - July 2008 CWI, August 2008 - 2021 MonetDB B.V. */ package org.monetdb.util; import org.monetdb.jdbc.MonetConnection; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.OutputStream; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; /** * Sample implementation of COPY ... INTO 'file-name' ON CLIENT handling * * Can be registered with {@link MonetConnection#setUploadHandler(MonetConnection.UploadHandler)} * and {@link MonetConnection#setDownloadHandler(MonetConnection.DownloadHandler)}. * Implements uploads and downloads by reading and writing files on the file system. */ public class FileTransferHandler implements MonetConnection.UploadHandler, MonetConnection.DownloadHandler { private final Path root; private final Charset encoding; /** * Create a new FileTransferHandler which serves the given directory. * @param dir directory to read and write files from * @param encoding set this to true if all files in the directory are known to be utf-8 encoded. */ public FileTransferHandler(final Path dir, final Charset encoding) { this.root = dir.toAbsolutePath().normalize(); this.encoding = encoding; } /** * Create a new FileTransferHandler which serves the given directory. * * @param dir directory to read and write files from * @param utf8Encoded set this to true if all files in the directory are known to be utf-8 encoded. */ public FileTransferHandler(final String dir, final Charset encoding) { this(FileSystems.getDefault().getPath(dir), encoding); } public void handleUpload(final MonetConnection.Upload handle, final String name, final boolean textMode, final long linesToSkip) throws IOException { final Path path = root.resolve(name).normalize(); if (!path.startsWith(root)) { handle.sendError("File is not in upload directory"); return; } if (!Files.isReadable(path)) { handle.sendError("Cannot read " + name); return; } if (!textMode) { // must upload as a byte stream handle.uploadFrom(Files.newInputStream(path)); } else if (linesToSkip == 0 && utf8Encoded()) { // more efficient to upload as a byte stream handle.uploadFrom(Files.newInputStream(path)); } else { // cannot upload as a byte stream, must deal with encoding final BufferedReader reader = Files.newBufferedReader(path, encoding); handle.uploadFrom(reader, linesToSkip); } } public void handleDownload(final MonetConnection.Download handle, final String name, final boolean textMode) throws IOException { final Path path = root.resolve(name).normalize(); if (!path.startsWith(root)) { handle.sendError("File is not in download directory"); return; } if (Files.exists(path)) { handle.sendError("File already exists: " + name); return; } if (!textMode) { // must download as a byte stream final OutputStream outputStream = Files.newOutputStream(path, StandardOpenOption.CREATE_NEW); handle.downloadTo(outputStream); } else if (utf8Encoded()) { // more efficient to download as a byte stream final OutputStream outputStream = Files.newOutputStream(path, StandardOpenOption.CREATE_NEW); handle.downloadTo(outputStream); } else { // cannot download as a byte stream, must deal with encoding final BufferedWriter writer = Files.newBufferedWriter(path, encoding, StandardOpenOption.CREATE_NEW); handle.downloadTo(writer); writer.close(); } } public boolean utf8Encoded() { return encoding.equals(StandardCharsets.UTF_8); } }