try {
// db parameters
String url = "jdbc:sqlite: db_path.db";
// create a connection to the database
conn = DriverManager.getConnection(url);
System.out.println("Connection to SQLite has been established.");
} catch (SQLException e) {
System.out.println(e.getMessage());
}
When database is connected a duplicate file is created with same name and size 0Kb inside project folder
String query = "INSERT INTO Path VALUES (?)";
try {
PreparedStatement state = DB_Path.conn.prepareStatement(query);
state.setString(1,path);
} catch (SQLException e) {
System.out.println(e.getMessage());
}
Your connection does not have permissions to access the existing db file. So it creates a new (different) file
The problem is in url of database file i-e space between jdbc:sqlite: and db_path.db
The correct way is:
url = "jdbc:sqlite:db_path.db;
You can use absolute path too but keep in mind the above line of error, for locating some file in directory, it preferable to use backward slash b/w directories because it is used in windows path system and for java syntax it comes two times like this,
url = "jdbc:sqlite:C:\\Desktop\\db_path.db;
or you can use forward slash too,
url = "jdbc:sqlite:C:/Desktop/db_path.db;
Related
How one would write a Lucene 8.11 ByteBuffersDirectory to disk?
something similar to Lucene 2.9.4 Directory.copy(directory, FSDirectory.open(indexPath), true)
You can use the copyFrom method to do this.
For example:
You are using a ByteBuffersDirectory:
final Directory dir = new ByteBuffersDirectory();
Assuming you are not concurrently writing any new data to that dir, you can declare a target where you want to write the data - for example, a FSDirectory (a file system directory):
Directory to = FSDirectory.open(Paths.get(OUT_DIR_PATH));
Use whatever string you want for the OUT_DIR_PATH location.
Then you can iterate over all the files in the original dir object, writing them to this new to location:
IOContext ctx = new IOContext();
for (String file : dir.listAll()) {
System.out.println(file); // just for testing
to.copyFrom(dir, file, file, ctx);
}
This will create the new OUT_DIR_PATH dir and populate it with files, such as:
_0.cfe
_0.cfs
_0.si
segments_1
... or whatever files you happen to have in your dir.
Caveat:
I have only used this with a default IOContext object. There are other constructors for the context - not sure what they do. I assume they give you more control over how the write is performed.
Meanwhile I figured it out by myself and created a straight forward method for it:
#SneakyThrows
public static void copyIndex(ByteBuffersDirectory ramDirectory, Path destination) {
FSDirectory fsDirectory = FSDirectory.open(destination);
Arrays.stream(ramDirectory.listAll())
.forEach(fileName -> {
try {
// IOContext is null because in fact is not used (at least for the moment)
fsDirectory.copyFrom(ramDirectory, fileName, fileName, null);
} catch (IOException e) {
log.error(e.getMessage(), e);
}
});
}
Using a service account, Google Drive API and Google SpreadSheet API, I create a spreadsheet that i then move to a specific folder, using the following code :
public async Task<File> SaveNewSpreadsheet(Spreadsheet spreadsheet, File folder)
{
try
{
Spreadsheet savedSpreadsheet = await _sheetService.Spreadsheets.Create(spreadsheet).ExecuteAsync();
string spreadsheetId = GetSpreadsheetId(savedSpreadsheet);
File spreadsheetFile = await GetFileById(spreadsheetId);
File spreadsheetFileMoved = await MoveFileToFolder(spreadsheetFile, folder);
return spreadsheetFileMoved;
}
catch (Exception e)
{
_logger.LogError(e, $"An error has occured during new spreadsheet save to Google drive API");
throw;
}
}
public async Task<File> MoveFileToFolder(File file, File folder)
{
try
{
var updateRequest = _driveService.Files.Update(new File(), file.Id);
updateRequest.AddParents = folder.Id;
if (file.Parents != null)
{
string previousParents = String.Join(",", file.Parents);
updateRequest.RemoveParents = previousParents;
}
file = await updateRequest.ExecuteAsync();
return file;
}
catch (Exception e)
{
_logger.LogError(e, $"An error has occured during file moving to folder.");
throw;
}
}
This used to work fine for a year or so, but since today, the MoveFileToFolder request throw the following exception:
Google.GoogleApiException: Google.Apis.Requests.RequestError
Increasing the number of parents is not allowed [403]
Errors [
Message[Increasing the number of parents is not allowed] Location[ - ] Reason[cannotAddParent] Domain[global]
]
The weird thing is that if I create a new service account and use it instead of the previous one, it works fine again.
I've looked for info on this "cannotAddParent" error but I couldn't find anything.
Any ideas on why this error is thrown ?
I have the same problem and filed in issue in the Google Issue Tracker. This is intended behavior, unfortunately. You are no longer able to place a file in multiple parents as in your example. See the linked documentation for migration.
Beginning Sept. 30, 2020, you will no longer be able to place a file in multiple parent folders; every file must have exactly one parent folder location. Instead, you can use a combination of status checks and a new shortcut implementation to accomplish file-related operations.
https://developers.google.com/drive/api/v2/multi-parenting
Here's the warning that I am getting:
S3AbortableInputStream:Not all bytes were read from the S3ObjectInputStream, aborting HTTP connection. This is likely an error and may result in sub-optimal behavior. Request only the bytes you need via a ranged GET or drain the input stream after use.
I tried using try with resources but S3ObjectInputStream doesn't seem to close via this method.
try (S3Object s3object = s3Client.getObject(new GetObjectRequest(bucket, key));
S3ObjectInputStream s3ObjectInputStream = s3object.getObjectContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(s3ObjectInputStream, StandardCharsets.UTF_8));
){
//some code here blah blah blah
}
I also tried below code and explicitly closing but that doesn't work either:
S3Object s3object = s3Client.getObject(new GetObjectRequest(bucket, key));
S3ObjectInputStream s3ObjectInputStream = s3object.getObjectContent();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(s3ObjectInputStream, StandardCharsets.UTF_8));
){
//some code here blah blah
s3ObjectInputStream.close();
s3object.close();
}
Any help would be appreciated.
PS: I am only reading two lines of the file from S3 and the file has more data.
Got the answer via other medium. Sharing it here:
The warning indicates that you called close() without reading the whole file. This is problematic because S3 is still trying to send the data and you're leaving the connection in a sad state.
There's two options here:
Read the rest of the data from the input stream so the connection can be reused.
Call s3ObjectInputStream.abort() to close the connection without reading the data. The connection won't be reused, so you take some performance hit with the next request to re-create the connection. This may be worth it if it's going to take a long time to read the rest of the file.
Following option #1 of Chirag Sejpal's answer I used the below statement to drain the S3AbortableInputStream to ensure the connection can be reused:
com.amazonaws.util.IOUtils.drainInputStream(s3ObjectInputStream);
I ran into the same problem and the following class helped me
#Data
#AllArgsConstructor
public class S3ObjectClosable implements Closeable {
private final S3Object s3Object;
#Override
public void close() throws IOException {
s3Object.getObjectContent().abort();
s3Object.close();
}
}
and now you can use without warning
try (final var s3ObjectClosable = new S3ObjectClosable(s3Client.getObject(bucket, key))) {
//same code
}
To add an example to Chirag Sejpal's answer (elaborating on option #1), the following can be used to read the rest of the data from the input stream before closing it:
S3Object s3object = s3Client.getObject(new GetObjectRequest(bucket, key));
try (S3ObjectInputStream s3ObjectInputStream = s3object.getObjectContent()) {
try {
// Read from stream as necessary
} catch (Exception e) {
// Handle exceptions as necessary
} finally {
while (s3ObjectInputStream != null && s3ObjectInputStream.read() != -1) {
// Read the rest of the stream
}
}
// The stream will be closed automatically by the try-with-resources statement
}
I ran into the same error.
As others have pointed out, the /tmp space in lambda is limited to 512 MB.
And if the lambda context is re-used for a new invocation, then the /tmp space is already half-full.
So, when reading the S3 objects and writing all the files to the /tmp directory (as I was doing),
I ran out of disk space somewhere in between.
Lambda exited with error, but NOT all bytes from the S3ObjectInputStream were read.
So, two things one need to keep in mind:
1) If the first execution causes the problem, be stingy with your /tmp space.
We have only 512 MB
2) If the second execution causes the problem, then this could be resolved by attacking the root problem.
Its not possible to delete the /tmp folder.
So, delete all the files in the /tmp folder after the execution is finished.
In java, here is what I did, which successfully resolved the problem.
public String handleRequest(Map < String, String > keyValuePairs, Context lambdaContext) {
try {
// All work here
} catch (Exception e) {
logger.error("Error {}", e.toString());
return "Error";
} finally {
deleteAllFilesInTmpDir();
}
}
private void deleteAllFilesInTmpDir() {
Path path = java.nio.file.Paths.get(File.separator, "tmp", File.separator);
try {
if (Files.exists(path)) {
deleteDir(path.toFile());
logger.info("Successfully cleaned up the tmp directory");
}
} catch (Exception ex) {
logger.error("Unable to clean up the tmp directory");
}
}
public void deleteDir(File dir) {
File[] files = dir.listFiles();
if (files != null) {
for (final File file: files) {
deleteDir(file);
}
}
dir.delete();
}
This is my solution. I'm using spring boot 2.4.3
Create an amazon s3 client
AmazonS3 amazonS3Client = AmazonS3ClientBuilder
.standard()
.withRegion("your-region")
.withCredentials(
new AWSStaticCredentialsProvider(
new BasicAWSCredentials("your-access-key", "your-secret-access-key")))
.build();
Create an amazon transfer client.
TransferManager transferManagerClient = TransferManagerBuilder.standard()
.withS3Client(amazonS3Client)
.build();
Create a temporary file in /tmp/{your-s3-key} so that we can put the file we download in this file.
File file = new File(System.getProperty("java.io.tmpdir"), "your-s3-key");
try {
file.createNewFile(); // Create temporary file
} catch (IOException e) {
e.printStackTrace();
}
file.mkdirs(); // Create the directory of the temporary file
Then, we download the file from s3 using transfer manager client
// Note that in this line the s3 file downloaded has been transferred in to the temporary file that we created
Download download = transferManagerClient.download(
new GetObjectRequest("your-s3-bucket-name", "your-s3-key"), file);
// This line blocks the thread until the download is finished
download.waitForCompletion();
Now that the s3 file has been successfully transferred into the temporary file that we created. We can get the InputStream of the temporary file.
InputStream input = new DataInputStream(new FileInputStream(file));
Because the temporary file is not needed anymore, we just delete it.
file.delete();
I had written following code to copy database file from dropbox account to app database.But i want to copy only specific table from Dropbox to App database table.Is it possible.
protected Boolean doInBackground(Void... params) {
final File tempDir = context.getCacheDir();
File tempFile;
FileWriter fr;
try {
File data = Environment.getDataDirectory();
String currentDBPath = "//data//"+ "loginscreen.example.com.girviapp" +"//databases//"+DATABASE_NAME;
File currentDB = new File(data, currentDBPath);
FileInputStream fileInputStream = new FileInputStream(currentDB);
Entry existingentry= dropbox.metadata( path ,1000,null,true,null);
if (existingentry.contents.size() != 0)
{
for (Entry ent :existingentry.contents)
{
String name = ent.fileName();
if(name.equals(DATABASE_NAME))
{ FileOutputStream outputStream = new FileOutputStream(currentDB);
DropboxFileInfo info = dropbox.getFile(path + DATABASE_NAME, null, outputStream, null);
return true;
}
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (DropboxException e) {
e.printStackTrace();
}
return false;
}
The answer here depends on exactly what you're looking to do.
If you want to be able to download only a specific table from the database file stored on Dropbox, in order to save bandwidth by not downloading all of the data, then no, this isn't possible. The unit of storage in the Dropbox API you're using is the file, and Dropbox doesn't know what the individual tables in your database file are, so it doesn't have a way for you to specify a particular table.
On the other hand, if you don't mind downloading the entire file from Dropbox, then yes, this is possible. Just download the file as you're doing, and then load it up as a database locally. Then query out just the data you want, that is, the desired table, and do what you need with it.
I am using a Maverick SSH library to connect to the remote machine. Then I am trying to find a file or a group of files in the specific directory based on the wild card : abc*.txt
I tried to use SFTPClient ls(String str) method, however it didn't work :
try{
String fileName = "/tmp/myDir/abc*.txt";
SftpFile[] files = sftp.ls(fileName);
if(files != null && files.length > 0)
retCode = true;
}
catch(Exception ex){
System.out.println("Exception : " + ex);
}
I am getting : No Such File exception.
Is there any way to find out whether the file/group of files exist on the remote machine?
Are you using this api https://www.sshtools.com/j2ssh-javadocs/com/sshtools/sftp/SftpClient.html?
As the javadoc states ls method takes a string path to a directory and not some sort of regular expression.
You can try programmatically listing each directory in your desired path and search the array of SftpFile(s) returned if that is what you need.